基於STM32F4的FreeRTOS_筆記2_打印輸出字符串

曾快速瀏覽過一遍《FreeRTOS實時內核使用指南》,但過後不久一些簡單的概念卻又忘了,遂決定把其中的示例程序都自己寫一遍,以加深記憶。

關於printf()

在此用printf()函數代替示例中的vPrintString()函數,以實現通過串口將相應的字符串打印至串口助手上。對此,ST的庫函數中有相應的例程,需要將以下代碼添加到程序中:

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}

  return ch;
}

此外,還需要勾選Use MicroLIB和添加stdio.h頭文件。

示例代碼

參照《FreeRTOS實時內核使用指南》例2,通過同一個任務代碼創建兩個任務實例,以此實現兩個任務分別打印輸出Task 1 is running和Task 2 is running。

將程序清單8改寫如下:

void vTaskFunction(void *pvParameters)
{
    /* 需要打印輸出的字符串從入口參數傳入,強制轉換爲字符串指針。 */
    const char *pcTaskName = (char *)pvParameters;
    volatile unsigned long ul;

    while(1)
    {
        /* 打印輸出任務名 */
        printf(pcTaskName);

        /* 用以產生一個週期延時 */
        for(ul = 0; ul < mainDELAY_LOOP_COUNT; ul++)
        {
        }
    }
}

將程序清單9改寫如下:

static const char *pcTextForTask1 = "Task 1 is running\r\n";
static const char *pcTextForTask2 = "Task 2 is running\r\n";

int main(void)
{
    /* Perform any hardware setup necessary. */
    prvSetupHardware();

    /* --- APPLICATION TASKS CAN BE CREATED HERE --- */
    /* 由相同的任務代碼創建多個任務,僅是傳入的參數不同。 */
    xTaskCreate(vTaskFunction, "Task 1", 1000, (void *)pcTextForTask1, 1, NULL);
    xTaskCreate(vTaskFunction, "Task 2", 1000, (void *)pcTextForTask2, 1, NULL);

    /* Start the created tasks running. */
    vTaskStartScheduler();

    /* Execution will only reach here if there was insufficient heap to
    start the scheduler. */
    while(1);
}

打印輸出字符串效果如下圖所示:

不難看出輸出結果未達到預期,這是因爲時間片長度太短,以致在一個時間片長度內未能輸出全部字符串便被另一個任務所打斷,參考《FreeRTOS實時內核使用指南》第17頁的相關內容,不妨將configTICK_RATE_HZ設爲100(HZ),效果如下圖所示:

不難看出依舊有一定的機率發生一個任務打斷另一個正在輸出字符串的任務,徹底解決此問題將在《FreeRTOS實時內核使用指南》的後續章節中涉及。

相關鏈接

源代碼下載

《FreeRTOS實時內核使用指南》下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章