os文件夹
cola_device.c
.h放在.c的同层级。作者采用了字符设备注册的方式,在.h中可以看到设备属性。也就是把LED这些设备抽象,外面传入"LED1"这样的参数,使我联想到java的new一个对象。
值得注意的是58行,可以得出整体采用的是单链表的结论,而且是从下往上的,从IO到应用层。同时,链表的特性就可以套到这上边来。
由于本人不希望项目作者的成果因为我而被爬取或者是供某些AI公司使用,涉及到项目代码的部分我都会截图。
对设备进行的操作显然是供上层使用,因此放在.h里面供外部调用。
这些函数调用到的而外部不直接调用的函数,声明为静态函数。比如cola_device_register就调用到了device_list_inster,来进行链表的新增节点操作。
.h里面的枚举写法,我们查询菜鸟教程可以得知C enum(枚举) | 菜鸟教程 (runoob.com):
枚举不赋值的语法:手动为GUI Guider生成代码增加控件替换图片。声明一个该类型的变量,然后判断他是不是这个集合里面的内容。
作者给出的驱动使用用例:
find是基于对设备name的比较判断实现的,assert用于DEBUG,设备write的入口参数为设备、起始、字符串、长度。
作者使用了结构体函数指针的方式,支持了各种设备可以在这个文件的基础上”继承“方法。在stm32_usart.c的第139行,我们可以看到:声明为cola_device_ops之后,该结构体变量就能引出下面的那些读写用法
我们只要在该文件中实现uart1_write等函数即可。入口参数用的是cola_device.h第48行的config。不得不说真是十分巧妙。
作者例程使用config中似乎没有使用到var参数,可能在其他一些情况用到。我由此联想到可能存在一种情况,即上层需求和底层接口不符的情况,一个device不能囊括所有的设备应用需求。师兄项目工程的写法类似,但是他对设备进行了区别,比如led_device。不过适合的才是最好的,具体问题具体分析。
cola_os.c
main.c相当的简洁。硬件初始化->硬件驱动初始化->软件应用初始化->while(1),无论是哪一个初始化,中间都是有应用层再到设备IO。
while(1)主循环中放了一个loop,写法有点类似LVGL。loop依赖cola_os.c运行,循环遍历任务链表。我们需要做的就是一开始把它注册到链表里面,由while(1)去轮询定时器是否达到任务的执行时间。
任务的创建和定时器的创建可以参考作者文档。