LPC540xx - MCAN_SetMsgRAMBase asserts with XIP image

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC540xx - MCAN_SetMsgRAMBase asserts with XIP image

Jump to solution
287 Views
Theodore_Bardy
Contributor I

I work on the LPCXpresso54S018 development board. Because this board doesn't have internal flash I use the populated external flash W25Q128JVFM, and I build my application as an XIP image, to do so I define the XIP_IMAGE flag for the LPC54S018_spifi_flash.ld linker script. And few ASM flags for the startup_LPC54S018.S startup file:

 

IMG_BAUDRATE=96000000
W25Q128JVFM
XIP_IMAGE
__STARTUP_CLEAR_BSS

 

Here is the result for memory regions:

 

[build] Memory region         Used Size  Region Size  %age Used
[build]     m_interrupts:         452 B        512 B     88.28%
[build]           m_text:       92616 B   16776704 B      0.55%
[build]           m_data:       58196 B     196604 B     29.60%
[build]       m_usb_sram:          0 GB         8 KB      0.00%

 

And I can the in the output.map file the `.data` region is at the very start of the internal RAM.

 

.data           0x0000000000000008      0x5c0 load address 0x0000000010016608
                0x0000000000000008                . = ALIGN (0x4)
                0x0000000000000008                __DATA_RAM = .
                0x0000000000000008                __data_start__ = .

 

So far, everything works good. I can flash or debug my program.

My issue comes when I try to use the CAN bus (MCAN driver), it seems the CAN message RAM is the source of the issue. When I add this line:

 

__attribute__((aligned(1U << CAN_MRBA_BA_SHIFT), section(".data"))) uint8_t msgRam[MSG_RAM_SIZE] = {1U};`

 

Here is my result, as you can see the m_data region sharp increases:

 

[build] Memory region         Used Size  Region Size  %age Used
[build]     m_interrupts:         452 B        512 B     88.28%
[build]           m_text:      101360 B   16776704 B      0.60%
[build]           m_data:      124076 B     196604 B     63.11% ← +65880 bytes (33.51%)
[build]       m_usb_sram:          0 GB         8 KB      0.00%

 

And the output.map:

 

.data           0x0000000000010000      0x708 load address 0x00000000100186e8
                0x0000000000010000                . = ALIGN (0x4)
                0x0000000000010000                __DATA_RAM = .
                0x0000000000010000                __data_start__ = .
 *(.ramfunc*)
 *(.data)
 .data          0x0000000000010000      0x12d
                0x0000000000010000                msgRam

 

And the assert in the MCAN_SetMsgRAMBase function is triggered:

 

assert(((value >= 0x20000000U) && (value <= 0x20027FFFU)) || ((value >= 0x04000000U) && (value <= 0x04007FFFU)));

 

How can I deal with this problem? What is the purpose of this assert, does it make sense for an XIP image, and how can I prevent the m_data region from increasing in this way?

Btw it seems the program works fine if I remove the assert.

To reproduce my issue, you can just build the mcan_loopback example as an XIP image. To do so, you need to edit the flag.cmake file as shown in the attachment.

Labels (1)
0 Kudos
Reply
1 Solution
268 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

For your question, as you have seen the line:

__attribute__((aligned(1U << CAN_MRBA_BA_SHIFT), section(".data"))) uint8_t msgRam[MSG_RAM_SIZE] = {1U};`

The CAN_MRBA_BA_SHIFT is 16 bits, it means that the compiler has to allocate 64KB memory space with low 16 bits all 0x0000, for example the this is a valid address 0xXXXX_0000.

This is the message RAM part, all the Receiver Filter, message buffer, and receiver FIFO are all put in the message RAM,the start address is written in the  Message RAM base address register, pls refer to section 36.8.44 Message RAM base address register.

xiangjun_rong_0-1706855155968.png

I have checked the CAN example with SDK with 2.7.0 version, it writes a memory address directly.

#define MSG_RAM_BASE 0x20010000U

/* Set Message RAM base address and clear to avoid BEU/BEC error. */

MCAN_SetMsgRAMBase(EXAMPLE_MCAN, MSG_RAM_BASE);

uint32_t *p = (uint32_t *)(MSG_RAM_BASE);

memset(p, 0, (8U + CAN_DATASIZE) * sizeof(uint8_t));

In order to save the memory address, you can refer to the method to write an immediate value to the

Message RAM base address register.

 

The assert() only verifies if the address is in the RAM address range.

Hope it can help you

BR

XiangJun Rong

View solution in original post

1 Reply
269 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

For your question, as you have seen the line:

__attribute__((aligned(1U << CAN_MRBA_BA_SHIFT), section(".data"))) uint8_t msgRam[MSG_RAM_SIZE] = {1U};`

The CAN_MRBA_BA_SHIFT is 16 bits, it means that the compiler has to allocate 64KB memory space with low 16 bits all 0x0000, for example the this is a valid address 0xXXXX_0000.

This is the message RAM part, all the Receiver Filter, message buffer, and receiver FIFO are all put in the message RAM,the start address is written in the  Message RAM base address register, pls refer to section 36.8.44 Message RAM base address register.

xiangjun_rong_0-1706855155968.png

I have checked the CAN example with SDK with 2.7.0 version, it writes a memory address directly.

#define MSG_RAM_BASE 0x20010000U

/* Set Message RAM base address and clear to avoid BEU/BEC error. */

MCAN_SetMsgRAMBase(EXAMPLE_MCAN, MSG_RAM_BASE);

uint32_t *p = (uint32_t *)(MSG_RAM_BASE);

memset(p, 0, (8U + CAN_DATASIZE) * sizeof(uint8_t));

In order to save the memory address, you can refer to the method to write an immediate value to the

Message RAM base address register.

 

The assert() only verifies if the address is in the RAM address range.

Hope it can help you

BR

XiangJun Rong