尝试写个简单任务调度内核voidtask
尝试写个简单任务调度内核。自己写的玩玩,不保证正确,还没在目标板试过。
1.任务只有延时,切换功能。
2.任务切换未保护所有寄存器。
3.没有空闲任务,空闲时切换到主函数。
4.IAR必须设置STACK_DOUL为1,GCC必须设置STACK_DOUL为0。
#include "config.h"
TTask TaskA,TaskB,TaskC;
TTimer TimerA ,TimerB ,TimerC ;
void TaskAProc(void)
{
while(1)
{
PORTD^=_BV(7);
TMR_Delay(&TimerA,3);
}
}
void TaskBProc(void)
{
while(1)
{
PORTD^=_BV(6);
TMR_Delay(&TimerB,4);
}
}
void TaskCProc(void)
{
while(1)
{
PORTD^=_BV(5);
TMR_Delay(&TimerC,5);
}
}
int main()
{
DDRD=_BV(7)|_BV(6)|_BV(5);
PORTD=_BV(7)|_BV(6)|_BV(5);
TCNT2 = 0;
TCCR2A=_BV(WGM21);
TCCR2B = T2_CLK_DIV_128;
OCR2A=OCR2A_INIT;
TIFR2|=_BV(OCF2A);
TIMSK2=_BV(OCIE2A);
#if STACK_DOUL==1 //AVRIAR 双堆栈
TSK_Init(&TaskA,TaskAProc,0,64,32);
TSK_Init(&TaskB,TaskBProc,1,64,32);
TSK_Init(&TaskC,TaskCProc,2,64,32);
#else //AVRGCC 单堆栈
TSK_Init(&TaskA,TaskAProc,0,64+32);
TSK_Init(&TaskB,TaskBProc,1,64+32);
TSK_Init(&TaskC,TaskCProc,2,64+32);
#endif
sei();
TSK_Start();
while(1)
{
}
}
SIGNAL(TIMER2_COMPA_vect)
{
VT_TicksHander();
}
点击此处下载 ourdev_451011.rar(文件大小:213K) (原文件名:VoidTask.rar) 更新一下:
点击此处下载 ourdev_451643.rar(文件大小:129K) (原文件名:VoidTask.7z.rar)
顺便把以前写的TEvent,TEventTiny一并放上来。
点击此处下载 ourdev_451147.rar(文件大小:878K) (原文件名:TEvent20090606.7z.rar)
点击此处下载 ourdev_451148.rar(文件大小:1.12M) (原文件名:TEventTiny20090606.7z.rar) 更新一下:20090609
点击此处下载 ourdev_452201.rar(文件大小:135K) (原文件名:VoidTask.7z.rar)
#include "config.h"
TTask TaskA,TaskB,TaskC;
void TaskAProc(void)
{
sei();
while(1)
{
PORTD^=_BV(7);
TSK_Delay(VT_TICKS_PER_SEC/2);
}
}
void TaskBProc(void)
{
sei();
while(1)
{
PORTD^=_BV(6);
TSK_Delay(VT_TICKS_PER_SEC/3);
}
}
void TaskCProc(void)
{
sei();
while(1)
{
PORTD^=_BV(5);
TSK_Delay(VT_TICKS_PER_SEC/4);
}
}
int main()
{
DDRD=_BV(7)|_BV(6)|_BV(5);
PORTD=_BV(7)|_BV(6)|_BV(5);
TCNT2 = 0;
TCCR2=_BV(WGM21) | T2_CLK_DIV_128;
OCR2=OCR2_INIT;
TIFR|=_BV(OCF2);
TIMSK=_BV(OCIE2);
#if STACK_DOUL==1 //AVRIAR 双堆栈
TSK_Init(&TaskA,TaskAProc,0,64,32);
TSK_Init(&TaskB,TaskBProc,1,64,32);
TSK_Init(&TaskC,TaskCProc,2,64,32);
#else //AVRGCC 单堆栈
TSK_Init(&TaskA,TaskAProc,0,64+32);
TSK_Init(&TaskB,TaskBProc,1,64+32);
TSK_Init(&TaskC,TaskCProc,2,64+32);
#endif
sei();
TSK_Start();
while(1)
{
while(VT_MainScheduler());
SleepIdle();
}
}
SIGNAL(TIMER2_COMP_vect)
{
VT_TicksHander();
} 更新一下:20090610
移植到IAR8051
IAR8051堆栈处理很麻烦,汇编也不会,硬着头皮移植过来的,不保证正确。
任务切换只保护了寄存器:R6,R7,V0-Vn,VB,PSW,EA,DPH,DPL,SP
mcu是CC1110,必须设置为Near,Large,XDATA stack reentrant,1 DPTR。
#include "config.h"
TTask TaskA,TaskB,TaskC;
void TaskAProc(void)
{
volatile float f1=1.0; //测试浮点运算
EA=1;
while(1)
{
P0_7=!P0_7;
f1+=0.1;
TSK_Delay(VT_TICKS_PER_SEC/2);
}
}
void TaskBProc(void)
{
volatile float f2=1.0; //测试浮点运算
EA=1;
while(1)
{
P0_6=!P0_6;
f2+=0.1;
TSK_Delay(VT_TICKS_PER_SEC/3);
}
}
void TaskCProc(void)
{
volatile float f3=1.0; //测试浮点运算
EA=1;
while(1)
{
f3+=0.1;
TSK_Delay(VT_TICKS_PER_SEC/4);
}
}
int main()
{
CLK_RC_TO_XOSC();
P0DIR|=_BV(6)|_BV(7);
TSK_Init(&TaskA,TaskAProc,0,100);
TSK_Init(&TaskB,TaskBProc,1,100);
TSK_Init(&TaskC,TaskCProc,2,100);
TMR_TicksInit();
EA=1;
TSK_Start();
while(1)
{
while(VT_MainScheduler());
}
}
ISR(T4_VECTOR)
{
EA=0;
T4OVFIF = 0;
T4IF = 0;
VT_TicksHander();
EA=1;
}
点击此处下载 ourdev_452359.rar(文件大小:219K) (原文件名:VoidTask.7z.rar) 帮顶 更新一下:20090612
简化移植。
移植只需要重写两个函数CTX_Init和CTX_Swap(另外还有临界段)。
IAREWAVR:
#include "VT.h"
#if STACK_DOUL!=1
#error "STACK_DOUL must be 1 in avriar"
#endif
//上下文初始化,IAR是双堆栈,GCC是单堆栈
void CTX_Init(TContext **ppContext,TTaskProc *TaskCode,void *Stack1,void *Stack2)
{
ctx_sp_t *ctx_sp;
ctx_y_t*ctx_y;
ctx_y=(ctx_y_t *)((char *)Stack1) - 1;
ctx_sp=(ctx_sp_t *)Stack2 - 1;
ctx_sp->_pcl = (uint16)TaskCode%256;
ctx_sp->_pch = (uint16)TaskCode/256;
ctx_y->_spl= (uint16)ctx_sp%256;
ctx_y->_sph= (uint16)ctx_sp/256;
//ctx_y->_sreg = 0x00;
ctx_y->_r27 = 0x27;
ctx_y->_r26 = 0x26;
ctx_y->_r25 = 0x25;
ctx_y->_r24 = 0x24;
ctx_y->_r15 = 0x15;
ctx_y->_r14 = 0x14;
ctx_y->_r13 = 0x13;
ctx_y->_r12 = 0x12;
ctx_y->_r11 = 0x11;
ctx_y->_r10 = 0x10;
ctx_y->_r9= 0x9;
ctx_y->_r8= 0x8;
ctx_y->_r7= 0x7;
ctx_y->_r6= 0x6;
ctx_y->_r5= 0x5;
ctx_y->_r4= 0x4;
CRITICAL()
{
*ppContext=ctx_y;
}
}
//寄存器分为 "草稿寄存器“和 "存储寄存器" --------个人叫法
//外部函数可以任意使用草稿寄存器而不必恢复,而使用存储寄存器必须先保护
//AVRIAR
//草稿寄存器R0-R3,R16-R23,R30-R31
//存储寄存器R4-15,R24-R27
//特殊寄存器R28-R29
//AVRGCC
//草稿寄存器R18-R27,R30-R31
//存储寄存器R2-R17,R28-R29
//特殊寄存器R0-R1
//上下文切换只保护存储寄存器寄存器,sp
#define SAVE_CONTEXT() \
do{ \
asm("ST -Y, R4 "); \
asm("ST -Y, R5 "); \
asm("ST -Y, R6 "); \
asm("ST -Y, R7 "); \
asm("ST -Y, R8 "); \
asm("ST -Y, R9 "); \
asm("ST -Y, R10 "); \
asm("ST -Y, R11 "); \
asm("ST -Y, R12 "); \
asm("ST -Y, R13 "); \
asm("ST -Y, R14 "); \
asm("ST -Y, R15 "); \
asm("ST -Y, R24 "); \
asm("ST -Y, R25 "); \
asm("ST -Y, R26 "); \
asm("ST -Y, R27 "); \
asm("in R24,0x3D"); \
asm("ST -Y, R24 "); \
asm("IN R24,0x3E"); \
asm("ST -Y, R24 "); \
}while(0)
#define RESTORE_CONTEXT() \
do{ \
asm("LD R24,Y+ "); \
asm("OUT 0X3E, R24 "); \
asm("LD R24,Y+ "); \
asm("OUT 0X3D, R24 "); \
asm("LD R27,Y+ "); \
asm("LD R26,Y+ "); \
asm("LD R25,Y+ "); \
asm("LD R24,Y+ "); \
asm("LD R15,Y+ "); \
asm("LD R14,Y+ "); \
asm("LD R13,Y+ "); \
asm("LD R12,Y+ "); \
asm("LD R11,Y+ "); \
asm("LD R10,Y+ "); \
asm("LD R9, Y+ "); \
asm("LD R8, Y+ "); \
asm("LD R7, Y+ "); \
asm("LD R6, Y+ "); \
asm("LD R5, Y+ "); \
asm("LD R4, Y+ "); \
}while(0)
// R16:R17 R18:R19
void CTX_Swap(TContext **ppContext1,TContext **ppContext2)
{
SAVE_CONTEXT();
asm ("movw r30,r16"); //Z=ppContext1
asm ("st z+, r28"); //*ppContext1=Y
asm ("st z,r29");
asm ("movw r30,r18"); //Z=ppContext2
asm ("ld r28, z+"); //Y=*ppContext2
asm ("ld r29, z");
RESTORE_CONTEXT();
asm ("ret");
}
点击此处下载 ourdev_452919.rar(文件大小:200K) (原文件名:VoidTask.7z.rar) 更新一下:20090614
移植到STM32,只能使用主堆栈,上下文切换只保护R4-11,LR。
#include "VT.h"
#include "hal_cpu.h"
void CTX_Init(TContext **ppContext,TTaskProc *TaskProc,void *Stack1)
{
ctx_sp_t *ctx_sp;
ctx_sp=(ctx_sp_t *)Stack1 - 1; //调整上下文指针,预留空间保存上下文
ctx_sp->_lr = ((uint32)TaskProc); //填充任务地址
ctx_sp->_r4 = 0x04; //填充R4-R11
ctx_sp->_r5 = 0X05;
ctx_sp->_r6 = 0x06;
ctx_sp->_r7 = 0x07;
ctx_sp->_r8 = 0x08;
ctx_sp->_r9 = 0x09;
ctx_sp->_r10 = 0x10;
ctx_sp->_r11 = 0x11;
CRITICAL()
{
*ppContext=(void *)ctx_sp; //保存新的上下文指针
}
}
//寄存器分为 "草稿寄存器“和 "存储寄存器" --------个人叫法
//外部函数可以任意使用草稿寄存器而不必恢复,而使用存储寄存器必须先保护
//Cortex-M3
//草稿寄存器R0-R3,R12
//存储寄存器R4-11,
//特殊寄存器SP,LR,PC
//上下文切换只保护存储寄存器寄存器,lr
#define SAVE_CONTEXT() \
do{ \
asm ("push {r4-r11,lr}"); \
}while(0)
#define RESTORE_CONTEXT() \
do{ \
asm ("pop {r4-r11,lr}"); \
}while(0)
//注意:CM3任务只能使用主堆栈!!!!!!
//void CTX_Swap(TContext **ppContext1,TContext **ppContext2)
//SAVE_CONTEXT
//*ppContext1=SP
//SP=*ppContext2
//RESTOR_CONTEXT
//return
// r0 r1
void CTX_Swap(TContext **ppContext1,TContext **ppContext2)
{
SAVE_CONTEXT();
asm ("mov r4,sp"); //*ppContext1=SP
asm ("str r4,");
asm ("ldr r4,");//SP=*ppContext2
asm ("mov sp,r4");
RESTORE_CONTEXT();
asm ("bx lr");
}
点击此处下载 ourdev_453262.rar(文件大小:594K) (原文件名:VoidTask.7z.rar)
页:
[1]