UCOSII操作系统 第3课—UCOSII启动过程

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

大家好,又见面了,我是你们的朋友全栈君。

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 ) == 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);
}

此函数就是最终的函数,与硬件所在的平台是不一样的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/139806.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 圣经中基甸的故事_马热伊基艾

    圣经中基甸的故事_马热伊基艾给定一个包含 n 个点 m 条边的有向图,每条边都有一个流量下界和流量上界。给定源点 S 和汇点 T,求源点到汇点的最小流。输入格式第一行包含四个整数 n,m,S,T。接下来 m 行,每行包含四个整数 a,b,c,d 表示点 a 和 b 之间存在一条有向边,该边的流量下界为 c,流量上界为 d。点编号从 1 到 n。输出格式输出一个整数表示最小流。如果无解,则输出 No Solution。数据范围1≤n≤50003,1≤m≤125003,1≤a,b≤n,0≤c≤d≤21474836

  • mbus水表方案_水表安装合同模板

    mbus水表方案_水表安装合同模板MBUS水表协议2400!!8E1???偶校验???NOCTS/RTS1.查询水表地址FEFEFE68AAAAAAAAAAAAAAAA0303810A004916起始A0……………A6CTR_0DI0DI1CSFEFEFE68AAAAAAAAAAAAAAAA0303810A004916T

    2022年10月10日
  • http请求报400报错

    http请求报400报错400是HTTP的状态码,主要有两种形式:1、badrequest意思是“错误的请求”;2、invalidhostname意思是“不存在的域名”。在ajax请求后台数据时有时会报HTTP400错误-请求无效(Badrequest);出现这个请求无效报错说明请求没有进入到后台服务里;1、确认发送的数据格式是否正确。调试查看你发送的数据格式是否正确或是否有乱码…

  • 小技巧 – Chrome 浏览器绕过“请在微信客户端打开链接”

    小技巧 – Chrome 浏览器绕过“请在微信客户端打开链接”微信和QQ内置浏览器UA~安卓QQ内置浏览器UAMozilla/5.0(Linux;Android5.0;SM-N9100Build/LRX21V)>AppleWebKit/537.36(KHTML,likeGecko)Version/4.0>Chrome/37.0.0.0MobileSafari/537.36V1_AND_SQ_5.3.1_196_YYB_D>QQ/5.3.1.2335NetType/WIFI安卓…

  • 高性能微服务网关.NETCore客户端Kong.Net开源发布

    高性能微服务网关.NETCore客户端Kong.Net开源发布前言项目地址:https://github.com/lianggx/Kong.Net你的支持使我们更加强大,请单击star让更多的.NETCore认识它。拥抱开源的脚步,我们从来都是一直

  • 关于ubuntu 18 SSH root 登录失败,设置PermitRootLogin = yes 也失败

    关于ubuntu 18 SSH root 登录失败,设置PermitRootLogin = yes 也失败切换到root用户下。apt-getinstallssh再次尝试就可以了这里我的问题是,/home下的用户安装了ssh了,但是,root用户没有安装。????这是区分的。

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号