BSP

rt-thread线程调度异常在stm32f103芯片上

发布于 2017-01-24 14:40:49
问题:
程序在运行中出现有两个线程不执行了,motor_ctrl_entry和can_send_entry不执行了,而其它线程都正常执行,错误是在反复运行后偶尔出现的,不容易复现,但是存在。在调试J-link状态下运行,出现问题时,打断点,用到的中断都正常,其它执行的线程也正常,就是出问题的线程哪地方打断点都运行不到,若是说高优先级线程死循环但是低优先级线程还可以运行,不知道哪里出的问题。
大神帮忙看看,谢谢了
int rt_application_init(void)
{
init_modules();

rt_thread_init(&watchdog_thread, "watchdog",
watchdog_thread_entry, RT_NULL, watchdog_thread_stack,
512, 10, 5);
rt_thread_startup(&watchdog_thread);

rt_thread_init(&motor_ctrl_thread, "motor_ctrl",
motor_ctrl_entry, RT_NULL, motor_ctrl_thread_stack,
1536, 11, 5);
rt_thread_startup(&motor_ctrl_thread);

rt_thread_init(&can_send_thread, "can_send",
can_send_entry, RT_NULL, can_send_thread_stack,
1024, 12, 5);
rt_thread_startup(&can_send_thread);

rt_thread_init(&can_recv_thread, "can_recv",
can_recv_entry, RT_NULL, can_recv_thread_stack,
1536, 13, 5);
rt_thread_startup(&can_recv_thread);

rt_thread_init(&servo_comm_thread, "servo_comm",
servo_comm_entry, RT_NULL, servo_comm_thread_stack,
1536, 14, 5);
rt_thread_startup(&servo_comm_thread);

rt_thread_init(&rf_comm_thread, "rf_comm",
rf_comm_entry, RT_NULL, rf_comm_thread_stack,
1024, 15, 5);
rt_thread_startup(&rf_comm_thread);

return 0;
}

void can_send_entry(void *parameter)
{
U8 ucMailbox, ucSendCnt;

while (1)
{
ucSendCnt = 0;
while (usTXRead != usTXSave)
{
ucMailbox = CAN_Transmit(CAN1, &stTxBuff[usTXRead]);
if(ucMailbox == CAN_TxStatus_NoMailBox)
{
if(ucSendCnt < 10)
{
ucSendCnt++;
rt_hw_us_delay(600); //>126bit*4us
}
else
{
rt_thread_delay(1);
}
}
else
{
usTXRead++;
if (usTXRead == LCAN_TX_BUFLEN)
{
usTXRead = 0;
}
ucTxFlag = TRUE;
}
}
xgj_status_update();
//led_indicate();
rt_thread_delay(3);
}
}

motor_ctrl_entry代码:
while(1)
{
ucStopFlag = FALSE;

key_analysis(&ucSendFlag, &ucStopFlag);

alarm_analysis();
//rf_analysis(&ucSendFlag);
if(g_sucModeFlag == MODE_AUTO && ucStopFlag == FALSE)
{
if(rt_event_recv(&event_ls_cmd, EVENT_RTC_TIMING, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
RT_WAITING_NO, &e) == RT_EOK)
{
if(ucSendFlag > CTRL_PRI4_TIMING)
{
ucSendFlag = CTRL_PRI4_TIMING;
}
}

if(rt_event_recv(&event_ls_cmd, EVENT_LS_COMMOND, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
RT_WAITING_NO, &e) == RT_EOK)
{
if(ucSendFlag > CTRL_PRI3_LOONGSEC)
{
ucSendFlag = CTRL_PRI3_LOONGSEC;
}
}

if(rt_event_recv(&event_ls_cmd, EVENT_RF_REMOTE, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
RT_WAITING_NO, &e) == RT_EOK)
{
if(ucSendFlag > CTRL_PRI2_REMOTE)
{
ucSendFlag = CTRL_PRI2_REMOTE;
}
}
}

if(ucSendFlag > 0 && ucSendFlag < CTRL_PRI_LOWEST && ucStopFlag == FALSE)
{
motor_start();
g_sucPosition = POS_MIDDLE;
ucSendFlag = CTRL_PRI_LOWEST;
}

rt_thread_delay(5);
}

QQ图片20170207143637.jpg

查看更多

关注者
0
被浏览
3.8k
8 个回答
bernard
bernard 2017-01-24
这个需要你自行查找问题了,当复现后可以用shell命令行的一些命令来了解任务的状态。另外,程序中依赖delay的方式来调度并不是好的设计。
dutchlight
dutchlight 2017-01-24
多谢大神解答,程序中还用到了
void rt_enter_critical(void); /* 进入临界区*/
......
void rt_exit_critical(void); /* 退出临界区*/,


多个线程会调用此函数会不会有问题?现在发现死的线程还不一定是这两个?!
还有不用rt_delay的方式调度,用什么调度,信号量,互斥量?比较好的用什么调度?
dutchlight
dutchlight 2017-02-07
不执行的线程每次还不一定一样,现在出现只有motor_ctrl_entry一个线程不执行了,

附件是finsh打印信息,大神帮帮看看,从哪找原因就是找不到啊,问题也是很难重现,搞了半天才出现一次

QQ图片20170207143637.jpg
dutchlight
dutchlight 2017-02-07
stm32是jlink在线调试运行的,出问题时,怎么查看原因,现在把所有信号量、事件、都去掉了,只有定时器还是会出现问题,论坛人太少了,实在找不到只能放弃使用rt-thread了。
aozima
aozima 2017-02-07
感觉很像是 rt_enter_critical/rt_exit_critical 里面出现了问题。
调度锁里面的操作应该是迅速的,执行结果可100%预测的。
建议停止调度后,通过JTAG来观察 rt_enter_critical 中 rt_scheduler_lock_nest 的值。
good luck!
dutchlight
dutchlight 2017-02-08
谢谢回答,rt_enter_critical/rt_exit_critical后来也去掉了,rt-thread里就只剩下用了定时器,其它全用全局变量代替了,还是会出现死线程,关键问题很难重现,现在没时间找原因了,改用裸跑的吧,以后有时间在仔细找找原因。
dutchlight
dutchlight 2017-02-24
今天有空测了下,发现应该是频繁进入串口接收中断引起的,试了两次可以重现现象,串口收发有个引脚偶尔会与地接触,导致频繁进入接收中断,但是还是没有找出rt-thread个别线程不工作的原因,不想找了,还是用的裸跑,每行代码都知道,

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友