以前我们都是一个任务,假设现在我们创建三个任务,项目工程在上一节网盘
#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;
}
不过这样创建的任务在相同优先级下会按照创建的顺序执行