PSoC4100S How to set code in SRAM with GCC

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

cross mob
ReMa_3807036
Level 2
Level 2
First like received

Hi,

I'm trying to put code to SRAM with PSOC4100S and GCC compiler.

I have followed some code example,

first to specify the section:

CY_SECTION(".sramCode") __attribute__((used))

void example(void)

{

...

}

Then, I have specified  the direttive in linker file  cm0plusgcc.ld as follow:

...

MEMORY

{

    rom (rx) : ORIGIN = 0x0, LENGTH = 32768

/*was    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4096*/

    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 3072

   

    sramCode(rwx): ORIGIN =0x20000C00 LENGTH = 1024

   

}

...

Now, after the "build" I can see in the map file the new segment "sramCode" in the specified position, but when I debug the SW, in particular when I halt into the example routine, I can see that the PC register is not over 0x20000C00 but its value is 0x4xxx (in flash area!).

Some other things are missing?

Thanks for help.

Renato

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

Hi Len,

I have seen your tentative ... thanks for the efforts but I believe (maybe I'm wrong) that the moving from flash to ram has to be done "automatically" by "startup routine", giving the right attribute to the routine to move.

Here you can find an updated to the project,  there I used "ram"  as attribute instead of "sramCode", in this way it is not necessary to modify the linker file (.ld), now the routine NonBlockWriteRow()  is located in SRAM.

Also the "SpcIntHandler" is in SRAM, but at the moment this interrupt never happen, and it is the actual issue (in vector table the address is relocated, and it is ok, address 0x20000070).

Yes I know the Em_EEPROM component..., using them the Write operation stops the cpu for some ms (about 20ms), in the project I will use a multiplexed LED display, to wait 20ms to update it  produces a "flicker" effect.

Br

Renato

View solution in original post

0 Likes
9 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Renato,

Are you willing to share your project with the forum for others to reproduce the issue?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
lock attach
Attachments are accessible only for community members.

Hi Len

yes sure thanks! Here I provide a simplified project focused on the issue.

There, you can see the tentative to obtain a non blocking emulated eeprom writing (it follows a code example in PSoC 4 Architecture Technical Reference Manual (TRM), par. 27.7).

During debugging if you put  a break point into "NonBlockingWriteRow" routine, you can observe the PC register is working on flash area instead of SRAM (around address > 0x20000C00 as defined in cm0plusgcc.ld file).

Then, the isr routine  "SpcIntHandler" never goes in execution, probably because we are still working in flash area (I understand that during erasing/writing flash operation no other flash activities are possible), but this problem will be take in consideration later.

Renato

0 Likes

Renato,

You are correct, both NonBlockWriteRow() and SpcIntHandler() functions are being assigned to FLASH.

This is because you assigned NonBlockWriteRow() and SpcIntHandler() to a new SECTION called .sramCode but your linker was never instructed where in memory (RAM in your case) to place .sramCode.  Since the functions you placed were code, it place it at the tail end of .text where all other code is stored in FLASH.

Below is a link to a similar issue someone else had.   He used a linker custom flag to assign the location of his special section in a specific location in FLASH.

Re: Placing Variables at permanent address in cy_checksum_exclude section

Even if you solve this problem of locating code in RAM at compile-time you have another problem:

Code can be executed from RAM but RAM cannot hold code after reset.

Once you program the PSoC (or any CPU) the RAM contents are not guaranteed after a reset which occurs after the programming is complete.  In fact, most startup initialization code executed before main() gets initialized to 0's.

Here's my suggestion to solve this issue:

  • Allocate enough RAM in main() to contain the functions NonBlockWriteRow() and SpcIntHandler().  (Make sure it is long aligned.)
  • At main() initialization, copy the NonBlockWriteRow() and SpcIntHandler() functions from FLASH to your allocated RAM.
  • Set your CyIntSetVector(12,SpcIntHandler); to the new SpcIntHandler() address in RAM.
  • When you execute NonBlockingWriteRow() make sure it is pointed to the new address in RAM.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
lock attach
Attachments are accessible only for community members.

Renato,

I've attached some modified code that will copy the NonBlockWriteRow() and SpcIntHandler() functions from FLASH to RAM.

It tries to jump to NonBlockWriteRow_code() but gets lost in the weeds (DefaultIntHandler) soon after.  It appears to be a stack issue.

What you are trying to do is fairly advanced.

Question:  It appears you are trying to modify FLASH at run-time.  The PSoC provides a Em_EEPROM component with API calls to handle FLASH calls correctly.  Is there a reason these component API functions will not work for you?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
lock attach
Attachments are accessible only for community members.

Hi Len,

I have seen your tentative ... thanks for the efforts but I believe (maybe I'm wrong) that the moving from flash to ram has to be done "automatically" by "startup routine", giving the right attribute to the routine to move.

Here you can find an updated to the project,  there I used "ram"  as attribute instead of "sramCode", in this way it is not necessary to modify the linker file (.ld), now the routine NonBlockWriteRow()  is located in SRAM.

Also the "SpcIntHandler" is in SRAM, but at the moment this interrupt never happen, and it is the actual issue (in vector table the address is relocated, and it is ok, address 0x20000070).

Yes I know the Em_EEPROM component..., using them the Write operation stops the cpu for some ms (about 20ms), in the project I will use a multiplexed LED display, to wait 20ms to update it  produces a "flicker" effect.

Br

Renato

0 Likes

Renato,

I see you've been able to move the code into RAM as you indicated.

I'm curious.  If a power-up reset occurs, how is the code in RAM preserved?

Yes I know the Em_EEPROM component..., using them the Write operation stops the cpu for some ms (about 20ms), in the project I will use a multiplexed LED display, to wait 20ms to update it  produces a "flicker" effect.

Yes.  The Em_EEPROM API calls are blocking for PSoC4s.  How many digits and segments are your multiplexed LEDs?

I've produced a 4 digit 7-segment LED multiplexer for the PSoC6.  It should transfer to the PSoC4 as well.  The advantage of this LED driver is that the only SW to drive the LED is the init call and loading the new data into the LED registers to display.   If no display changes are needed, the LED will mux the digits totally in HW.  In this case there is NO FLICKER!  4 Digit 7-segment LED driver for the PSoC6

If needed, this driver design can be extended to more digits.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Renato,

Update to my previous emai:

The PSoC 4100S does not have any UDBs.  Therefore my statement

"I've produced a 4 digit 7-segment LED multiplexer for the PSoC6.  It should transfer to the PSoC4 as well."

is not correct.  My implementation requires UDBs.

Question:

Are you using a timer interrupt to switch the LED multiplexer?

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Hi Len,

... the code is not memorized in sram, it is in flash, at power on during "cstartup" (or similar name) routine (before jumping to main), it is moved to sram.

...  yes I use a 2ms timer interrupt.

I consider closed the originally question "How to set code to sram...", really I open another discussion about the issue on SPC interrupt.

Thanks

Br

Renato

0 Likes

Renato,

Got it.  Good luck.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes