创建多任务只需要按照创建单任务的套路依葫芦画瓢即可,接下来我们创建两个任务,
    任务 1 让一个 LED 灯闪烁,任务 2 让另外一个 LED 闪烁,两个 LED 闪烁的频率不一样。
    注意:两个任务的优先级不一样。使用还是比较简单的。

    1. /* 包含头文件 ----------------------------------------------------------------*//* Includes ------------------------------------------------------------------*/
    2. #include "stm32f10x.h"
    3. /* FreeRTOS头文件 */
    4. #include "FreeRTOS.h"
    5. #include "task.h"
    6. /* 开发板硬件bsp头文件 */
    7. #include "bsp_usart.h"
    8. #include "bsp_led.h"
    9. /* 私有类型定义 --------------------------------------------------------------*/
    10. /* 私有宏定义 ----------------------------------------------------------------*/
    11. /* 私有变量 ------------------------------------------------------------------*/
    12. /*
    13. * 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
    14. * 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
    15. * 这个句柄可以为NULL。
    16. */
    17. /* 创建任务句柄 */
    18. static TaskHandle_t AppTaskCreate_Handle = NULL;
    19. /* LED任务句柄 */
    20. static TaskHandle_t LED_Task_Handle = NULL;
    21. /* LED2任务句柄 */
    22. static TaskHandle_t LED2_Task_Handle = NULL;
    23. /* 扩展变量 ------------------------------------------------------------------*/
    24. /* 私有函数原形 --------------------------------------------------------------*/
    25. static void BSP_Init(void);
    26. static void LED_Task(void* parameter);
    27. static void AppTaskCreate(void);
    28. static void LED2_Task(void* parameter);
    29. /* 函数体 --------------------------------------------------------------------*/
    30. /**
    31. * 函数功能: 主函数.
    32. * 输入参数: 无
    33. * 返 回 值: 无
    34. * 说 明: 无
    35. */
    36. int main(void)
    37. {
    38. BaseType_t xReturn = pdPASS;
    39. BSP_Init();
    40. /* 创建AppTaskCreate任务 */
    41. xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */
    42. (const char* )"AppTaskCreate", /* 任务名字 */
    43. (uint16_t )512, /* 任务栈大小 */
    44. (void* )NULL, /* 任务入口函数参数 */
    45. (UBaseType_t )1, /* 任务的优先级 */
    46. (TaskHandle_t* )&AppTaskCreate_Handle); /* 任务控制块指针 */
    47. /* 启动任务调度 */
    48. if(pdPASS == xReturn)
    49. vTaskStartScheduler(); /* 启动任务,开启调度 */
    50. else
    51. return -1;
    52. }
    53. /***********************************************************************
    54. * @ 函数名 : AppTaskCreate
    55. * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
    56. * @ 参数 : 无
    57. * @ 返回值 : 无
    58. **********************************************************************/
    59. static void AppTaskCreate(void)
    60. {
    61. BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
    62. taskENTER_CRITICAL(); //进入临界区
    63. /* 创建LED_Task任务 */
    64. xReturn = xTaskCreate((TaskFunction_t )LED_Task, /* 任务入口函数 */
    65. (const char* )"LED_Task", /* 任务名字 */
    66. (uint16_t )512, /* 任务栈大小 */
    67. (void* )NULL, /* 任务入口函数参数 */
    68. (UBaseType_t )2, /* 任务的优先级 */
    69. (TaskHandle_t* )&LED_Task_Handle); /* 任务控制块指针 */
    70. if(pdPASS == xReturn)
    71. printf("创建LED1_Task任务成功!\r\n");
    72. /* 创建LED_Task任务 */
    73. xReturn = xTaskCreate((TaskFunction_t )LED2_Task, /* 任务入口函数 */
    74. (const char* )"LED2_Task",/* 任务名字 */
    75. (uint16_t )512, /* 任务栈大小 */
    76. (void* )NULL, /* 任务入口函数参数 */
    77. (UBaseType_t )3, /* 任务的优先级 */
    78. (TaskHandle_t* )&LED2_Task_Handle);/* 任务控制块指针 */
    79. if(pdPASS == xReturn)
    80. printf("创建LED2_Task任务成功!\r\n");
    81. vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
    82. taskEXIT_CRITICAL(); //退出临界区
    83. }
    84. /**********************************************************************
    85. * @ 函数名 : LED_Task
    86. * @ 功能说明: LED_Task任务主体
    87. * @ 参数 :
    88. * @ 返回值 : 无
    89. ********************************************************************/
    90. static void LED_Task(void* parameter)
    91. {
    92. while (1)
    93. {
    94. LED1_ON;
    95. vTaskDelay(500); /* 延时500个tick */
    96. printf("LED_Task Running,LED1_ON\r\n");
    97. LED1_OFF;
    98. vTaskDelay(500); /* 延时500个tick */
    99. printf("LED_Task Running,LED1_OFF\r\n");
    100. }
    101. }
    102. /**********************************************************************
    103. * @ 函数名 : LED_Task
    104. * @ 功能说明: LED_Task任务主体
    105. * @ 参数 :
    106. * @ 返回值 : 无
    107. ********************************************************************/
    108. static void LED2_Task(void* parameter)
    109. {
    110. while (1)
    111. {
    112. LED2_ON;
    113. vTaskDelay(500); /* 延时500个tick */
    114. printf("LED2_Task Running,LED2_ON\r\n");
    115. LED2_OFF;
    116. vTaskDelay(500); /* 延时500个tick */
    117. printf("LED2_Task Running,LED2_OFF\r\n");
    118. }
    119. }
    120. /***********************************************************************
    121. * @ 函数名 : BSP_Init
    122. * @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
    123. * @ 参数 :
    124. * @ 返回值 : 无
    125. *********************************************************************/
    126. static void BSP_Init(void)
    127. {
    128. /*
    129. * STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15
    130. * 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
    131. * 都统一用这个优先级分组,千万不要再分组,切忌。
    132. */
    133. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    134. /* LED初始化 */
    135. LED_GPIO_Init();
    136. LED1_ON;
    137. /* 串口初始化 */
    138. USART_Config();
    139. }