从零开始学习UCOSII操作系统3--UCOSII启动过程
2018-03-29 18:31
555 查看
从零开始学习UCOSII操作系统3--UCOSII启动过程
1、初始化UCOSII
(1)在调用UCOSII在任何的其他的服务之前,UCOSII要求首先调用初始化函数OSInit();这个函数的目的就是在整个系统启动之前,初始化所有的变量和数据结构。(2)其中,在OSInit()函数中建立空闲任务OS_TaskIdle();
这个任务总是处于就绪态的,空闲任务的优先级是设置为最低的。
(3)调用OSInit以后,任务控制块缓冲池中有OS_MAX_TASKS个任务控制块,事件控制缓冲区中有OS_MAX_EVENTS个事件控制块,消息队列缓冲池OS_Q中有OS_MAX_QS个消息队列控制块等等。
2、UCOSII的启动过程
int main(void) { OSInit(); /* 系统初始化*/ /* 创建主任务*/ OSTaskCreate(MainTask, (void *)0, &MainTask_Stk[MainTask_StkSize-1], MainTask_Prio); OSStart(); /* 开始任务调度*/ return 0; }
(1)这是我们使用的一个移植到VS2013成功的UCOSII的代码工程。
里面有我们需要了解的启动UCOSII的全部的过程。
(2)刚刚说明的是OSInit()系统的初始化程序,就是为了初始化UCOSII启动过程的全部变量和一些内存池。
(3)通过调用OSTaskCreate()创建至少一个任务。
因为我们到时候,程序的指针SP,会跳出main.c的函数,那么如果不创建一个任务的话,那么程序的指针就会跑飞。
(4)OSStart()函数就是为了进行任务调度的,因为我们很快就会跳出main.c的函数,不会再跳进来,所以我们需要进行内部的指针跳出。
void OSStart (void) { if (OSRunning == OS_FALSE) { OS_SchedNew(); /* Find highest priority's task priority number */ OSPrioCur = OSPrioHighRdy; OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */ OSTCBCur = OSTCBHighRdy; OSStartHighRdy(); /* Execute target specific code to start task */ } }
(1)这是UCOSII启动的一个关键的函数,此函数记录了我们操作系统是怎么进入多任务的状态的。
(2)解析:当OS的状态等于错误的状态的时候,把当前的最高优先级的任务赋值给OS的当前的优先级。
(3)最高优先级是通过位图来进行查找的,按上一讲已经完全说清楚获取最高优先级的算法。
(4)OSStartHighRdy()此函数是这个开始函数的关键,也就是这个地方进行任务的切换的,就是我们上一节课说明的进入中断,然后把CPU寄存器的值进行切换,从而跳转到最高优先级的任务当中。
void OSStartHighRdy() { DWORD dwID; OSInitTrace(100000); OS_ENTER_CRITICAL(); OSTaskSwHook(); ++OSRunning; OSCtxSwW32Event = CreateEvent(NULL,FALSE,FALSE,NULL); OSCtxSwW32Handle = CreateThread( NULL, 0, OSCtxSwW32, 0, 0, &dwID ); SetPriorityClass(OSCtxSwW32Handle,THREAD_PRIORITY_HIGHEST); #ifdef SET_AFFINITY_MASK if( SetThreadAffinityMask( OSCtxSwW32Handle, 1 ) == 0 ) { #ifdef OS_CPU_TRACE OS_Printf("Error: SetThreadAffinityMask\n"); #endif } #endif SetThreadPriority(OSCtxSwW32Handle,THREAD_PRIORITY_TIME_CRITICAL); OSTick32Handle = CreateThread( NULL, 0, OSTickW32, 0, 0, &dwID ); SetPriorityClass(OSTick32Handle,THREAD_PRIORITY_HIGHEST); #ifdef SET_AFFINITY_MASK if( SetThreadAffinityMask( OSTick32Handle, 1 ) == b9e9 0 ) { #ifdef OS_CPU_TRACE OS_Printf("Error: SetThreadAffinityMask\n"); #endif } #endif SetThreadPriority(OSTick32Handle,THREAD_PRIORITY_HIGHEST); #ifdef WIN_MM_TICK timeGetDevCaps(&OSTimeCap, sizeof(OSTimeCap)); if( OSTimeCap.wPeriodMin < WIN_MM_MIN_RES ) OSTimeCap.wPeriodMin = WIN_MM_MIN_RES; timeBeginPeriod(OSTimeCap.wPeriodMin); OSTickEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); OSTickTimer = timeSetEvent((1000/OS_TICKS_PER_SEC),OSTimeCap.wPeriodMin,(LPTIMECALLBACK)OSTickEventHandle, dwID,TIME_PERIODIC|TIME_CALLBACK_EVENT_SET); #endif SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr; /* OSTCBCur = OSTCBHighRdy; */ /* OSPrioCur = OSPrioHighRdy; */ ResumeThread(SS_SP->Handle); OS_EXIT_CRITICAL(); WaitForSingleObject(OSCtxSwW32Handle,INFINITE); #ifdef WIN_MM_TICK timeKillEvent(OSTickTimer); timeEndPeriod(OSTimeCap.wPeriodMin); CloseHandle(OSTickEventHandle); #endif CloseHandle(OSTick32Handle); CloseHandle(OSCtxSwW32Event); }
此函数就是最终的函数,与硬件所在的平台是不一样的。
参考代码:移植UCOSII到VS2013程序
相关文章推荐
- 从零开始学习UCOSII操作系统1--UCOSII的基础知识
- 从零开始学习UCOSII操作系统5--时间管理
- 从零开始学习UCOSII操作系统6--事件控制块
- 操作系统学习(一)--概述启动过程
- 操作系统学习笔记(3)--内核启动过程
- 从零开始学习UCOSII操作系统12--内存管理
- 从零开始学习UCOSII操作系统9--事件标志组
- 从零开始学习UCOSII操作系统10--消息邮箱
- 从零开始学习UCOSII操作系统2--UCOSII的内核实现
- 从零开始学习UCOSII操作系统4--任务管理
- 从零开始学习UCOSII操作系统7--信号量
- [学习指导] linux 启动过程以及 /etc/rc.d/init.d/目录的一点理解
- Android应用程序的Activity启动过程简要介绍和学习计划
- Linux操作系统启动过程
- TMS320F28335学习笔记-启动过程
- Linux操作系统学习_用户态与内核态之切换过程
- android 学习笔记 Activity 和service 的启动过程
- 理解Linux的启动过程 ---好好学习呀
- 操作系统学习之程序编译,链接,加载过程中的内存管理
- Windows XP \Windows 2003启动过程的学习及故障分析处理(八)终极篇