CH32V20X使用RTOS時堆棧好像要很大

在測試CH32V208的RT-Thread+NetLib移植。只有這兩個線程+FinSH線程,一開始IDLE默認(rèn)的256堆棧好像爆了,增加后,再加了一個線程,線程的運行函數(shù)如下:

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;
????????}
????}
}

堆棧大小設(shè)置為4096,優(yōu)先級只比netlib低,運行一段時間后,這個線程爆棧了。我是想不通這幾行代碼,為什么4K堆棧都爆。本來就沒多少RAM的MCU,好像創(chuàng)建不了幾個線程了。

大概調(diào)試了一下,不應(yīng)該用太多才對。


目前試了一次“溢出”。發(fā)現(xiàn)是這個線程的sp(棧指針)指向的地址跟netlib線程的sp是一樣的。如果我把這個線程的優(yōu)先級設(shè)置成比netlib線程高,好像就沒有這個問題。感覺是線程切換時sp搞錯了?把netlib的sp復(fù)制到這個線程上。


netlib線程我的設(shè)計是通過一個信號量進行喚醒,利用一個10ms的TIM中斷以及ETH中斷,兩個中斷里面對發(fā)送信號量實現(xiàn)。

#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()

復(fù)制代碼竟然一堆問號,就是兩個IRQHandler執(zhí)行 -- GET_INT_SP() -- rt_interrupt_enter(); -- 中斷代碼 -- rt_interrupt_leave(); -- FREE_INT_SP();

感覺跟中斷里面喚醒netlib線程,然后切換的時候?qū)е逻@個線程的sp出錯。


1678347871919561.png

1678347871551870.png

1678347871119572.png

故障可以重現(xiàn),基本就是一個低優(yōu)先級的線程,sp被改為netlib的那個sp了。


把TIM定時去掉,使用RT-Thread的定時器作為10毫秒定時發(fā)送信號量,測試了一個晚上沒有出問題。有沒有可能是

GET_INT_SP和FREE_INT_SP + 中斷嵌套導(dǎo)致出問題?如低優(yōu)先級線程運行過程中,兩個中斷函數(shù)嵌套發(fā)生,都發(fā)送信號量,最后第一個中斷FREE_INT_SP的時候,mscratch的值已經(jīng)不是原來線程的sp,已經(jīng)變成新線程的sp?


您好,若你程序中使用GET/FREE_INT_SP這兩個函數(shù),不建議使用中斷嵌套,建議按照下圖將0x804寄存器值設(shè)置為0,關(guān)閉中斷嵌套和硬件壓棧,中斷函數(shù)采用軟件壓棧的方式。具體已郵件回復(fù)你,請注意查收,后續(xù)問題可繼續(xù)通過郵箱溝通。

image.png


1678424716118030.png

1678424716637354.pngWX<span class='label label-success'>個人信息保護,已隱藏</span>

試了一下,使能中斷嵌套之后,就算不用INT_SP這兩個函數(shù),還是會出問題。還是先禁止中斷嵌套使用吧。


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频