C FreeRTOS,Atmel Studio-任务在收到二进制信号量之前未被阻止
我试图在按下按钮后切换到被阻止的任务。基本上,我希望task_player1在收到task_ctrl发出的信号量之前什么都不做。我发出信号灯的方式是按按钮。代码如下:C FreeRTOS,Atmel Studio-任务在收到二进制信号量之前未被阻止,c,embedded,freertos,atmelstudio,C,Embedded,Freertos,Atmelstudio,我试图在按下按钮后切换到被阻止的任务。基本上,我希望task_player1在收到task_ctrl发出的信号量之前什么都不做。我发出信号灯的方式是按按钮。代码如下: #define B1 PIO_PB26_IDX #define TASK_STACK_SIZE (2048/ sizeof(portSTACK_TYPE)) xTaskCreate(task_ctrl, (const signed char * const) "Control", TASK_STACK_SIZE, NULL,
#define B1 PIO_PB26_IDX
#define TASK_STACK_SIZE (2048/ sizeof(portSTACK_TYPE))
xTaskCreate(task_ctrl, (const signed char * const) "Control", TASK_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(task_player1, (const signed char * const) "Player1", TASK_STACK_SIZE, NULL, 1, NULL);
void task_player1(void *pvParameters)
{
vSemaphoreCreateBinary(player1_signal);
while (1)
{
if( xSemaphoreTake( player1_signal, portMAX_DELAY ) == pdTRUE )
{
printf("Semaphore taken\n");
ioport_set_pin_level(L1, HIGH);
}
}
}
void task_ctrl(void *pvParameters)
{
static signed portBASE_TYPE xHigherPriorityTaskWoken;
bool button1;
while (1)
{
xHigherPriorityTaskWoken = pdFALSE;
button1 = ioport_get_pin_level(B1);
printf("TASK_CTRL RUNNING...\n");
ioport_set_pin_level(L1, LOW);
if (button1)
{
xSemaphoreGiveFromISR(player1_signal, &xHigherPriorityTaskWoken);
printf("Semaphore given\n");
vTaskDelay(1);
}
}
}
问题是任务\u播放器1从未被portMAX\u延迟阻止,因为它应该被阻止。当我把代码上传到微芯片上时,LED灯就亮了,而我只想让它在按下按钮和信号灯发出后亮起来。我做错了什么
由于Atmel Studio的限制,我使用的是FreeRTOS v7.3
编辑:FreeRTOS中更新的代码二进制信号量是在给定状态下创建的,即计数为1。因此,当task_player1进入while循环时,它会将引脚设置为高电平,而不会在信号量处阻塞。您可以在创建信号量之后调用xSemaphoreTake,将信号量计数减少到0
task_ctrl不应使用xSemaphoreGiveFromIsr,因为它是一个task而不是ISR。信号量是如何创建的?通常,信号量用于保护共享资源,而不是用作标志。根据您的问题描述,您似乎没有向我们展示所有相关代码。请检查。为什么,如果信号量在task_ctrl中发出,您是否在task_player1中再次发出信号?@jwdonahue使用信号量进行线程间通信并非不合理。它不是一个标志-你不能有效地等待一个标志一个标志没有计数,一个简单的非原子标志不是线程安全的。@jwdonahue用VSEMaphoreCreateBarynary创建了这个信号量,忘了在这里包含它。此代码段包含来自不同.c和.h的代码,如main.c。这应该可以工作,谢谢!一个简单的问题——xSemaphoreHandle播放器1u信号=1;做同样的事?现在,它被设置为0。player1_信号是一个信号量句柄,不能设置为1。在调用vSemaphoreCreateBinary之后,只需在player1_信号上添加对xSemaphoreTake的调用。然后修复控制任务,不调用ISR版本的函数。是的,它工作了,我已经修复了ISR函数。再次感谢!