CH32V20X使用RTOS时堆栈好像要很大

在测试CH32V208的RT-Thread+NetLib移植。只有这两个线程+FinSH线程,一开始IDLE默认的256堆栈好像爆了,增加后,再加了一个线程,线程的运行函数如下:

static void _cc_entry(void *arg)
{
    rt_tick_t ctick,peri_tick = rt_tick_from_millisecond(10);
    uint16_t inval;
    int i;
    ChgInfo *info;
    while(1)
    {
        rt_thread_delay(peri_tick);
        ctick = rt_tick_get();
        inval = GPIO_ReadInputData(GPIOB);
        info = &chg_info[0];
        if(info->chx_tick < ctick)
        {
            info->chx_tick = ctick;
            info->chx_state_cnt = inval;
        }
    }
}

堆栈大小设置为4096,优先级只比netlib低,运行一段时间后,这个线程爆栈了。我是想不通这几行代码,为什么4K堆栈都爆。本来就没多少RAM的MCU,好像创建不了几个线程了。

大概调试了一下,不应该用太多才对。


目前试了一次“溢出”。发现是这个线程的sp(栈指针)指向的地址跟netlib线程的sp是一样的。如果我把这个线程的优先级设置成比netlib线程高,好像就没有这个问题。感觉是线程切换时sp搞错了?把netlib的sp复制到这个线程上。


netlib线程我的设计是通过一个信号量进行唤醒,利用一个10ms的TIM中断以及ETH中断,两个中断里面对发送信号量实现。

#define?GET_INT_SP()??__asm("csrrw?sp,mscratch,sp")
#define?FREE_INT_SP()?__asm("csrrw?sp,mscratch,sp")
#define?DEF_IRQ_HANDLER_BEGIN(irq_name_)?void?irq_name_(void)?__attribute__((interrupt()));?\
????void?irq_name_(void)?{GET_INT_SP();
#define?DEF_IRQ_HANDLER_END()?FREE_INT_SP();}

#include?"rtthread.h"
#define?OS_IRQ_HANDLER_BEGIN(irq_name)?DEF_IRQ_HANDLER_BEGIN(irq_name)?rt_interrupt_enter();
#define?OS_IRQ_HANDLER_END(...)?__VA_ARGS__;?rt_interrupt_leave();?DEF_IRQ_HANDLER_END()

OS_IRQ_HANDLER_BEGIN(ETH_IRQHandler)
{
????WCHNET_ETHIsr();
????rt_sem_release(&_net_sem);
}
OS_IRQ_HANDLER_END()

OS_IRQ_HANDLER_BEGIN(TIM2_IRQHandler)
{
????WCHNET_TimeIsr(WCHNETTIMERPERIOD);
????rt_sem_release(&_net_sem);
????TIM_ClearITPendingBit(TIM2,?TIM_IT_Update);
}
OS_IRQ_HANDLER_END()

复制代码竟然一堆问号,就是两个IRQHandler执行 -- GET_INT_SP() -- rt_interrupt_enter(); -- 中断代码 -- rt_interrupt_leave(); -- FREE_INT_SP();

感觉跟中断里面唤醒netlib线程,然后切换的时候导致这个线程的sp出错。


1678347871919561.png

1678347871551870.png

1678347871119572.png

故障可以重现,基本就是一个低优先级的线程,sp被改为netlib的那个sp了。


把TIM定时去掉,使用RT-Thread的定时器作为10毫秒定时发送信号量,测试了一个晚上没有出问题。有没有可能是

GET_INT_SP和FREE_INT_SP + 中断嵌套导致出问题?如低优先级线程运行过程中,两个中断函数嵌套发生,都发送信号量,最后第一个中断FREE_INT_SP的时候,mscratch的值已经不是原来线程的sp,已经变成新线程的sp?


您好,若你程序中使用GET/FREE_INT_SP这两个函数,不建议使用中断嵌套,建议按照下图将0x804寄存器值设置为0,关闭中断嵌套和硬件压栈,中断函数采用软件压栈的方式。具体已邮件回复你,请注意查收,后续问题可继续通过邮箱沟通。

image.png


1678424716118030.png

1678424716637354.pngWX<span class='label label-success'>个人信息保护,已隐藏</span>

试了一下,使能中断嵌套之后,就算不用INT_SP这两个函数,还是会出问题。还是先禁止中断嵌套使用吧。


只有登录才能回复,可以选择微信账号登录