Я пытаюсь включить и выключить светодиод с помощью FreeRTOS на микроконтроллере STM32 F401RE в IAR Workbench IDE.
Светодиод относится к плате ядра STM32. Есть две задачи: один светодиод включается, а другой - тот же светодиод.
Вот код:
Основной код:
SemaphoreHandle_t xMutex;
int main()
{
if ( xMutex == NULL )
{
xMutex = xSemaphoreCreateMutex();
if ( ( xMutex ) != NULL )
xSemaphoreGive( ( xMutex ) );
}
xTaskCreate(LedOn, "Led On", 100, NULL, 1, NULL);
xTaskCreate(LedOff, "Led Off", 100, NULL, 1, NULL);
vTaskStartScheduler();
while(1){}
}
Задачи:
void LedOn(void *argument)
{
for(;;)
{
xSemaphoreTake( xMutex, ( TickType_t )5000 ) ;
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
vTaskDelay(5000);
xSemaphoreGive(xMutex);
}
}
void LedOff(void *argument)
{
for(;;)
{
xSemaphoreTake( xMutex, ( TickType_t )5000 ) ;
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
vTaskDelay(5000);
xSemaphoreGive(xMutex);
}
}
Мое намерение здесь таково:
Задача Led отвечает за включение Led на 5 с
Задача Led off отвечает за включение Led на 5 с
Так что это будет продолжаться до выключения питания
Моя проблема здесь:
В первоначальном случае светодиод остается включенным на 5 с после того, как светодиод выключен на 5 с, он работает только переключение двух контекстов после двух переключений светодиод остается включенным.
Когда после отладки после двух переключений точка останова не попадает в задачи
После небольшой попытки, я думаю, я нашел ответ:
Каждое задание должно иметь время задержки, поэтому нам нужно добавить время задержки, чтобы задача продолжила свою работу, но я добавил, что было добавлено время задержки между xTakeSemaphore
и xGiveSemaphore
методами, которые являются временем задержки мьютексов где указано, как должен быть заблокирован ресурс, а не время задержки задачи. * 103 1 *
Решение:
void LedOn(void *argument)
{
for(;;)
{
if(xSemaphoreTake(xMutex, portMAX_DELAY)== pdTRUE)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
vTaskDelay(pdMS_TO_TICKS(5000));
xSemaphoreGive(xMutex);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
}
void LedOff(void *argument)
{
for(;;)
{
if( xSemaphoreTake( xMutex, portMAX_DELAY)== pdTRUE)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
vTaskDelay(pdMS_TO_TICKS(5000));
xSemaphoreGive(xMutex);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
}