我正在一个使用STM32F446的项目进行工作,该样板带有用STM32CubeMX创建的样板(用于外围设备初始化和中间件,例如带有CMSIS-V1接口的FreeRTOS)。 我有两个使用邮箱进行通信的线程,但是遇到一个问题:线程主体之一是
void StartDispatcherTask(void const * argument)
{
mailCommand *commandData = NULL;
mailCommandResponse *commandResponse = NULL;
osEvent event;
for(;;)
{
event = osMailGet(commandMailHandle, osWaitForever);
commandData = (mailCommand *)event.value.p;
// Here is the problem
osDelay(5000);
}
}
到达延迟,但再也不会消失。在同一线程中使用邮箱和延迟是否存在问题?我还尝试过将延迟时间放在for(;;)
之前,并且可以正常工作。
编辑:我想我可以尝试为该问题添加更多细节。第一个线程发送某种类型的邮件,然后等待另一种类型的邮件;我遇到问题的线程在第一种接收邮件,然后根据接收到的内容执行一些代码,然后将结果作为第二种邮件发送出去;有时是必须等待使用osDelay才能停止工作,但无需进入任何故障处理程序
答案 0 :(得分:0)
我宁愿使用标准的freeRTOS API。 ARM CMSIS包装器是垃圾。
顺便说一句,我宁愿怀疑{% extends "admin/change_list.html" %}
{% load admin_list %}
{% block result_list %}
{% pagination cl %}
{{ block.super }}
{% endblock %}
在这种情况下完全不需要延迟。如果您等待处于BLOCKED状态的数据,则该任务不会消耗任何处理能力
如果还有其他猜测:
使用调试器,看看发生了什么。
答案 1 :(得分:0)
osStatus osDelay(uint32_t millisec)
millisec值指定计时器的刻度数。
确切的时间延迟取决于自上次计时器滴答后的实际时间。
对于值1,系统将等待直到发生下一个计时器滴答声。
=>您必须检查计时器刻度是否正在运行。
选中此link
答案 2 :(得分:0)
正如P__J__在先前的回答中所指出的那样,您不应在循环中使用osDelay()
调用 1
因为您的任务循环将在osMailGet()
调用中等待下一个请求/邮件,直到它到达为止。
但是此提示使我注意到您进行观察的另一个可能原因,因此,我打开了这个新答案: 2
由于循环执行被延迟了5000个滴答声而中断-可能是邮件的生产者填充邮箱的速度快于任务使用邮件的速度吗?然后,您应该检查在生产者上下文中是否检测到/处理了这种情况。
如果生产者忽略“队列已满”返回值并在发送之前丢弃了这些邮件,则系统将每隔5000个滴答处理几封邮件(否则,第一次填充后可能会丢失几封邮件)邮箱(如果您的示例中的生产者仅填充一次邮箱队列)。 即使主要问题与生产者上下文(任务/ ISR)有关,这看起来也像消费者任务被卡住了。
1
如果您要避免在5000个滴答声中处理另一封邮件(如果请求邮件的生成速度比任务处理它们的速度快),那么osDelay()
调用就可以为您提供帮助。
但是然后,您会有一个不同的问题,应该打开一个不同的问题...
2 编辑:我刚刚注意到,克利福德(Clifford)在对问题的评论之一中已经提到了此选项。我认为此选项必须包含答案。