1、 修改TCB控制块,在后面添加TickType_t xTicksToDelay;
typedef struct tskTaskControlBlock{
volatile StackType_t *pxTopOfStack;
ListItem_t xStateListItem;
StackType_t *pxStack;
char pcTaskName[configMAX_TASK_NAME_LEN];
TickType_t xTicksToDelay; /* 用于延时 */
}taskTCB;
2、 编写空闲任务相关
2.1、 在FreeRTOS文件夹下新建idle_task.c和idle_task.h,添加到工程中。
2.2、 撸代码
#include "task.h"
#include "portable.h"
#include "idle_task.h"
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
TCB_t IdleTaskTCB;
uint32_t idle_task_flag1=0;
static void prvIdleTask( void *p_arg )
{
uint32_t temp=0;
( void ) p_arg;
for(;;)
{
temp++;
if (temp>6000)
{
temp=0;
idle_task_flag1++;
idle_task_flag1 = idle_task_flag1&0x01;
}
}
}
void AppTaskCreateIdleTask(void)
{
xTaskCreateStatic(prvIdleTask,"IdleTask",configMINIMAL_STACK_SIZE,0,IdleTaskStack,&IdleTaskTCB);
/* 插入就绪列表*/
vListInsertEnd( &( pxReadyTasksLists[0] ), &( ((TCB_t *)(&IdleTaskTCB))->xStateListItem ) );
}
3、实现阻塞延时。在task.c文件下编写vTaskDelay ()函数。
void vTaskDelay(const TickType_t xTicksToDelay)
{
TCB_t *pxTCB = NULL;
pxTCB = pxCurrentTCB;
pxTCB->xTicksToDelay = xTicksToDelay;
taskYIELD();
}
4、 修改 vTaskSwitchContext()函数
void vTaskSwitchContext( void )
{
if (pxCurrentTCB==&IdleTaskTCB)
{
if (Task1TCB.xTicksToDelay == 0)
{
pxCurrentTCB = &Task1TCB;
}else if (Task2TCB.xTicksToDelay == 0)
{
pxCurrentTCB = &Task2TCB;
}
}else if (pxCurrentTCB==&Task1TCB)
{
if (Task2TCB.xTicksToDelay == 0)
{
pxCurrentTCB = &Task2TCB;
}else
{
pxCurrentTCB = &IdleTaskTCB;
}
}else if (pxCurrentTCB==&Task2TCB)
{
if (Task1TCB.xTicksToDelay == 0)
{
pxCurrentTCB = &Task1TCB;
}else
{
pxCurrentTCB = &IdleTaskTCB;
}
}
}
5、 编写SysTick中断服务函数
5.1、 在FreeRTOS文件夹下新建sys_tick.c和sys_tick.h,添加到工程中。
5.2、 撸代码
#include "sys_tick.h"
#include "port.h"
#include "task.h"
#include "task_lists.h"
// SysTick 中断服务函数======================================
#define configCPU_CLOCK_HZ ( ( unsigned long ) 25000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 100 )
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
void vPortSetupTimerInterrupt(void)
{
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT |
portNVIC_SYSTICK_INT_BIT |
portNVIC_SYSTICK_ENABLE_BIT );
}
static volatile TickType_t xTickCount = ( TickType_t ) 0U;
void xTaskIncrementTick( void )
{
TCB_t *pxTCB = NULL;
BaseType_t i = 0;
const TickType_t xConstTickCount = xTickCount + 1;
xTickCount = xConstTickCount;
for(i=0; i<configMAX_PRIORITIES; i++)
{
pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &pxReadyTasksLists[i] ) );
if(pxTCB->xTicksToDelay > 0)
{
pxTCB->xTicksToDelay --;
}
}
portYIELD();
}
6、 在port.c文件添加如下代码
void xPortSysTickHandler( void )
{
vPortRaiseBASEPRI();
xTaskIncrementTick();
vPortClearBASEPRIFromISR();
}
7、 修改Task1_Entry和Task2_Entry函数
uint32_t flag1=0;
uint32_t flag2=0;
void Task1_Entry( void *p_arg )
{
for( ;; )
{
flag1 = 1;
vTaskDelay(2);//delay( 100 );
flag1 = 0;
vTaskDelay(2);//delay( 100 );
//portYIELD();
}
}
void Task2_Entry( void *p_arg )
{
for( ;; )
{
flag2 = 1;
vTaskDelay(2);//delay( 100 );
flag2 = 0;
vTaskDelay(2);//delay( 100 );
//portYIELD();
}
}
8、 修改main.c
int main(void)
{
/* 就绪列表初始化*/
prvInitialiseTaskLists();
/* 创建任务1*/
Task1_Handle = xTaskCreateStatic(Task1_Entry,"task1",TASK1_STACK_SIZE,0,Task1Stack,&Task1TCB);
/* 插入就绪列表*/
vListInsertEnd( &( pxReadyTasksLists[1] ), &( ((TCB_t *)(&Task1TCB))->xStateListItem ) );
/* 创建任务2*/
Task2_Handle = xTaskCreateStatic(Task2_Entry,"task2",TASK2_STACK_SIZE,0,Task2Stack,&Task2TCB);
/* 插入就绪列表*/
vListInsertEnd( &( pxReadyTasksLists[2] ), &( ((TCB_t *)(&Task2TCB))->xStateListItem ) );
/* 创建空闲任务*/
AppTaskCreateIdleTask();
/* 初始化 SysTick*/
vPortSetupTimerInterrupt();
/*启动任务*/
vTaskStartScheduler();
//理论是不会到这里
while(1){}
}
运行结果如下