Hello!
What I have to do to put const chars into flash memory?
I use KDS like below with j-link from Segger (Picture1).
Picture1:
For example
static const unsigned char en_menu_1_0[15]="Put into flash";
Picture2:
map file (Picture3):
When I read from this array in run
i= en_menu_1_0[2];
Picture4:
On the Picture4 the value i=0x74 (ASCII == ‘t’) so this is correct. In this situation debbuger show correct value.
But why:
1. The debugger shows strange value like in picture2 above, where is initialization of const unsigned char array? const unsigned char en_menu_1_0[15]="Put into flash"?
2. Why address of static const unsigned char en_menu_1_0 is …. 0x00000000 (picture2)?
...................................................................................................................................................
Maybe I describe what I want to do....
I want to prepare menu strings that I want to put to the flash memory.
Then make array of pointers to the array of chars….
Something like this below for atmel.
But how can I do this in Kinetis (KL46Z256)?
In 8051 there is “code”
In atmel ther is “PROGMEM”
What I have to do in Kinetis KL46?
example from atmel:
const char MenuItem1[] PROGMEM = "Mirek";
const char MenuItem2[] PROGMEM = "Tomek";
const char MenuItem3[] PROGMEM = "Atnel";
const char * const MenuItemPointers[] PROGMEM = {
MenuItem1,
MenuItem2,
MenuItem3
};
int main( void ) {
lcd_init();
uint8_t i;
while(1) {
for(i=0; i<3; i++)
lcd_str_P( (char*)pgm_read_word( &MenuItemPointers[i] ) );
}
}
...............................................................................................................................................
I will be very gratefull for any help and sugestion.
Best Regards
Piotr
Solved! Go to Solution.
This is the code I use with GCC. Some macros make it compatible with AVR-GCC so same code can be used on both ARM and AVR.
#define PGM_P char const *
#define strncpy_P strncpy
#define PROGMEM
#ifndef PGM_READ_WORD
#define PGM_READ_WORD(adr) (adr)
#endif
#define UNUSED( PARAMETER ) (void)(PARAMETER) /** Used to silence 'unused parameter' */
/* Example function: */
static uint16_t bootload_jump_func( uint8_t const *string_u8 );
static uint16_t bootload_jump_func( uint8_t const *string_u8 )
{
UNUSED( string_u8 );
bootload_jump_func(); /* Never returns */
return( 0U ); /* Keep compiler happy, we never get here */
}
/* ******************** Decode incoming ASCII commands ******************** */
/*
* To get the static strings to really be in the flash you have to do
* it this way with structures. The 'obvious' way only gets the array
* of pointers in flash, not the strings themselves. Also the
* #)$*#$(#$*)_# IAR compiler doesn't generate the code you expect
* sucking away your RAM! #$__*)#$* IAR will not let you put an array
* of pointers into flash, but it will allow you to put an array of
* structures into flash.
*/
typedef uint16_t (*cmdfunc_t)( uint8_t const *string_u8 );
typedef struct /* define the struct 'cmd_entry' */
{
PGM_P string; /* Pointer to string in flash */
cmdfunc_t function;
}str_func_entry;
static const char cmd_str_firmware_update[] PROGMEM = "Firmware_Update";
static const str_func_entry cmd_func_table[] PROGMEM= /* Declare a constant object of type 'cmd_entry' */
{/* Keep in Alphabetical order for the Help command: */
{cmd_str_firmware_update, bootload_jump_func}
};
#define COMMANDS_AVAILABLE (sizeof( cmd_func_table ) / sizeof( str_func_entry ))
static uint16_t cmd_help_func( uint8_t const *string_u8 )
{
UNUSED( string_u8 );
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
for( uint_fast16_t number_of_patterns_u16 = 0U; number_of_patterns_u16 < COMMANDS_AVAILABLE; number_of_patterns_u16++ )
{
strout_P( (PGM_P) PGM_READ_WORD( cmd_func_table[number_of_patterns_u16].string ) );
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
}
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
return( 0U );
}
This is the code I use with GCC. Some macros make it compatible with AVR-GCC so same code can be used on both ARM and AVR.
#define PGM_P char const *
#define strncpy_P strncpy
#define PROGMEM
#ifndef PGM_READ_WORD
#define PGM_READ_WORD(adr) (adr)
#endif
#define UNUSED( PARAMETER ) (void)(PARAMETER) /** Used to silence 'unused parameter' */
/* Example function: */
static uint16_t bootload_jump_func( uint8_t const *string_u8 );
static uint16_t bootload_jump_func( uint8_t const *string_u8 )
{
UNUSED( string_u8 );
bootload_jump_func(); /* Never returns */
return( 0U ); /* Keep compiler happy, we never get here */
}
/* ******************** Decode incoming ASCII commands ******************** */
/*
* To get the static strings to really be in the flash you have to do
* it this way with structures. The 'obvious' way only gets the array
* of pointers in flash, not the strings themselves. Also the
* #)$*#$(#$*)_# IAR compiler doesn't generate the code you expect
* sucking away your RAM! #$__*)#$* IAR will not let you put an array
* of pointers into flash, but it will allow you to put an array of
* structures into flash.
*/
typedef uint16_t (*cmdfunc_t)( uint8_t const *string_u8 );
typedef struct /* define the struct 'cmd_entry' */
{
PGM_P string; /* Pointer to string in flash */
cmdfunc_t function;
}str_func_entry;
static const char cmd_str_firmware_update[] PROGMEM = "Firmware_Update";
static const str_func_entry cmd_func_table[] PROGMEM= /* Declare a constant object of type 'cmd_entry' */
{/* Keep in Alphabetical order for the Help command: */
{cmd_str_firmware_update, bootload_jump_func}
};
#define COMMANDS_AVAILABLE (sizeof( cmd_func_table ) / sizeof( str_func_entry ))
static uint16_t cmd_help_func( uint8_t const *string_u8 )
{
UNUSED( string_u8 );
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
for( uint_fast16_t number_of_patterns_u16 = 0U; number_of_patterns_u16 < COMMANDS_AVAILABLE; number_of_patterns_u16++ )
{
strout_P( (PGM_P) PGM_READ_WORD( cmd_func_table[number_of_patterns_u16].string ) );
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
}
strout_P( text_string_ptr_get( CMDS_TXT_CRLF ) );
return( 0U );
}
Thank you very much for answer and help!
Very useful sugestions - everything works fine - I checked:)
Best Regards
Piotr