尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TMS320F28388D IPC实战:CM核向CPU1发送数据的关键步骤与调试心得

TMS320F28388D IPC实战:CM核向CPU1发送数据的关键步骤与调试心得 1. TMS320F28388D IPC通信基础概念在双核处理器中实现核间通信IPC是嵌入式开发中的常见需求。TMS320F28388D作为TI的明星产品其C28x内核与CM内核的协同工作能力非常强大。但初次接触这个芯片时很多开发者会对IPC的具体实现感到困惑。我自己在项目中也踩过不少坑特别是在以太网通信场景下由于以太网外设只能由CM核访问必须通过IPC实现数据在CPU1和CM核之间的传递。IPC本质上是通过共享内存和中断机制实现的。在F28388D中TI已经为我们准备好了MSGRAM多核共享RAM区域比如MSGRAM_CM_TO_CPU1就是专门用于CM向CPU1发送数据的存储区。这里有个关键点需要注意两个核看到的同一块物理内存的地址可能不同这就是为什么代码中要使用IPC_ADDR_CORRECTION_ENABLE参数进行地址校正。官方例程默认提供的是CPU1向CM发送数据的示例ipc_ex1_basic_c28x1.c但实际项目中我们经常需要反向操作。直接修改例程方向时会遇到几个典型问题中断响应机制不对称、地址校正配置错误、共享内存区域溢出等。接下来我会结合具体代码详细说明如何避开这些坑。2. CM核向CPU1发送数据的代码改造2.1 共享内存区域配置在CM核的代码中最关键的是正确声明共享内存区域。原始例程使用的是默认配置我们需要将其调整为CM到CPU1的专用区域uint32_t readData[10]{11,12,13,14,15,16,17,18,19,20}; #pragma DATA_SECTION(readData, MSGRAM_CM_TO_CPU1)这里有几个注意事项数组大小不能超过MSGRAM_CM_TO_CPU1的实际容量800字节必须使用#pragma指令指定数据段初始值不是必须的但方便调试时观察数据变化实测中发现如果忘记添加#pragma指令编译不会报错但运行时数据根本无法传递到对端核这种问题特别难排查。建议在cmd文件中确认MSGRAM_CM_TO_CPU1的地址范围确保配置正确。2.2 数据发送流程改造CM核的主循环中发送命令的代码需要特别注意地址校正IPC_sendCommand(IPC_CM_L_CPU1_R, IPC_FLAG1, IPC_ADDR_CORRECTION_ENABLE, IPC_CMD_READ_MEM, (uint32_t)readData, 10);参数解释IPC_CM_L_CPU1_R指定通信方向CM到CPU1IPC_FLAG1使用的IPC标志位IPC_ADDR_CORRECTION_ENABLE启用地址校正必须IPC_CMD_READ_MEM自定义命令字(uint32_t)readData数据起始地址10数据长度单位是uint32_t这里最容易出错的是忘记启用地址校正。我在第一次尝试时漏掉了这个参数结果CPU1端收到的地址完全不对导致数据读取错误。后来在TI论坛查了很久才发现这个问题官方文档对这个参数的说明其实不太显眼。3. CPU1端的接收处理3.1 中断服务程序改造CPU1端的IPC中断服务程序(ISR)需要做相应调整__interrupt void IPC_ISR0() { uint8_t i; uint32_t command, addr; bool status false; IPC_readCommand(IPC_CPU1_L_CM_R, IPC_FLAG1, IPC_ADDR_CORRECTION_ENABLE, command, addr, data); if(command IPC_CMD_READ_MEM) { status true; for(i0; idata; i) { readData[i] *((uint32_t *)addr i); } } if(status) { IPC_sendResponse(IPC_CPU1_L_CM_R, TEST_PASS); } else { IPC_sendResponse(IPC_CPU1_L_CM_R, TEST_FAIL); } IPC_ackFlagRtoL(IPC_CPU1_L_CM_R, IPC_FLAG1); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP11); }关键点说明IPC_readCommand也必须启用地址校正第三个参数数据读取是通过指针操作完成的需要注意类型转换IPC_ackFlagRtoL是必须的否则通信会卡死Interrupt_clearACKGroup是C28x内核特有的操作3.2 主程序初始化CPU1的主程序需要正确初始化IPC和中断int main(void) { Device_init(); Device_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0); Interrupt_initModule(); Interrupt_initVectorTable(); IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL); IPC_registerInterrupt(IPC_CPU1_L_CM_R, IPC_INT1, IPC_ISR0); IPC_sync(IPC_CPU1_L_CM_R, IPC_FLAG31); EINT; ERTM; while(1); }初始化顺序很重要先初始化设备时钟和外设启动CM核如果CM核需要独立运行初始化中断系统清除IPC标志位注册IPC中断同步双核最后启用全局中断4. 调试技巧与常见问题4.1 CCS调试实战使用CCS调试IPC通信时这些技巧很实用在Watch窗口添加readData数组可以实时观察数据变化设置IPC相关寄存器的断点比如IPC_FLAG寄存器使用Memory Browser查看MSGRAM_CM_TO_CPU1区域的实际内容在IPC_sendCommand和IPC_readCommand处设置断点检查参数是否正确我遇到过一个典型问题数据看似发送成功了但接收端读到的全是0。后来发现是CM核的编译优化级别太高导致数组被优化掉了。解决方法是在数组定义前加上volatile关键字或者调整优化级别。4.2 常见错误排查数据无法接收检查#pragma DATA_SECTION是否正确确认IPC_ADDR_CORRECTION_ENABLE已启用验证MSGRAM区域地址是否匹配通信卡死确认IPC_ackFlagRtoL被调用检查中断ACK是否清除Interrupt_clearACKGroup确保没有标志位冲突数据错误检查数据长度是否超出限制验证两端的数据类型是否一致确认字节序问题F28388D是小端模式在实际项目中我还遇到过电磁干扰导致IPC通信不稳定的情况。这时需要在硬件上加强电源滤波并在软件上添加重试机制。对于关键数据建议添加CRC校验。
返回列表