在带有 STM32 的 FreeRTOS 中使用 1 个 UART 执行三个相同优先级的任务

问题描述 投票:0回答:1

我尝试在三个相同优先级的任务中使用一个 UART,如下面的代码,但发生的情况让我感到困惑!事实上,我希望任何任务每秒发送一次字符串,所以我应该每秒在终端中有 3 个语句,但 UART 发送函数只工作一次,其他 2 个发送函数被省略。

当我将任务优先级更改为高、正常和低时,效果很好。如何在不更改任务优先级的情况下解决此问题?

其实我不想有一个复杂的RTOS程序。我只想要一个简单的多任务程序,没有信号量或互斥体!我希望这是可能的,因为我不想增加我的程序的复杂性。 (请注意,如果我添加等待 UART 就绪功能,程序可以正常工作,但这不是微控制器编程中的常用方法)。

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* definition and creation of myTask02 */
  osThreadDef(myTask02, StartTask02, osPriorityNormal, 0, 128);
  myTask02Handle = osThreadCreate(osThread(myTask02), NULL);

  /* definition and creation of myTask03 */
  osThreadDef(myTask03, StartTask03, osPriorityNormal, 0, 128);
  myTask03Handle = osThreadCreate(osThread(myTask03), NULL);

void StartDefaultTask(void const * argument)
{
  /* Infinite loop */
  for(;;)
  {
    //while (HAL_UART_GetState (&huart2) != HAL_UART_STATE_READY);
    HAL_UART_Transmit(&huart2,(uint8_t*)"T1\r\n",sizeof("T1\r\n")-1,100);
    osDelay(1000);
  }
}

void StartTask02(void const * argument)
{
  /* Infinite loop */
  for(;;)
  {
    //while (HAL_UART_GetState (&huart2) != HAL_UART_STATE_READY);
    HAL_UART_Transmit(&huart2,(uint8_t*)"T2\r\n",sizeof("T2\r\n")-1,100);
    osDelay(1000);
  }
}

void StartTask03(void const * argument)
{
  /* Infinite loop */
  for(;;)
  {
    //while (HAL_UART_GetState (&huart2) != HAL_UART_STATE_READY);
    HAL_UART_Transmit(&huart2,(uint8_t*)"T3\r\n",sizeof("T3\r\n")-1,100);
    osDelay(1000);
  }
}
stm32 freertos multitasking
1个回答
0
投票

使用互斥体有什么问题?显然,您需要某种方法来防止三个任务同时访问 UART,而互斥锁是实现此目的的明显方法。

最简单的方法是将所有 UART 功能(包括互斥体)移至单个函数中,从而消除单个任务中的“复杂性”:

static StaticSemaphore_t uart_mutex;
static SemaphoreHandle_t h_uart_mutex = NULL;

void init_mutex(void) // Called before tasks are created
{
    h_uart_mutex = xSemaphoreCreateMutexStatic ( &uart_mutex );
}

void send_string(const char *str)
{
    xSemaphoreTake(h_uart_mutex, ( TickType_t ) 1000);
    HAL_UART_Transmit(&huart2, (uint8_t *)str, strlen(str), 100);
    xSemaphoreGive(h_uart_mutex);
}

void StartTask02(void const * argument)
{
  /* Infinite loop */
  for(;;)
  {
    send_string("T2\r\n");
    osDelay(1000);
  }
}

另一种方法是使用消息队列之类的东西,您的任务将字符串输入其中,另一个任务将它们读出并将它们发送到 UART。但在我看来,这更加复杂,并且在内部它可能无论如何都使用互斥体来保护队列。

© www.soinside.com 2019 - 2024. All rights reserved.