FreeRTOS 标志位被篡改

编程入门 行业动态 更新时间:2024-10-10 23:24:51

FreeRTOS <a href=https://www.elefans.com/category/jswz/34/1769913.html style=标志位被篡改"/>

FreeRTOS 标志位被篡改

 

调试程序是遇到了一个很奇葩的问题,设置好的静态全局标志位被意外篡改了。

起初以为是栈溢出覆盖了,于是在该变量前后定义静态全局变量,两个周都没变动过,就标志位被修改了。于是确定不是堆栈的问题。

分析:

记录一下这个容易犯的错误,也可以说是小漏洞。

如果存在A线程正在等待队列X(及线程正阻塞在xQueueReceive函数中)。此时如果有B线程执行xQueueSend 函数执行时,B线程在将数据拷贝入队列后会立即释放B线程的执行,转而执行A线程。只有当A线程主动释放线程或者到任务调度的时间,B线程才有机会被执行。

如下代码,当xQueueSend 执行后,  【waitqueue_flag=false;】不会被紧接着执行,而是跳到xQueueReceive函数继续执行,如果该线程不主动释放CUP,再次执行了【can_read_until】函数,则继续执行【  waitqueue_flag = true;】命令,运行到xQueueReceive函数才会主动释放一次CPU,此时系统调动回来执行xQueueSend后面的语句,及【 waitqueue_flag=false;】。此时就会出现waitqueue_flag刚设置的标志位被莫名其妙的清除了,也就是xQueueSend后的语句干的坏事。他来的太慢了!!!

最简单的办法就是把 waitqueue_flag=false;放在xQueueSend执行前执行。

 

总结:

根据以上分析,得出两个血淋淋的教训:

1、全局变量多线程操作时,尽量保证一方读一方写,如果需要同时写的情况,请加锁。

2、在调用FreeRTOS函数时,可能会存在系统提前触发上下文切换。所以之前做好切换前的数据准备。

 

 

 

 

异常部分代码如下:

其中一个线程:

回调函数设置应答队列:cmd_queue

static int can_receive_callback(void *msg, int size)
{can_node_t node = (can_node_t)msg;if(waitqueue_flag){if(waitqueue_address == node->address && waitqueue_cmd==node->can.cmd){xQueueSend(cmd_queue, node,0);waitqueue_flag=false;return 0;}}
。。。。。。

另一个线程:

等待队列中数据更新

bool can_read_until(can_node_t node, int timeout)
{waitqueue_flag = true;if (xQueueReceive(cmd_queue, node, timeout) == pdTRUE){return true;}return false;
}

 

 

 

更多推荐

FreeRTOS 标志位被篡改

本文发布于:2024-03-10 09:49:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1727638.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:标志   FreeRTOS

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!