You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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),核心原因是非法指针访问,按以下顺序排查:

  1. 检查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);
    }
    
  2. 检查receive变量初始化
    代码中receive未定义或未分配内存,(char*)receive是野指针,传入mq_receive会触发HardFault。分配对应大小的内存:

    char receive[1]; // 匹配队列消息大小1字节
    
  3. 确认队列属性与线程栈

    • 确认mq_attr成员顺序正确:TI-RTOS中mq_attr顺序为mq_flags、mq_maxmsg、mq_msgsize、mq_curmsgs,你的初始化{0,1,1,0}是正确的。
    • 尝试增大线程栈大小:当前设置4096字节,若线程内有其他大变量,可能导致栈溢出破坏队列对象,可改为8192测试。
  4. 启用故障信息打印
    在bios.cfg中启用TI-RTOS的FaultHandler模块,打印故障详情:

    var FaultHandler = xdc.useModule('ti.sysbios.family.arm.m3.FaultHandler');
    FaultHandler.enablePrint = true;
    

    触发异常后,CCS控制台会输出故障寄存器值、出错PC地址等信息,直接定位问题点。

内容的提问来源于stack exchange,提问作者Magare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:43:37