Preserving debugging breadcrumbs across reboots in Cortex-M

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

cross mob
CaKu_4284131
Level 5
Level 5
50 replies posted 25 replies posted 10 likes received

I'm trying to implement something like this: Preserving debugging breadcrumbs across reboots in Cortex-M on CM4 in a CY8C6347BZI-BLD53. However, I'm unsure about where I can safely carve out a piece of RAM for saving breadcrumbs.  If I look at cy8c6xx7_cm0plus.ld I see:

    ram               (rwx)   : ORIGIN = 0x08000000, LENGTH = 0x24000

but in  cy8c6xx7_cm4_dual.ld I see:

    ram               (rwx)   : ORIGIN = 0x08024000, LENGTH = 0x23800

So, I have two ranges:

 0x08000000 - 0x08023FFF

and

 0x08024000 - 0x080477FF

There is also this comment in cy8c6xx7_cm4_dual.ld:

    /* The ram and flash regions control RAM and flash memory allocation for the CM4 core.
     * You can change the memory allocation by editing the 'ram' and 'flash' regions.
     * Note that 2 KB of RAM (at the end of the RAM section) are reserved for system use.
     * Using this memory region for other purposes will lead to unexpected behavior.
     * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld',
     * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'.
     */

I am using dual-core BLE, so I have to be careful not to step on that.

So, I started looking at saving data in flash. That looks like a great option. There is lots of room in even one row of sflash_user_data to store a whole cy_stc_fault_frame_t and whatever else I can think of.  And, it should persist across power off. However, I am concerned that I can only write to flash by calling Cy_Flash_WriteRow.  If I am dealing with a Hard Fault, maybe the stack is corrupted. Can I still call a function? I guess if the fault occurs while the Processor Stack Pointer (PSP)  is active, the fault handler will run with the Main Stack Pointer (MSP), and I should be OK. (I'm running FreeRTOS.) But, what if the fault occurs in an Interrupt Service Routine?

Maybe the best option is all of the above, a RAM save area plus a flash row... if I can figure out where to put the RAM area.

 

 

0 Likes
1 Solution
LiDo_2439176
Level 5
Level 5
First question asked 50 replies posted 50 sign-ins

Hi @CaKu_4284131 ,

You can put it at address 0x08023fc0. In cy8c6xx7_cm0plus.ld change the length of ram to 0x24000 - 0x40 = 0x23fc0

line

ram               (rwx)   : ORIGIN = 0x08000000, LENGTH = 0x24000

become

ram               (rwx)   : ORIGIN = 0x08000000, LENGTH = 0x23fc0

This block of memory can be accessed from both cores by declaring for example

char *block = (char*)0x08023fc0;

Best regards,

Liviu

View solution in original post

0 Likes
2 Replies
LiDo_2439176
Level 5
Level 5
First question asked 50 replies posted 50 sign-ins

Hi @CaKu_4284131 ,

You can put it at address 0x08023fc0. In cy8c6xx7_cm0plus.ld change the length of ram to 0x24000 - 0x40 = 0x23fc0

line

ram               (rwx)   : ORIGIN = 0x08000000, LENGTH = 0x24000

become

ram               (rwx)   : ORIGIN = 0x08000000, LENGTH = 0x23fc0

This block of memory can be accessed from both cores by declaring for example

char *block = (char*)0x08023fc0;

Best regards,

Liviu

0 Likes

Thanks, Liviu.

I did that, and it works well. While I was at it I also moved the CM0 - CM4 line down by 0x1000, since all I have on CM0 is the BLE Controller. And (now that I have all that extra RAM!) then I decided to increase the crash save area size so that I could save a whole cy_stc_fault_frame_t.  As I experimented with different configurations, I kept forgetting to keep my .ld and .c files in synch, so I tried to improve on the situation by using sections. Here is what I'm running now:

In cy8c6xx7_cm0plus.ld:

/* CK3: End of CM0 RAM (192 [0xC0] bytes) will be reserved for crash info: */   
    ram               (rwx)   : ORIGIN = 0x08000000, LENGTH = 0x22F40

In cy8c6xx7_cm4_dual.ld:

/* CK3: End of CM0 RAM (192 [0xC0] bytes) will be reserved for crash info: */   
    crash             (rwx)   : ORIGIN = 0x08022F40, LENGTH = 0xC0      
    ram               (rwx)   : ORIGIN = 0x08023000, LENGTH = 0x24800
...
SECTIONS
{
...
    /* See crash.c */
    .my_crash (NOLOAD) : {} > crash
}

In crash.c:

// See linker script: cy8c6xx7_cm4_dual.ld:
CY_SECTION(".my_crash") volatile crash_info_ram_t p_crash_info_ram[1];

Now I can access it like:

p_crash_info_ram->crash_info.cy_faultFrame.cfsr.cfsrReg = SCB->CFSR;

and

if (p_crash_info_ram->cy_faultFrame.cfsr.cfsrBits.bfarValid)

 

These are the first linker scripts I've messed with, so I don't know if this is right, or correct, but it seems to work. Suggestions welcome!

       -Carl

0 Likes