×
单片机 > 单片机程序设计 > 详情

基于STM32F4的FreeRTOS_笔记2_打印输出字符串

发布时间:2020-05-30 发布时间:
|

曾快速浏览过一遍《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 runningrn";

static const char *pcTextForTask2 = "Task 2 is runningrn";


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实时内核使用指南》的后续章节中涉及。




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯