前往小程序,Get更优阅读体验!
立即前往
社区首页 >专栏 >从零开始学习UCOSII操作系统3–UCOSII启动过程「建议收藏」

从零开始学习UCOSII操作系统3–UCOSII启动过程「建议收藏」

作者头像
用户10377643
发布于 2023-02-22 06:02:33
发布于 2023-02-22 06:02:33
78900
代码可运行
举报
文章被收录于专栏:开发学习开发学习
运行总次数:0
代码可运行

从零开始学习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的启动过程

代码语言:javascript
代码运行次数:0
复制
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的函数,不会再跳进来,所以我们需要进行内部的指针跳出。

代码语言:javascript
代码运行次数:0
复制
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寄存器的值进行切换,从而跳转到最高优先级的任务当中。

代码语言:javascript
代码运行次数:0
复制
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);
}

复制

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

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
UCOSII操作系统 第3课—UCOSII启动过程
(1)在调用UCOSII在任何的其他的服务之前,UCOSII要求首先调用初始化函数OSInit();这个函数的目的就是在整个系统启动之前,初始化所有的变量和数据结构。
全栈程序员站长
2022/09/03
4880
UCOSII系统移植详解「建议收藏」
1,处理器的C编译器能产生可重入型的代码,如果不行的话,那么就不能在任务之间随意的切换,因为当你切换到别的任务的时候,该任务在这个函数的数据就会被破坏。
全栈程序员站长
2022/08/19
2.3K0
从零开始学习UCOSII操作系统13–系统移植理论篇「建议收藏」
(1)UCOSII移植到不同的处理器上,所谓的移植就是将一个实时的内核能在其他的微处理器或者微控制器上运行。
全栈程序员站长
2022/08/19
6990
从零开始学习UCOSII操作系统2–UCOSII的内核实现「建议收藏」
参考书籍:《嵌入式实时操作系统μCOS-II原理及应用》、《嵌入式实时操作系统uCOS-II 邵贝贝(第二版)》
用户10377643
2023/02/22
8500
从零开始学习UCOSII操作系统2–UCOSII的内核实现「建议收藏」
参考书籍:《嵌入式实时操作系统μCOS-II原理及应用》、《嵌入式实时操作系统uCOS-II 邵贝贝(第二版)》
全栈程序员站长
2022/09/05
1.1K0
从零开始学习UCOSII操作系统4–任务管理
(1)任务可以是一个无限的循环,也可以在一次执行完毕后被删除。 这里需要注意的是,任务的代码并不是真正的删除了,而是UCOSII不再理会该任务代码,所以该任务代码不会再执行。
全栈程序员站长
2022/09/01
4350
嵌入式实时操作系统UCOSII[通俗易懂]
1.什么是操作系统? 操作系统是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行。介于APP和硬件之间。
全栈程序员站长
2022/08/19
4.1K0
嵌入式实时操作系统UCOSII[通俗易懂]
STM32 + UCOSII 操作系统(简单讲解)「建议收藏」
这是我将UCOSII操作系统移植在STM32单片机上后进行UCOSII操作系统学习的一些笔记与理解,此文最后会附上我自己在UCOSII操作系统下使用STM32写的ESP8266+onenet+http协议的程序链接,可以作为参考,如果文中有不当的地方,还请各位大佬加以中指正,我一定会虚心求教。参考资料:正点原子RTOS操作系统讲解,参考的文章:(53条消息) STM32学习笔记一一UCOSII(1)_霁风AI-CSDN博客_ucosii
全栈程序员站长
2022/09/05
1.2K0
实时操作系统UCOS学习笔记1—-UCOSII简介
前面我们所有的实验都是跑的裸机程序(裸奔),从本章开始,我们开始介绍UCOSII(实时多任务操作系统内核)。
全栈程序员站长
2022/09/07
3.3K0
实时操作系统UCOS学习笔记1—-UCOSII简介
从零开始学习UCOSII操作系统12–内存管理
前言: 在标准的C语言中,可以用malloc()和free()2个动态的分配内存和 释放内存,但是在嵌入式中,调用malloc()和free()却是非常危险的。 因为多次调用这两个函数,会把原来的很大的一块连续的内存区域逐渐的分割成许多非常小的而且彼此又不相邻的内存块,也就是所谓的内存碎片。这样子的话,使得程序后面连一段非常小的内存都分配不到,另外由于内存管理算法上的原因,malloc()和free()函数执行的时间是不确定的。
全栈程序员站长
2022/08/19
1K0
动手写简单的嵌入式操作系统一
业余时间想研究一下RTOS,但是现有的嵌入式系统很多,代码量也很大,厚厚的一本书,又是任务控制块,又是链表又是指针的指来指去,让人不耐心点根本看不下去,也没太多时间去研究。于是就有了自己动手去做的想法,这样可以提高兴趣.比看书有意思。慢慢的发现,操作系统也没有那么神秘。触发软中断,保存堆栈,开始进行任务切换。于是一个多任务就出来了,但是一个完整的操作系统并不简单,涉及到一系列的算法和数据结构的运用,还有系统的引导程序bootloader,内存管理,文件系统,网络管理,IO驱动管理等模块。
杨永贞
2020/08/04
7280
【二代示波器教程】第14章 uCOS-III操作系统版本二代示波器实现
本章教程为大家讲解uCOS-III操作系统版本的二代示波器实现。主要讲解RTOS设计框架,即各个任务实现的功能,任务间的通信方案选择,任务栈,系统栈以及全局变量共享问题。同时,工程调试方法也专门做了说明。
Simon223
2018/09/04
1.5K0
【二代示波器教程】第14章 uCOS-III操作系统版本二代示波器实现
UCOSII系统时间管理[通俗易懂]
绝大多数的内核要求提供定时中断,以实现延时与超时控制等功能。这个定时中断叫做时钟节拍。时钟的中断子程序ISR和时钟节拍函数OSTimeTick()该函数通知UCOSII,发生了时钟节拍中断。
全栈程序员站长
2022/08/22
1.1K0
建立任务,OSTaskCreate()源码解析
想让uC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt()。OSTaskCreate()与uC/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。
全栈程序员站长
2022/09/07
7570
ucos创建任务流程图_createthread函数的参数
大家好,又见面了,我是你们的朋友全栈君。 uC/OS-III任务创建函数OSTaskCreate() 欢迎进入linuxweiyh的博客 1.OSTaskCreate()函数原型 void TaskCreate(OS_TCB *p_tcb, // 任务控制OS_TCB的地址 CPU_CHAR *p_name, // 任务的名字 OS_TASK_PTR p_task, // 任务代码的起始地址 void *p_arg,
全栈程序员站长
2022/10/04
6290
从零开始学习UCOSII操作系统15–总结篇[通俗易懂]
前言:在大学的时候,我们班级上面都有很多人觉得学习UCOSII(包括UCOSIII)是没什么厉害的,因为很多人都喜欢去学习Linux操作系统,但是,但是,真实的对整个UCOSII操作系统进行学习,我可以保证,如果你是基于源码级别的阅读的话,绝对是不简单的。仅仅是调用几个API的话,是永远用不好UCOSII的操作系统的。还有你真正学通了UCOSII操作系统的话,那么你对Linux操作系统的内核也不会有太大的难度。
全栈程序员站长
2022/08/18
1.4K0
从零开始学习UCOSII操作系统15–总结篇[通俗易懂]
ucosii操作系统内核源码学习第一篇
1. 操作系统默认定义了64个TCB块(为全局变量,编译时候以及分配了,创建一个任务就使用一个,删除一个任务就归还一个)(为什么最大只支持64个任务呢,我们可能想到去更改OS_MAX_TASKS宏的值,但是任务就绪表OSRdyTbl[8]既然已经这样定义了,说明此系统初衷只能最大管理64个任务,而且为了加快查找最高优先级任务定义的OSUnMapTbl[ ]数组(这个数组比较难理解)也是专门为64个任务二设定的,所以要想修改系统支持的最大任务数,就得修改多处,自己慢慢琢磨吧!),每个TCB里面包括了所有的属性,所以会占用大量的单片机ram空间,包括OS_STK *ptos这个指针变量,只是这个任务自己的堆栈指针没有指向任何分配的空间(这个空间由我们创建任务时候才自己定义一个大数组,这个更浪费ram空间)。
全栈程序员站长
2022/08/23
6320
UCOSII操作系统学习之任务间的通信(1)
为了把描述事件的数据结构统一起来,UCOSII 使用叫做事件控制块(ECB)的数据结构来描述诸如信号量、邮箱(消息邮箱)和消息队列这些事件。信号量,邮箱,消息队列都是一类事件。
全栈程序员站长
2022/08/26
1.1K0
UCOSII操作系统学习之任务间的通信(1)
【RL-TCPnet网络教程】第9章 RL-TCPnet网络协议栈移植(uCOS-III)
本章教程为大家讲解RL-TCPnet网络协议栈的uCOS-III操作系统移植方式,学习了第6章讲解的底层驱动接口函数之后,移植就比较容易了,主要是添加库文件、配置文件和驱动文件即可。另外,RL-TCPnet移植到uCOS-III要重新配置RL-TCPnet的接口函数,以此来支持RL-TCPent多任务运行。使用RTX无需重新配置,因为默认情况下就是采用RTX的API函数配置的。
Simon223
2018/09/04
1.3K0
【RL-TCPnet网络教程】第9章    RL-TCPnet网络协议栈移植(uCOS-III)
如何设计嵌入式系统?带你理解一个小型嵌入式操作系统的精髓
1 多任务机制 其实在单一CPU 的情况下,是不存在真正的多任务机制的,存在的只有不同的任务轮流使用CPU,所以本质上还是单任务的。但由于CPU执行速度非常快,加上任务切换十分频繁并且切换的很快,所以我们感觉好像有很多任务同时在运行一样。这就是所谓的多任务机制。 实时系统的特征是延时可预测,能够在一个规定的时间内(通常是 ms 级别的)对某些信号做出反应。 2 任务的状态 任务有下面的特性:任务并不是随时都可以运行的,而一个已经运行的任务并不能保证一直占有 CPU 直到运行完。一般有就绪态,运行态,挂起态等
刘盼
2018/03/16
1.3K0
如何设计嵌入式系统?带你理解一个小型嵌入式操作系统的精髓
推荐阅读
相关推荐
UCOSII操作系统 第3课—UCOSII启动过程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档