CC3220S开发板mq_receive执行陷入无限循环问题求助
CC3220S TI-RTOS 消息队列触发HardFault问题排查
使用CC3220S LaunchPad开发板、CCS编译器、TI-RTOS及SimpleLink CC32xx SDK 5.20.00.06开发,通过POSIX消息队列实现两个pthread通信,线程创建代码如下:
pthread_attr_init(&pAttrs); priParam.sched_priority = 1; int detachState = PTHREAD_CREATE_DETACHED; status = pthread_attr_setdetachstate(&pAttrs, detachState); status |= pthread_attr_setschedparam(&pAttrs, &priParam); status |= pthread_attr_setstacksize(&pAttrs, 4096); status |= pthread_create(&spawn_thread, &pAttrs, thread0, NULL); status |= pthread_create(&spawn_thread, &pAttrs, thread1, NULL); if (status != 0) { /* pthread_create() failed */ while (1) { ; } }
线程thread0中消息队列相关代码:
mq_attr defaultMqueueAttr = { 0, 1, 1, 0 }; mqd_t mqDes0 = mq_open("messagequeue0", O_RDWR | O_CREAT, 0666, &defaultMqueueAttr); char var0 = 0; mq_receive(mqDes0 , (char*) receive, 1 ,0);
问题现象
执行到mq_receive时单步进入内部函数,当执行到if (msg_len < (size_t)((msgQueue->attrs).mq_msgsize))判断语句后,直接跳转到ARM M3异常处理汇编代码,最终卡在无限循环b $1处,修改msg_len、队列属性参数均无效。异常汇编代码如下:
ti_sysbios_family_arm_m3_Hwi_excHandlerAsm__I: .asmfunc tst lr, #4 ; context on PSP? ite NE mrsne r0, psp ; if yes, then use PSP moveq r0, sp ; else use MSP mov sp, r0 ; use this stack stmfd sp!, {r4-r11} ; save r4-r11 while we're at it mov r0, sp ; pass sp to exception handler mov r1, lr ; pass lr too mov r4, lr ; preserve LR in r4 ldr r2, excHandlerAddr blx r2 mov r0, sp ; for ROV mov r1, r4 ; for ROV $1 b $1 ; spin here indefinitely
排查与解决步骤
这个异常属于内存访问错误(HardFault),核心原因是非法指针访问,按以下顺序排查:
检查
mq_open返回值有效性
当前代码未判断消息队列是否创建成功,若mq_open失败会返回(mqd_t)-1,后续访问mqd->msgQueue会触发非法内存访问。添加判断:mqd_t mqDes0 = mq_open("messagequeue0", O_RDWR | O_CREAT, 0666, &defaultMqueueAttr); if (mqDes0 == (mqd_t)-1) { // 可打印errno定位创建失败原因,比如权限、队列名重复等 while(1); }检查
receive变量初始化
代码中receive未定义或未分配内存,(char*)receive是野指针,传入mq_receive会触发HardFault。分配对应大小的内存:char receive[1]; // 匹配队列消息大小1字节确认队列属性与线程栈
- 确认
mq_attr成员顺序正确:TI-RTOS中mq_attr顺序为mq_flags、mq_maxmsg、mq_msgsize、mq_curmsgs,你的初始化{0,1,1,0}是正确的。 - 尝试增大线程栈大小:当前设置4096字节,若线程内有其他大变量,可能导致栈溢出破坏队列对象,可改为8192测试。
- 确认
启用故障信息打印
在bios.cfg中启用TI-RTOS的FaultHandler模块,打印故障详情:var FaultHandler = xdc.useModule('ti.sysbios.family.arm.m3.FaultHandler'); FaultHandler.enablePrint = true;触发异常后,CCS控制台会输出故障寄存器值、出错PC地址等信息,直接定位问题点。
内容的提问来源于stack exchange,提问作者Magare
相关产品推荐
相关产品推荐

