9 Replies Latest reply on May 26, 2020 10:23 PM by DheerajK_81

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

    YoIs_1298666

      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

       

        • 1. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
          DheerajK_81

          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:

           

           

          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

          • 2. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
            BoTa_264741

            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

            • 3. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
              YoIs_1298666

              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

              • 4. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
                YoIs_1298666

                Hello BoTa_264741-san,

                 

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

                 

                After all it was useless.

                 

                Best regards,

                Yocchi

                • 5. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
                  DheerajK_81

                  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

                  • 6. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
                    YoIs_1298666

                    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

                     

                     

                    • 7. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
                      DheerajK_81

                      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

                      • 8. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
                        YoIs_1298666

                        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

                        • 9. Re: Bytewise reading of uint8 array allocated in FLASH by linker of PSoC4S
                          DheerajK_81

                          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