msOS 中分层与注册思想的个人理解 这一周断断续续的看了下msOS,发现其代码分层比较好(PS:其实之前还没体会分层,只是觉得那些代码放在一起看起来比较舒服)。 然后再看看自己的工程,看的都是泪。。。 于是决定按照msOS的架构来从新整理。 整理之前于是开始分析msOS的架构: 从上到下,依次看 首先,App这一层给人最清晰,一看就知道是应用层 如图 app.c应用层主函数入口 然后调用一些初始化接口 mmi.c 界面相关的函数(本质上是注册) data.c 主要是app用到的数据在此初始化 event.c 消息响应的相关事件函数 然后再看System 层 这一层给我的感觉比较模糊,我第一次整理架构的时候 是按照 app --- device --- drive ---- system 这样一路下来 因为我的工程不要OS (接下来有关OS的不做分析,没看代码) 所以在我心目中,一直以为system是最低层(错误理解)! 正确的层次应该是 app ---- system --- device --- drive 继续看,system里面的文件 system.h和system.c是把Device、GUI、OS,封装了一下 App中直接调用system中的接口; 由于我没有用OS 在这一层定义了消息队列相关的接口和一些数据类型重定义等(不知分层是否正确) 当然我有用到文件系统,也放在这一层 如gui也可放在这一层。 接下来到device层 这一层是直接面向设备的驱动层,如按键(key),显示(lcd)等等 device.c和device.h是直接对device_xxx设备驱动封装一次,抽象出相应的接口,给system调用。 剩下其他device_xxx C文件都是各种设备的驱动接口。具体内容要自己看代码,不在此一一讲述。 再下来是drive层 由于msOS目前还是比较精简的一个版本,所以驱动成只放了一个驱动库头文件(位带,可方便定义使用GPIO) 这个里面主要是放一些如基础总线驱动:SPI IIC IIS等。 剩下的这些都是stm32官方提供的库,按照他的分类即可! 这是ARM推荐的标准模型,按照这个即可(看起来没感觉,真正做好分层很难)! 个人看法: 怎么认为分层“成功”了呢?? 个人感觉最起码要满足这一点。 打开MDK 在APP成下,随便点开一个c文件,看c文件里面包含的h文件 如; 这样,不管分层好坏,这样起码分层达到所谓的“成功”了! App层绝对不能包含如stm32f10x.h这种头文件! 分层给我目前的感觉就像现实中的公司架构定位, 工程师------项目经理-------开发总监 ----- BOSS (工作不久,小公司俺感觉是这样的) 命令都是一层一层的传递,如果工程师没事就去找下老板,小公司也许没事,随着公司的发展达到一定的规模,那这个公司的老板肯定会(剩略100字)。。。。(ps: 纯属开玩笑) 分层很能看出一个人的软件功力,随着软件功能越来越多,规模越来越大,这种分层思想会变得越来越重要,特别是对于嵌入式,单片机这种类型,用面向过程的C写出一种面向对象的程序(OOC),对从业者是一种挑战,也是一种机遇。 而从事这个行业的大多数都不是真正的计算机软件毕业的,好多都是半路出家(PS:我是学机电专业,周围也有很多这类人),所以如果有msOS这个平台能够很好的吸收分层等大型软件的特性,将是我们这些基础差的人,进一步提升自己程序的平台。 分层就谈到这里,自己水平太菜,只是有感而发。 接下来说说分层的一种方法:注册 谈注册之前先来很清楚两个概念:注册和调用 上层直接使用下层提供的接口,就叫调用上层把地址赋值给下层,让下层调用,这叫注册 理解这两个概念,继续往下看(ps:下面没美女)。。。。。。 好的分层方法可能有很多(小弟暂时不知道其他),注册肯定是其中一个。 (PS:群里聊天讨论的内容) 到底什么是注册?? 用代码说话吧 注册,其实就是上层把想要被底层调用或者修改的东西的指针传递给下层,让下层来调用或者修改!(来源于msOS作者解释) 我的理解就是:在把驱动接口做好后,然后直接把接口函数的地址,赋值给被上一层调用的结构体中的函数指针,这样就叫注册(不知是否完全正确,个人理解)。 再拿这个公司架构打比方:工程师------项目经理-------开发总监 ----- BOSS 调用,给的是值 -------对应公司-------------调用,老板直接指挥注册,给的是值的地址 -------对应公司-------------注册,老板给予权力,他自己指挥 这样做的好处是什么呢? 当然是分层。 分层又有什么作用呢? 高内聚,低耦合,程序独立性好等等 什么是高内聚,低耦合呢?? 这。。。。 度娘在呼唤你。。。 哈哈 分层这种方法虽然多了几步(刚开始我是思维没转过来,为啥要这么麻烦),但多了一些约束,大公司无规矩不成方圆,好软件无分层不成。。。。。(不知道说了,哈哈) 说了这么多废话,还是看看msOS中的注册代码吧(这一段我纠结了很久,唉 说出来都是泪。。。。。。) 首先这里,定义了几个函数指针,并把函数指针指向一个空函数(函数指针初始化,一定要初始化,不然像条没栓链子的“疯狗”,太危险了。。。。) ps:野指针 注意function 一开始没认真看,一直当作定义一个数组看。。。。。 (函数太长,截图表示一下,未完整) 这里定义了一个回调函数的具体内容,注意参数!!! 这里是回调函数注册!!!(所谓注册就是把函数地址给另一个函数指针)。 注册之后就可以用于其他的调用了。比如在app.c中, 这里就把SystemTickService()这个函数调用了,注意这个函数前面的static 这个表示接口的隐藏,具体不详细说。 如OS中也有也有这个一模一样的函数名! 这样就表示每10ms会对这个函数调用一次! 所以呢 这个空的SystemTickService()函数地址就赋值给了SystemTick100Block[0]; 这个start函数中再次注册了一次,所以 OS的时钟服务函数地址赋值给了 SystemTick1000Block[0] 然后这样就可以充分的利用时钟分频,软件定时器了! 这个函数中,这些是我刚开始一直迷惑的 原来这些,你不注册但到他时就执行一次空函数,注册了就可以用(这种扩展性,自己一直都想不到,学习了)! 后来我提出了添加一个注销注册的函数,群主和群友解析的很好,如下 大体上就说这么多吧,废话也比较多,msOS还要深入的好好看,衷心感谢群主(ms0S作者)和各位群友的帮助。如:tomsu 剑客 用代码总结,用代码思考!(好的思维一定要用代码验证。。。。。。) 如需转载,请注明出处! 网名:独钓千古愁 联系方式QQ:2257179162 2013-08-23
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。