为什么xQueueSendToBack调用被阻塞?
我正在STM32F103C8T6(蓝色药片板上)上学习FreeRTOS。 我正在尝试使用队列和任务为什么xQueueSendToBack调用被阻塞?,c,embedded,freertos,C,Embedded,Freertos,我正在STM32F103C8T6(蓝色药片板上)上学习FreeRTOS。 我正在尝试使用队列和任务 #include <FreeRTOS.h> #include <libopencm3/stm32/gpio.h> #include <libopencm3/stm32/rcc.h> #include <queue.h> #include <task.h> static QueueHandle_t queue; static void
#include <FreeRTOS.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <queue.h>
#include <task.h>
static QueueHandle_t queue;
static void
task_receive(void *args __attribute__((unused)))
{
bool nothing;
while (1)
{
if (xQueueReceive(queue, ¬hing, 10) == pdPASS)
gpio_set(GPIOC, GPIO13); // Turn off
else
taskYIELD(); // Yeld so that other taks can run
}
}
static void
task_send(void *args __attribute__((unused)))
{
bool nothing = false;
while (1)
{
gpio_clear(GPIOC, GPIO13); // Turn on
vTaskDelay(pdMS_TO_TICKS(100));
xQueueSendToBack(queue, ¬hing, portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
int
main(void)
{
rcc_clock_setup_in_hse_8mhz_out_72mhz();
// Blue-Pill led
rcc_periph_clock_enable(RCC_GPIOC);
gpio_set_mode(
GPIOC,
GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
GPIO13);
gpio_set(GPIOC, GPIO13); // Turn off (polarity of the led is inversed!)
queue = xQueueCreate(32, sizeof(bool));
if (queue == 0)
{
while (1)
{
gpio_toggle(GPIOC, GPIO13);
for (uint32_t i = 0; i < 80000; ++i)
__asm__("nop");
};
}
xTaskCreate(task_receive, "RECEIVE", 200, NULL, configMAX_PRIORITIES-1, NULL);
xTaskCreate(task_send, "SEND", 200, NULL, configMAX_PRIORITIES-2, NULL);
vTaskStartScheduler();
while(1);
return 0;
}
您的
任务\u接收
优先级高于任务\u发送
优先级<如果没有更高优先级的任务,code>taskYIELD将反复运行相同的调用任务
要实现您的目标,请尝试按以下方式更改任务\u receive
static void
task_receive(void *args __attribute__((unused)))
{
bool nothing;
while (1)
{
if (xQueueReceive(queue, ¬hing, portMAX_DELAY) == pdPASS)
gpio_set(GPIOC, GPIO13); // Turn off
}
}
有关taskYIELD的更多信息,请参阅以下内容
通过将编译器更新到最新版本,问题得以解决 Kubuntu 18.04附带
arm none eabi gcc(15:6.3.1+svn253039-1build1)6.3.1 20170620
,使用此编译器,代码不起作用
memcpy
似乎是代码中有问题的函数调用,FreeRTOS在向队列添加元素时会调用它
如果我使用
Version 8-2018-q4-major Linux 64位
编译器,则代码执行良好。可以在此处下载:在您的示例中,任务的接收
优先级高于任务的发送
优先级,因此,在较高优先级的任务中让步将再次让步调用任务。因此,您的send\u任务
根本不会被抢占。看看这个,我尝试过这个改变,但它并没有改善led的行为(它是打开的,从不关闭)。我还试图使这两项任务具有相同的优先级:没有更好的。让我在这里做一个有根据的猜测。您的代码不是卡在vTaskDelay
而不是xQueueSendToBack
中了吗。如果是这种情况,请确保您的systick ISR(我假设systick是RTOS tick源)正确配置为调用FreeRTOS tick函数。看看libopencm3
是如何处理systick ISR的。我认为它的配置是正确的。我创建了一个示例,用两个任务使led闪烁(一个任务打开led,另一个任务关闭led),每个任务都调用vTaskDelay
,效果良好。您是否有通过调试器逐步完成源代码的功能?似乎您在FreeRTOS代码中遇到了一个configAssert
。同样,我希望此时您已经检查了200
单词的堆栈大小是否足以完成这两项任务。@VictorAmoine我没有发现代码有任何错误(对于非taskYIELD
one)。我在另一块板上尝试了一个类似的代码,似乎工作得很好(我用UART printfs替换了GPIO调用)。也许您最好尝试对STM32Cube HAL做同样的事情,绕过libopencm3依赖项—只是一个建议。为了进一步帮助您更好地使用FreeRTOS讨论论坛。
static void
task_receive(void *args __attribute__((unused)))
{
bool nothing;
while (1)
{
if (xQueueReceive(queue, ¬hing, portMAX_DELAY) == pdPASS)
gpio_set(GPIOC, GPIO13); // Turn off
}
}