我按下按钮后尝试切换到已阻止的任务。基本上我希望 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, 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);
}
}
}
问题 task_player1 永远不会被 portMAX_DELAY 阻止。一旦我将代码上传到微芯片,LED就会亮起,而我只想在按下按钮并显示信号量后点亮它。我在这里做错了什么?
由于Atmel Studio的限制,我使用的是FreeRTOS v7.3。
编辑:更新代码
答案 0 :(得分:1)
FreeRTOS中的二进制信号量是在给定的"国家,即。因此当task_player1()进入while循环时,它会将引脚设置为高电平而不会阻塞信号量。您可以在创建信号量后立即调用xSemaphoreTake()以将信号量计数减少为0.
task_ctrl()不应该使用xSemaphoreGiveFromIsr(),因为它是一个任务而不是ISR。