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.
Solved! Go to Solution.
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.
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
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.
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