Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
YoIs_1298666
Level 5
Level 5
250 sign-ins 100 replies posted 100 sign-ins

Hello,

In case of the thread below, we can read uint8 array allocated in FLASH, we can get "test" variable that not used anywhere.

Placing uint32 array with compiler optimization "size"

volatile int32 g_vsin[360] __attribute__ ((section (".FlashData"))) = {}

volatile int32 test;             // for debug

       ...

test = g_vsin[100];          // break point for debug

we would like to let the linker allocate the array to FLASH. So, we will use

"__attribute__ ((aligned(CY_FLASH_SIZEOF_ROW)))".

If we use like below, the array cannot be read in bytewize.

const int32 g_vsin[360] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) = {}

volatile int32 test;             // for debug

       ...

test = g_vsin[100];          // break point for debug

And if we use like volatile, the array is allocated in RAM.

volatile int32 g_vsin[360] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) = {}

or

volatile const int32 g_vsin[360] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) = {}

Is it possible to read it allocated in FLASH in bytewize with compiler or linker option  with GCC or something?

Best regards,

Yocchi

0 Likes
1 Solution

Hello Yocchi,

Please refer to this blog which explains how to do this in detail: https://iotexpert.com/2017/06/06/psoc-4-flash-write/

Regards,

Dheeraj

View solution in original post

0 Likes
9 Replies
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Hello Yocchi,

Please correct me if I'm wrong in understanding your issue. You want to align the array on a 256-byte flash boundary and also want it to be placed in a custom location in flash.

You can do it by doing the following:

volatile int32 g_vsin[360] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) CY_SECTION(".FlashData") = {}

Here CY_SECTION(".FlashData") basically expands to __attribute__((section(".FlashData"))). So, it is basically same as writing:

volatile int32 g_vsin[360] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) __attribute__((section(".FlashData"))) = {}

You should see the array in the flash location you have defined in the linker tab in the Build Settings as shown below:

pastedImage_4.png

And you can enter the flash address in the Memory window to see the values of the array as shown below:

mem1.PNG

Let me know if you have any queries. Happy to help!

Regards,

Dheeraj

0 Likes

Dheeraj,

I used to have the "volatile" attribute applied to parameters which are subject to sudden changes (e.g. inside an interrupt). But the above declaration of the array puts it into the Flash:

volatile int32 g_vsin[360] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) CY_SECTION(".FlashData") = {}

shouldn't it be declared as "static const" instead of the "volatile"?

Is it possible to write/modify array's content at run-time with array declaration as shown above?

/odissey1

0 Likes

Hello BoTa_264741

I tried "static const uint8 InitParameter[CY_FLASH_SIZEOF_ROW] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) = ".

After all it was useless.

Best regards,

Yocchi

0 Likes

Hello Odyssey1,

The volatile keyword requests the compiler to not optimize the variable and will be helpful in cases of debugging when you want to see the value of it.

You can make use of the const variable when you want the data to force the placement of the variable in flash. But note that when you set the variable to const, you can no longer change the values at run time.

Using the static keyword provides internal linkage where the scope of the variable is restricted to the file it is defined in.

The attribute section keyword lets you place the variable either in any memory location if you know the custom location addresses. The volatile is not required.

int32 g_vsin[360] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) __attribute__((section(".FlashData")))

Note that if you const along with attribute section keyword, the variable is going to still end up in the section you have defined.

.FlashData      0x0000ff00       0x28

.FlashData     0x0000ff00       0x28 .\CortexM0\ARM_GCC_541\Debug\main.o

                0x0000ff00                g_vsin

If you use the const keyword, you will find the variable assigned with a custom address by the linker in the .rodata region.

const int32 g_vsin[10] __attribute__ ((aligned(CY_FLASH_SIZEOF_ROW))) = {};

You can observe this in the .map memory file:

.rodata         0x00002800      0x108

*(.rodata .rodata.* .gnu.linkonce.r.*)

.rodata        0x00002800       0x28 .\CortexM0\ARM_GCC_541\Debug\main.o

                0x00002800                g_vsin

Yocchi,

When you use the const keyword, you should see the custom address allocated by the linker to the variable. You can enter this address in the memory window to see the values:

map.PNG

Regards,

Dheeraj

0 Likes

Hello Dheeraj-san,

I can allocate the array in Flash memory.

but, I cannot read it in units of 4 bytes(uint32).

Of course I can read it with the volatile qualifier as follows.

volatile int32 g_vsin[360] __attribute__ ((section (".FlashData"))) = {}

Is there a way to be allocated with Linker and read it in the declared unit(uint32)?

test = g_vsin[100];          // break point for debug

Best regards,

Yocchi

0 Likes

Hello Yocchi,

In the first interaction, you declared an int32 variable and used it to read the value of the array. That should work as shown below:

debug2.png

Note that based on the size of the array that is being placed in flash, it might take sometime for the value to reflect while debugging. So, please wait for sometime if you see the fields as blank. It will get populated eventually. Please confirm if this is what you are seeing.

debug3.png

If yes, then please wait for a while and the value should be seen.

Regard,s

Dheeraj

0 Likes

Hello Dheeraj-san,

I forgot to tell you something important.

I am using "CySysFlashWriteRow"API to modify this array.

If we use the "const" qualifier and program the code to read a few words with uint32, the compiler seems to make it an immediate value.

Your code is in 1-byte wise, so try making the for statement 9 bytes or less. (Try about 4 bytes.)

   for(uint8 i = 496; i<500; i++)

       if(i % 10 == i > 0){

           UART_UartPutString("\n\r);

       }

Then, it is not the modified value but the value at the time of writing.

Best regards,

Yocchi

0 Likes

Hello Yocchi,

Please refer to this blog which explains how to do this in detail: https://iotexpert.com/2017/06/06/psoc-4-flash-write/

Regards,

Dheeraj

0 Likes

Hello Dheeraj-san,

Thank you very much for your reply.

But I already know this way.

This setting requires the user to allocate the absolute address of FLASH.

I would like to leave the allocation of the address to Linker.

Best regards,

Yocchi

0 Likes