以前我们都是一个任务,假设现在我们创建三个任务,项目工程在上一节网盘
#include "stm32f10x.h" // Device header
#include "freertos.h"
#include "task.h"
#include "usart.h"TaskHandle_t myTaskHandler1;
TaskHandle_t myTaskHandler2;
TaskHandle_t myTaskHandler3;void myTask1( void * arg)
{while(1){printf("myTask1 running\n");vTaskDelay(200);}}void myTask2( void * arg)
{while(1){printf("myTask2 running\n");vTaskDelay(200);}}void myTask3( void * arg)
{while(1){printf("myTask3 running\n");vTaskDelay(200);}}int main(void){GPIO_InitTypeDef GPIO_Initstruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Initstruct.GPIO_Pin = GPIO_Pin_13;GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_Initstruct);GPIO_ResetBits(GPIOC, GPIO_Pin_13);USART_Config();xTaskCreate(myTask1, "myTask1", 128, NULL, 2, &myTaskHandler1); xTaskCreate(myTask2, "myTask2", 128, NULL, 2, &myTaskHandler2); xTaskCreate(myTask3, "myTask3", 128, NULL, 2, &myTaskHandler3); vTaskStartScheduler();while(1){}}StaticTask_t IdleTaskTCB;
StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{*ppxIdleTaskTCBBuffer = &IdleTaskTCB;*ppxIdleTaskStackBuffer = IdleTaskStack; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;}
现象如下,这时会发现模拟串口仿真输出的是乱序的
出现多个线程竞争同一个输出函数,非线程安全,这样我们对临界区实现保护:
#include "stm32f10x.h" // Device header
#include "freertos.h"
#include "task.h"
#include "usart.h"TaskHandle_t myTaskHandler1;
TaskHandle_t myTaskHandler2;
TaskHandle_t myTaskHandler3;void myTask1( void * arg)
{while(1){taskENTER_CRITICAL();printf("myTask1 running\n");taskEXIT_CRITICAL();vTaskDelay(200);}}void myTask2( void * arg)
{while(1){taskENTER_CRITICAL();printf("myTask2 running\n");taskEXIT_CRITICAL();vTaskDelay(200);}}void myTask3( void * arg)
{while(1){taskENTER_CRITICAL();printf("myTask3 running\n");taskEXIT_CRITICAL();vTaskDelay(200);}}int main(void){GPIO_InitTypeDef GPIO_Initstruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Initstruct.GPIO_Pin = GPIO_Pin_13;GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_Initstruct);GPIO_ResetBits(GPIOC, GPIO_Pin_13);USART_Config();xTaskCreate(myTask1, "myTask1", 128, NULL, 2, &myTaskHandler1); xTaskCreate(myTask2, "myTask2", 128, NULL, 2, &myTaskHandler2); xTaskCreate(myTask3, "myTask3", 128, NULL, 2, &myTaskHandler3); vTaskStartScheduler();while(1){}}StaticTask_t IdleTaskTCB;
StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{*ppxIdleTaskTCBBuffer = &IdleTaskTCB;*ppxIdleTaskStackBuffer = IdleTaskStack; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;}
然后我们试验一下删除任务在mytask1里实现:
void myTask1( void * arg)
{uint8_t i=0;while(1){taskENTER_CRITICAL();printf("myTask1 running\n");taskEXIT_CRITICAL();vTaskDelay(200);i++;if(i==2){vTaskDelete(myTaskHandler2);}else if(i==3){vTaskDelete(NULL);}else if(i==4){vTaskDelete(myTaskHandler3);}}}
现象如下
还有一种创建多任务的实现。使用开始任务创建其他任务,感觉为了好看规整点吧…
#include "stm32f10x.h" // Device header
#include "freertos.h"
#include "task.h"
#include "usart.h"TaskHandle_t myTaskHandler1;
TaskHandle_t myTaskHandler2;
TaskHandle_t myTaskHandler3;
TaskHandle_t startTaskHandler;void myTask1( void * arg)
{uint8_t i=0;while(1){taskENTER_CRITICAL();printf("myTask1 running\n");taskEXIT_CRITICAL();i++;if(i==1){vTaskDelete(myTaskHandler3);}else if(i==2){vTaskDelete(NULL);}vTaskDelay(200);}}void myTask2( void * arg)
{while(1){taskENTER_CRITICAL();printf("myTask2 running\n");taskEXIT_CRITICAL();vTaskDelay(200);}}void myTask3( void * arg)
{while(1){taskENTER_CRITICAL();printf("myTask3 running\n");taskEXIT_CRITICAL();vTaskDelay(200);}}void startTask(void* arg){taskENTER_CRITICAL();printf("start running\n");taskEXIT_CRITICAL();xTaskCreate(myTask1, "myTask1", 128, NULL, 2, &myTaskHandler1); xTaskCreate(myTask2, "myTask2", 128, NULL, 2, &myTaskHandler2); xTaskCreate(myTask3, "myTask3", 128, NULL, 2, &myTaskHandler3); vTaskDelete(NULL);
}
int main(void){GPIO_InitTypeDef GPIO_Initstruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Initstruct.GPIO_Pin = GPIO_Pin_13;GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_Initstruct);GPIO_ResetBits(GPIOC, GPIO_Pin_13);USART_Config();xTaskCreate(startTask,"startTask",128,NULL,2,&startTaskHandler);vTaskStartScheduler();while(1){}}StaticTask_t IdleTaskTCB;
StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{*ppxIdleTaskTCBBuffer = &IdleTaskTCB;*ppxIdleTaskStackBuffer = IdleTaskStack; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;}
不过这样创建的任务在相同优先级下会按照创建的顺序执行