CAN RX 和 TX 缓冲区/FIFO 起始地址(F0SA/TBSA)的寄存器仅考虑地址的低 16 位,但 RAM 地址可以从 0x20000000 到 0x20040000(18 位)。
链接至数据表。
因此,如果我像这样初始化一个数组作为 RX FIFO 工作:
uint8_t can1_rx_fifo0[CAN1_RX_FIFO_ELEMENTS * 16] __attribute__((__aligned__(4)));
编译器将其放在内存地址 0x20005A70 处,这没有问题,因为我可以将 0x5A70 写入 F0SA/TBSA 并且 CAN 将看到正确的缓冲区/FIFO 地址。但如果该数组放在地址 0x20015A70 处,我仍然只能将 0x5A70 写入 F0SA/TBSA,这是错误的地址。
我尝试这样做,FIFO 被放置在我指定的适当地址,但随后该地址被覆盖/用于 RAM 中的其他内容。
#define CAN1_RX_FIFO (volatile struct can1_rx_fifo_struct*)(0x20000000)
static struct can1_rx_fifo_struct
{
uint8_t can1_rx_fifo[CAN1_RX_FIFO_ELEMENTS * 16];
};
我是否误解了它的工作原理?如果不是,我怎样才能最好、安全地初始化数组,使其存储在 0x20000000 - 0x2000FFFF 之间的内存地址?
请参阅链接数据表的第 39.9.1 章:
消息 RAM 只能位于系统 RAM 的前 64 KB 区域。
因此,您需要确保缓冲区存在。
通常使用链接器脚本和特定部分来执行此操作。将部分作为
.data
和 .bss
(及其他)之前的第一个部分添加到内存 ram
,或定义您自己的内存空间。