开源EMOS-简单嵌入式操作系统
@[**### 开源软件EMOS简介
@[开源软件EMOS**]
http://sourceforge.net/projects/emos/
摘要:EMOS 是基于 uCOS-ii v2.0 改写的开源嵌入式操作系统,采用商业化代码风格,提供 MinGW 仿真平台环境,支持 32 位和 64 位 Windows 系统。系统包含任务调度、信号量、内存管理、消息队列等核心模块,并新增了类似 VxWorks 的 MsgQ 功能。本文详细介绍了 EMOS 的系统架构、核心函数、编译运行方法以及测试验证过程,适合嵌入式系统学习者参考使用。
开源软件EMOS
条款26 开源软件EMOS嵌入式操作系统
D.1 EMOS嵌入式操作系统简介
EMOS 嵌入式操作系统继承于uCOS-ii v2.0 的改写。基于uCOS-ii 的核心思想和核心代码,进行了如下改写:
(1) 所有核心代码基于商业代码常用风格进行重写。结合笔者多年嵌入式软件开发经验总结进行重写和归纳。
(2) 提供MinGW仿真平台环境,无需基于Borland C++或者实物CPU平台进行仿真。uCOS-ii提供了大量平台的移植件,这些移植件基于简单的修改即可提供给EMOS使用。MinGW仿真平台移植代码基于uCOS-ii 之Visual C++ 6.0 仿真平台代码修改获得。
(3) 新增加VxWorks类似MsgQ操作模块,从源代码可概览嵌入式系统MsgQ详细工作机理。
(4) 新增加适量的测试Case,测试Functions等。
(5) 较大量的源代码细节改动等,后续新功能不断更新和升级(如tcl debug等)。
(6) 请使用UltraEdit/Notepad++或者SourceInsight阅读代码,并且配置为如下字体才能获取正确清晰的代码风格。
EMOS源代码下载地址如下:
http://sourceforge.net/projects/emos/
点击Download EMOS 获取源代码包裹,当时最新版本为EMOS 1.0.0; 目前本文档附件部分会升级为最新的EMOS 1.0.1版本。
所有源文件简单解释如下:
README32.txt
README64.txt
Makefile
cmnd.bat
emos_inc.h
emos_core.h
emos_core.c
emos_cfg.h
emos_task.c
emos_sem.c
emos_mem.c
emos_mbox.c
emos_msgq.c
emos_cpu.c
emos_cpu.h
emos_test.c
start_cmd.bat
start_cmdd.bat 说明文件MinGW(32bit),用UltraEdit打开;
说明文件MinGW64(64bit),用UltraEdit打开;
Makefile文件;
建立MinGW编译工具路径bat文件,参考笔者《MinGW指南》;
常用标准数据类型定义头文件;
核心数据结构定义,核心函数声明文件;
核心功能实现;
EMOS模块功能选择性配置头文件;(学习取默认即可)
EMOS的任务实现文件;
EMOS的信号量实现文件;
EMOS的简单memory管理文件;
EMOS的MBox实现文件;
EMOS的MsgQ实现文件;
EMOS的CPU相关实现文件,当前提供MinGW的仿真环境;
EMOS的CPU相关头文件;
EMOS的主要测试代码,以及main()函数入口,启动EMOS的案例等;
笔者的cmd环境,给MinGW(32bit)使用,主要找到编译环境路径。
笔者的cmd环境,专为MinGW64(64bit)配置,主要用于定位编译环境路径。
EMOS嵌入式操作系统MinGW仿真
uCOS-ii提供不同CPU的Porting时,有四个最核心的函数,且代码基于不同CPU的汇编实现,如下为这四个函数:
PUBLIC _OSTickISR
PUBLIC _OSStartHighRdy
PUBLIC _OSCtxSw
PUBLIC _OSIntCtxSw
具体的细节可参考uCOS-ii的实现。
本章节内容主要讨论基于MinGW仿真时的实现,在源代码文件emos_cpu.c中,如下为核心porting函数:
void emosCtxSw(void); /implement in cpu.asm of context switch/ void emosIntCtxSw(void); /implement in cpu.asm of interrupt context switch/ void emosStartHighRdy(void); /implement in cpu.asm of task switch/ void emosTickISR(void); /implement in cpu.asm of tick interrupt/ void* emosTaskStkInit(void (*task)(void *pd), void *pdata, void *ptos, uint16 opt);
核心思想为: (1) EMOS的每个任务绑定于MinGW中每个windows的线程; (2) EMOS的任务上下文切换中断和EMOS的Tick中断在仿真中均基于windows中最高优先级线程仿真实现。部分代码可参考如下:
EMOS任务上下文切换中断基于windows最高优先级线程仿真启动代码:
EMOS中Tick中断基于windows最高优先级线程仿真启动代码:
说明:基于MinGW的仿真Porting可参考emos_cpu.c具体代码详细实现,这里不作详细叙述;
EMOS嵌入式操作系统组件基础 EMOS的主要基本模块简要介绍如下:
EMOS核心的任务调度切换等由emos_core.c文件实现,核心的模块函数为:
void emosTimeDly(uint16 ticks); void emosTimeSet(uint32 ticks); void emosTimeTick(void); uint8 emosTimeDlyHMSM(uint8 hours, uint8 minutes, uint8 seconds, uint16 milli); uint8 emosTimeDlyResume(uint8 prio); uint32 emosTimeGet(void);
void emosInit(void); void emosInitStart(void); void emosStart(void); void emosStatInit(void); void emosIntEnter(void); void emosIntExit(void); void emosSchedLock(void); void emosSchedUnlock(void); uint16 emosVersion(void); char* emosVersionString(void);
/*************************************************************************** I NTERNAL FUNCTION PROTOTYPES (Your application MUST NOT call these functions)
***************************************************************************/ uint8 emosTCBInit(uint8 prio, EMOS_STK *ptos, EMOS_STK *pbos, uint16 id, uint16 stk_size, void *pext, uint16 opt); void emosSched(void); void emosTaskIdle(void *data);
#if EMOS_MBOX_EN || EMOS_Q_EN || EMOS_SEM_EN void emosEventTaskRdy(EMOS_EVENT_T *pevent, void *msg, uint8 msk); void emosEventTaskWait(EMOS_EVENT_T *pevent); void emosEventTo(EMOS_EVENT_T *pevent); void emosEventWaitListInit(EMOS_EVENT_T *pevent);
#endif
EMOS的任务操作模块函数有: uint8 emosTaskCreate(void (*task)(void *pd), void *pdata, EMOS_STK *ptos, uint8 prio); uint8 emosTaskQuery(uint8 prio, EMOS_TCB_T *pdata);
#if EMOS_TASK_CHANGE_PRIO_EN uint8 emosTaskChangePrio(uint8 oldprio, uint8 newprio);
#endif
#if EMOS_TASK_CREATE_EXT_EN uint8 emosTaskCreateExt(void (*task)(void *pd),
void *pdata,
EMOS_STK *ptos,
uint8 prio,
uint16 id,
EMOS_STK *pbos,
uint32 stk_size,
void *pext,
uint16 opt);
#endif
#if EMOS_TASK_CREATE_EXT_EN uint8 emosTaskStkChk(uint8 prio, EMOS_STK_DATA_T *pdata); /*uint8 emosTaskStkChk (uint8 prio, EMOS_STK_DATA_T pdata);/
#endif
#if EMOS_TASK_DEL_EN uint8 emosTaskDel(uint8 prio); uint8 emosTaskDelReq(uint8 prio);
#endif
#if EMOS_TASK_SUSPEND_EN uint8 emosTaskResume(uint8 prio); uint8 emosTaskSuspend(uint8 prio);
#endif
EMOS的信号量操作模块函数有: EMOS_EVENT_T* emosSemCreate(uint16 value); uint16 emosSemAccept(EMOS_EVENT_T *pevent); void emosSemPend(EMOS_EVENT_T *pevent, uint16 timeout, uint8 *err); uint8 emosSemPost(EMOS_EVENT_T *pevent); uint8 emosSemQuery(EMOS_EVENT_T *pevent, EMOS_SEM_DATA_T *pdata);
EMOS的MBox操作模块函数有: EMOS_EVENT_T* emosMboxCreate(void msg); void emosMboxAccept(EMOS_EVENT_T pevent); void emosMboxPend(EMOS_EVENT_T *pevent, uint16 timeout, uint8 *err); uint8 emosMboxPost(EMOS_EVENT_T *pevent, void *msg); uint8 emosMboxQuery(EMOS_EVENT_T *pevent, EMOS_MBOX_DATA_T *pdata);
EMOS的MsgQ操作模块函数有: 原uCOS-ii实现的MsgQ的改写功能模块, EMOS_EVENT_T* emosQCreate(void *start, uint16 size); void emosQAccept(EMOS_EVENT_T pevent); void emosQPend(EMOS_EVENT_T *pevent, uint16 timeout, uint8 *err); uint8 emosQFlush(EMOS_EVENT_T *pevent); uint8 emosQPost(EMOS_EVENT_T
*pevent, void *msg); uint8 emosQPostFront(EMOS_EVENT_T *pevent, void *msg); uint8 emosQQuery(EMOS_EVENT_T *pevent, EMOS_Q_DATA_T *pdata);
笔者新增加的类VxWorks之MsgQ实现: struct EMOS_MSGQ_t; typedef struct EMOS_MSGQ_t* EMOS_MSGQ_ID; void emosMsgQInit(); EMOS_MSGQ_ID emosMsgQCreate(uint16 msgNum, uint16 msgLen); EMOS_MSGQ_ID emosMsgQDelete(EMOS_MSGQ_ID ID ); int emosMsgQRecv(EMOS_MSGQ_ID ID, char* buf, uint16 size, int timeout); int emosMsgQSend(EMOS_MSGQ_ID ID, char* buf, uint16 size);
D.1 EMOS嵌入式操作系统测试CASE 笔者编写了内核核心调试信息函数:(emos_core.c文件中)
void emosDbgShow();
输出的格式信息如下:(红色部分为笔者文档说明内容):
TCBCur TCBHRdy PriCur PriHRdy gTCBList RdyGrp
taskIdle taskStat timeTick 00000000 004080b0 000000 0000000 004080b0
000081 004019d0 004019ee 00000305 (EMOS核心的全局重要数据变量信息) RDY TBL
All:(8个gEmosRdyTbl的内容,可监控所有运行任务的优先级) Rdy[0]=01 Rdy[1]=00 Rdy[2]=00
Rdy[3]=00 Rdy[4]=00 Rdy[5]=00 Rdy[6]=00 Rdy[7]=60 TcbPrioTbl TBL All:
(64个TCB的内存地址信息) 004080b0 00408080 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00408050
00408020 Tcb_Addr Tcb_next Tcb_prev stk_Ptr Sta Dly Pri tX tY bX bY
004080b0 00408080 00000000 00409c2b 000 000 000 00 00 01 01 00408080
00408050 004080b0 00409a2b 010 65535 001 01 00 02 01 00408050 00408020
00408080 00408a48 000 000 061 05 07 20 80 00408020 00000000 00408050
00408248 000 000 062 06 07 40 80 (所有活动任务的TCB内存地址信息和链接关系,以及各任务的状态信息)
--------------- Debug Information end --------------其余的测试函数和EMOS启动案例函数在emos_test.c文件中, 笔者运行测试时的某输出结果案例如下:
D:\core\src>make gcc -Wall -Werror -I. -g -o emos.o emos_core.c
emos_task.c emos_mem.c emos_cpu.c emos_sem. c emos_msgq.c emos_mbox.c
emos_test.c -lwinmm -mconsole emos.o emos_msgq.c 526 Init
sucessfully,sizeof=40
==>Trace:emosTaskTst1=404df4
==>Trace:emosTaskTst2=404e19 EMOS Test Task B Running
D:\MinGW64\emos100> 敲入任意键结束
使用make clean去清楚编译 再敲入make可以重新编译
建议仔细阅读Makefile,笔者已经默认编译结果为emos.o(实际为.exe的编译结果),同时能够自动运行。
总结
EMOS基于uCOS-ii v2.0的商业化代码风格改写,并增加了相对适当的新功能,当前版本emos-1.0.1提供在MinGW(32bit)和MinGW64(64bit)环境下的仿真测试。
EMOS可作为学习嵌入式操作系统工作原理的入门参考利器,一个月的时间足可以掌握,可为后续深入学习实用和实践中的嵌入式软件开发工作打好坚实基础。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)