基于PendSV 双任务时间片切换
// 定义任务um_task task1; //任务1
um_task task2; //任务2
um_task task_idle;//空闲任务
// 定义任务堆栈
um_stacktask1_stack;
um_stacktask2_stack;
um_stacktask_idle_stack;
um_task *CurrentTask,*NextTask;
um_task *TaskTable;
void task1_thread(void *param);
void task2_thread(void *param);
void TaskInit(um_task *task,void(*entry)(void*),void *param,unsigned int *task_tack);
void Um_TaskSched();
void ProductPendSV();
// 任务调度
void Um_TaskSched()
{
if(CurrentTask == TaskTable)
{
if(TaskTable->DelayTicks == 0)
NextTask = TaskTable;
else if(TaskTable->DelayTicks == 0)
NextTask = TaskTable;
elsereturn;
}
else
{
if(CurrentTask == TaskTable)
{
if(TaskTable->DelayTicks == 0)
NextTask = TaskTable;
else if(CurrentTask->DelayTicks != 0)
NextTask = TaskTable;
}
else if(CurrentTask == TaskTable)
{
if(TaskTable->DelayTicks == 0)
NextTask = TaskTable;
else if(CurrentTask->DelayTicks != 0)
NextTask = TaskTable;
}
}
ProductPendSV();
}
// 设置Systick 中断定时
void SetSysTickPeriod(unsigned int ms)
{
SysTick->LOAD = ms * SystemCoreClock/1000 -1;
NVIC_SetPriority(SysTick_IRQn,(1<<__NVIC_PRIO_BITS)-1);
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
}
// Systick 中断函数
void SysTick_Handler()
{
int i;
for(i=0;i<2;i++)
{
if(TaskTable->DelayTicks >0)
{
TaskTable->DelayTicks--;
}
}
Um_TaskSched();
}
// 任务延时函数
void TaskDelay(unsigned int delay)
{
CurrentTask->DelayTicks = delay;
Um_TaskSched();
}
// 任务1 任务2 空闲任务 初始化任务
unsigned char flag1,flag2;
void task1_thread(void *param)
{
SetSysTickPeriod(10);
while(1)
{
flag1 = 1;
TaskDelay(10);
flag1 = 0;
TaskDelay(10);
}
}
void task2_thread(void *param)
{
while(1)
{
flag2 = 1;
TaskDelay(10);
flag2 = 0;
TaskDelay(10);
}
}
void idel_thread(void *param)
{
while(1)
{
}
}
void FirstTask()
{
__set_PSP(0);
ProductPendSV();
}
主函数
int main()
{
TaskInit(&task1,task1_thread,(void*)1234,&task1_stack);
TaskInit(&task2,task2_thread,(void*)5678,&task2_stack);
TaskInit(&task_idle,idel_thread,(void*)0023,&task_idle_stack);
TaskTable = &task1;
TaskTable = &task2;
TaskTable = &task_idle;
NextTask = TaskTable;
FirstTask();
}
//任务初始化函数
void TaskInit(um_task *task,void(*entry)(void*),void *param,um_stack *task_tack)
{
*(--task_tack) = (unsigned long)(1<<24);
*(--task_tack) = (unsigned long)entry; //pc寄存器
*(--task_tack) = (unsigned long)0x14;
*(--task_tack) = (unsigned long)0x12;
*(--task_tack) = (unsigned long)0x3;
*(--task_tack) = (unsigned long)0x2;
*(--task_tack) = (unsigned long)0x1;
*(--task_tack) = (unsigned long)param;
*(--task_tack) = (unsigned long)0x11;
*(--task_tack) = (unsigned long)0x10;
*(--task_tack) = (unsigned long)0x9;
*(--task_tack) = (unsigned long)0x8;
*(--task_tack) = (unsigned long)0x7;
*(--task_tack) = (unsigned long)0x6;
*(--task_tack) = (unsigned long)0x5;
*(--task_tack) = (unsigned long)0x4;
task->stack_addr = task_tack;
task->DelayTicks = 0;
}
// 进入临界区保护
unsigned int TaskEnterCritical()
{
unsigned int primask;
primask = __get_PRIMASK();
__disable_irq();
return primask;
}
// 退出临界区保护
void TaskExitCritical(unsigned int status)
{
__set_PRIMASK(status);
}
// PendSV异常
void ProductPendSV()
{
*(volatile unsigned long *)NVIC_SYSPRI2 = NVIC_PENDSV_PRI;
*(volatile unsigned long *)NVIC_INT_CTRL = NVIC_PENDSV_SET;
}
// PendSV中断处理函数
__asm__ void PendSV_Handler(void)
{
IMPORT CurrentTask
IMPORT NextTask
MRS R0, PSP //将PSP寄存器保存到R0中
CBZ R0,PendSVHander_nosave //判断PSP寄存器的值是否为0 从而判断是否是
//FirstTask任务触发还是umTaskSwitch()触发
STMDB R0!,{R4-R11}
LDR R1, = CurrentTask
LDR R1,
STR R0,
PendSVHander_nosave
LDR R0, = CurrentTask //完成了nextTask向currentTask赋值操作
LDR R1, = NextTask
LDR R2,
STR R2,
LDR R0, //从currentTask取出堆栈的地址
LDMIA R0!,{R4-R11} //批量加载R4-R11寄存器
MSR PSP,R0
ORR LR,LR,#0x04
BXLR
} 不错
页:
[1]