DIY:给单片机写个实时操作系统内核!
度的方法,在实时操作系统中常用,这种方法的原理就是:操作系统在任何时候都要保证拥有最高优先级的那个任务处于运行态,比如此记在运行着优先级为2的任务,因为一些信号到达,优先级为1的那个任务解除了阻塞,处于就绪态,这时操作系统就必须马上停止任务2,切换到任务1,切换的这段时间需要越短越好。
而时间片轮询即是让每个任务都处于平等地位,然后给每个任务相同的时间片,当一个任务的运行时间用完了,操作系统就马上切换给下一个需要执行的任务,这种方法的实时性不高,但它确保了每个任务都有相同的执行时间。
我把这两种方法结合起来,首先设定了8个优先级组,每个优先级组下面都用单向链表把具有相同优先级的任务连接起来。这样的话首先操作系统会查找最高优先级的那组,然后在组里面轮流执行所有任务(和UCOS II相比这种做法更具有灵活性,因为UCOS II只有抢占式调度,这是UCOS II的硬伤。。)。我声明了一个任务结构体称为线程控制块,把关于该任务的所有状态都放在一起:
/**
* @结构体声明
* @名称 : OS_TCB , *pOS_TCB
* @成员 : 1. OS_DataType_ThreadStack *ThreadStackTop
* 线程人工堆栈栈顶指针
* 2. OS_DataType_ThreadStack *ThreadStackBottom
* 线程人工堆栈栈底指针
* 3. OS_DataType_ThreadStackSize ThreadStackSize
* 线程人工堆栈大小
* 4. OS_DataType_ThreadID ThreadID
* 线程ID号
* 5. OS_DataType_ThreadStatus ThreadStatus
* 线程运行状态
* 6. OS_DataType_PSW PSW
* 记录线程的程序状态寄存器
* 7. struct _OS_TCB *Front
* 指向上一个线程控制块的指针
* 8. struct _OS_TCB *Next
* 指向下一人线程控制块的指针
* 9.struct _OS_TCB *CommWaitNext ;
* 指向线程通信控制块的指针
* 10.struct _OS_TCB *TimeWaitNext ;
* 指向延时等待链表的指针
* 11.OS_DataType_PreemptionPriority Priority ;
* 任务优先级
* 12.OS_DataType_TimeDelay TimeDelay ;
* 任务延时时间
* @描述 : 定义线程控制块的成员
* @建立时间 : 2011-11-15
* @最近修改时间: 2011-11-17
*/
typedef struct _OS_TCB{
OS_DataType_ThreadStack *ThreadStackTop ;
OS_DataType_ThreadStack *ThreadStackBottom ;
OS_DataType_ThreadStackSize ThreadStackSize;
OS_DataType_ThreadID ThreadID ;
OS_DataType_ThreadStatus ThreadStatus ;
OS_DataType_PSW PSW ;
struct _OS_TCB *Front ;
struct _OS_TCB *Next ;
#if OS_COMMUNICATION_EN == ON
struct _OS_TCB *CommWaitNext ;
#endif
struct _OS_TCB *TimeWaitNext ;
OS_DataType_PreemptionPriority Priority ;
OS_DataType_TimeDelay TimeDelay ;
}OS_TCB,*pOS_TCB;
首先启动系统的时候需要先创建任务,任务被创建之后才可以得到执行,使用如下函数:
/**
* @名称:线程创建函数
* @输入参数:1.pOS_TCB ThreadControlBlock 线程控制块结构体指针
* 2.void (*Thread)(void*) 线程函数入口地址,接受一个空指针形式的输入参数,无返回参数
* 3.void *Argument 需要传递给线程的参数,空指针形式
* @建立时间 : 2011-11-18
* @最近修改时间: 2011-11-18
*/
void OS_ThreadCreate(pOS_TCB ThreadControlBlock,void (*Thread)(void *),void *Argument)
关于创建任务的大致描述就是:填定线程控制块,把线程控制块链到单向链表中,设置人工堆栈,细节很多,就不一一赘述了。
当前版本只实现了轮询调度,还没加上抢占调度,使用下面的函数就可以启动操作系统开始多线程任务!
/**
* @名称 : 实时内核引发函数
* @版本 : V 0.0
* @输入参数 : 无
* @输出参数 : 无
* @描述 : 在主函数中用于启动,调用该函数后不会返回,直接切换到最高优先级任务开始执行
* @建立时间 : 2011-11-15
* @最近修改时间: 2011-11-15
*/
void OS_KernelStart(void)
{
OS_Status = OS_RUNNING ; //把内核状态设置为运行态
//取得第一个需要运行的任务
OS_CurrentThread = OS_TCB_PriorityGroup[pgm_read_byte(ThreadSearchTab + OS_PreemptionPriority)].OS_TCB_Current;
OS_LastThread = NULL ;
DIY单片机实时操作系统内 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)