- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Renato,
Are you willing to share your project with the forum for others to reproduce the issue?
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Renato,
Got it. Good luck.
Len
"Engineering is an Art. The Art of Compromise."