基于消息机制的Gogoto OS嵌入式实时操作系统说明书
(G-OS)
作者:卢益贵 QQ:48092788
博客:luyigui.blog.gxsky.com
网络搜索:绿城代码、Gogoto OS、狗狗兔
一、 许可协议
1. 版权所有,未经授权不得用于任何商业行为;
2. 任何获得授权使用的单位和个人,都必须保持原有的文件内容、文件名和目录结构;
3. 作者保留对本系统的版本发布权,任何对本系统的修改、完善、升级等版本都必须提供给作者,由作者统一发布;
4. 由于软件具有不可预见性的错误,作者不对此负责;
5. 任何移植的个人或单位,都必须向作者提供移植版本的所有代码,否则作者保留追究其侵权的权力;
6. 由于代码的算法可能具有雷同性,如有侵权的部分,请立即向作者说明,立即更改;
7.与本系统的代码交流,均以作者提供的博客为平台。
二、 文件结构
1. GGT_CPU_a.s:CPU相关的汇编核心代码部分
2. GGT_CPU_c.c:CPU相关的C核心代码部分
3. GGT_CPU.h:CPU相关的头文件部分
4. GGT_Kernel.c:CPU无关的核心代码部分
5. GGT_Type.h:变量类型定义
6. GGT_SysType.h:仅提供给系统的类型定义
7. GGT_SysCfg.h:功能模块使能头文件
8. GGT_OS.h:提供给用户引用的头文件
9. GGT_Kernel.h:仅提供给系统引用的所以功能头文件
10. GGT_Mut.c:任务排斥功能单元:
11. GGT_Msg.c:消息功能单元
12. GGT_Timer.c:用户定时器功能单元
13. GGT_Mem.c:简单内存功能单元
14. GGT_Func.c:功能 函数单元
15. GGT_Config.c:用户配置单元
16. GGT_Config.h:用户配置单元头文件
三、 设计说明
本系统设计基于消息传送机制,采用完全的32位变量数据,具有时间片任务分配切换功能,本系统的设计考虑到了移植和项目开发的各异性,在结构上为两者留有了空间,用户可以根据不同需求更改设置。系统的创新点在于,一切任务间的数据交换都采用消息机制。尽管也有很多系统具有消息功能,但是各有优势。
本系统的链表结构采用了统一的头成员为下一个节点指针的形式,统一了链表功能函数,在内存分配的处理上,采用别人的MemBox机制。在系统节拍的实现代码部分,已经进行了代码优化,最大限度的保障了没有必要的判断,提高了使用频率高的代码的效率。
四、 移植说明
本系统的移植,仅对三个文件进行更改即可:
1. GGT_CPU_a.s:CPU相关的汇编核心代码部分
2. GGT_CPU_c.c:CPU相关的C核心代码部分
3. GGT_CPU.h:CPU相关的头文件部分
GGT_CPU_a.s是软件中断代码部分,主要是软件中断切换任务和开关IRQ中断功能,因为在代码执行时,需要对CPU进行独占,所以必须提供开关IRQ中断的功能,以防止IRQ中断对程序执行代码切分后,造成公共数据的数据不一致的情况。
GGT_CPU_c.c是和CPU或编译器相关的代码部分,实现了系统时钟节拍的功能,在时钟中断里面,必须保存当前任务环境,进行任务调度和定时器计数,和进行新任务环境的加载。由于不同的编译器,堆栈的结构也不一样,因此对堆栈的初始化也在这里进行。本系统设计将C语言的Main函数纳入了系统的默认任务,因此,在这个部分,也对系统的默认堆栈指针进行了巧妙的替换,达到了将Main函数设置为任务体的目的。
在进行任务切换前,都必须保证pOSTskReady不为空,如果没有任务,必须让默认的Main任务出列,进入就绪状态,以保证必须有任务维持系统的运转。在main任务里面,死循环的对CPU进行了休眠处理。
五、 使用说明
1)本系统在Keil编译器上编译通过,并在LPC2106芯片运转良好,注意:编译设置里面必须把Keil的Use Thumb Mode选项去掉。
2)由于本系统使用了main函数,用户不能再有main函数体,系统提供了umain函数来给用户初始化用户系统:
void umian(void)
{
OSTaskCreate(…);
……
}
任务函数的格式:
Void TaskBody(UINT32 Param)
{
_Msg Msg;
Param = 0;
While(1)
{
If(OSMsgWait(&Msg)) 如果不想让任务吊死的话,可以使用OSMsgPeek
{
Switch(Msg.Msg)
{
……
}
}
}
}
3)用户函数(原形可看源文件):
1. extern UINT32 OSTaskUserCreate(void(*pTaskBody)(UINT32 Param), UINT32 Param, const UINT32 Prio, UINT32 Mode);
2. extern UINT32 OSTaskCreate(void(*pTaskBody)(UINT32 Param), UINT32 Param, const UINT32 Prio);
3. extern void Suspend(UINT32 TaskID);
4. extern BOOL Resume(UINT32 TaskID);
5. extern UINT32 OSTaskSelf(void);
6. extern void OSTaskKill(UINT32 TaskID);
7. void OSTaskDelay(UINT32 Time);
8. #define OSTaskKillSelf OSTaskKill(OSTaskSelf())
9.
10. extern void ListFirst(void *pFirst, void *pNode);
11. extern void ListAppend(void *pFirst, void *pNode);
12. extern void ListDelete(void *pFirst, void *pNode);
13. extern void ListInsert(void *pFirst, void *pNode,
14. BOOL (*pIsHere)(void *pNode, void *pNodeIns));
15.
16. extern void BoxInit(void *pBoxMem, INT32 BoxSize, INT32 BlockSize);
17. extern void *BoxAlloc(void *pBoxMem);
18. extern void BoxFree(void *pBomMem, void *Box);
19.
20. extern void OSMutWait(_pOSMut pMut);
21. extern void OSMutRelease(_pOSMut pMut);
22. extern void OSMutInit(_pOSMut pMut);
23.
24. extern BOOL OSMsgWaitFor(const UINT32 Msg, _pMsg pMsg);
25. extern BOOL OSMsgWait(_pMsg pMsg);
26. extern BOOL OSMsgPeek(_pMsg pMsg);
27. extern BOOL OSMsgPost(const UINT32 TaskID, const UINT32 Msg, const UINT32 wParam, const UINT32 lParam);
28.
29. void OSTimerKill(const UINT32 TimerID);
30. BOOL OSTimerSet(const UINT32 TaskID, const UINT32 Time);
4)由于本系统设计于单片机,为了节省处理时间和减少代码量,很多函数没有对参数的有效值进行过滤,在使用时,必须按照声明的要求使用。