babyOS开源框架

开源链接:

https://gitee.com/notrynohigh/BabyOS.git

 

BabyOS适用于MCU项目,她是一套管理功能模块和外设驱动的框架。

对项目而言,缩短开发周期。项目开发时选择适用的功能模块及驱动。直接进入功能代码编写的阶段。

对工程师而言,减少重复工作。调试过的功能模块和驱动代码放入BabyOS中管理,以后项目可以直接使用,去掉重复调试的工作。

代码结构

BabyOS代码分为3部分:

BabyOS仓库:功能模块和驱动 ,一般情况下用户不需要改动,可以将此仓库作为子模块。

BabyOS_Config:配置文件和设备注册文件

BabyOS_Hal:硬件抽象层, 不同分支对应不同硬件平台,选择对应平台下载,没有合适的则选择master分支

frame

适用项目

使用裸机开发的项目推荐基于BabyOS进行。

使用操作系统开发的项目,BabyOS可作为功能库及驱动库使用。

前世今生

说一说编写BabyOS原由

................

使用MCU开发的项目大多有两个要求:产品功耗开发周期

功耗的考量

设备的操作:唤醒设备,操作,设置休眠。

文件的操作:打开文件,编辑,关闭文件。

因此BabyOS中对设备的操作由统一的接口,即将设备看做文件一样对待。

缩短开发周期

项目中有较多使用率高的功能模块和外设,BabyOS提供友好的框架对功能模块和设备驱动进行收集和管理。

新项目启动时,以搭积木的方式即可完成一部分工作,以此来缩短开发时间。

 

BabyOS核心设计思想 

初始化函数主要干如下几件事:

1. 将驱动实例和硬件接口绑定

2. 执行必要的初始化程序

3. 填充驱动实例的元素

4. 更新状态:正常或者异常

关于初始化还有一个重要的部分,这里的初始化函数怎么让系统知道它的存在呢?在驱动的 C 文件最后都要加上一句: bDRIVER_REG_INIT(XXXX_Init); 为什么加上这一句就可以呢,来看具体实现,

在 b_driver.h 添加如下代码:

#define bDRIVER_USED __attribute__((used))

#define bDRIVER_SECTION(x) __attribute__((section(".rodata.bdriver_init" x)))

#define bDRIVER_INIT_START(func) \ bDRIVER_USED const pbDriverInit_t _bDriverInitStart bDRIVER_SECTION("0.end") = NULL

#define bDRIVER_INIT(func) \ bDRIVER_USED const pbDriverInit_t bdrv_init##func bDRIVER_SECTION("1") = func

#define bDRIVER_INIT_END(func) \ bDRIVER_USED const pbDriverInit_t _bDriverInitEnd bDRIVER_SECTION("1.end") = NULL

extern const pbDriverInit_t _bDriverInitStart;

extern const pbDriverInit_t _bDriverInitEnd;

#define bDRV_INIT_BASE (&_bDriverInitStart + 1)

#define bDRIVER_REG_INIT(func) bDRIVER_INIT(func) 通 过 bDRIVER_REG_INIT 便 可 以 将 初 始 化 函 数 放 入 _bDriverInitStart 和 _bDriverInitEnd 之间,然后修改 int bDeviceInit()函数内容:

int bDeviceInit() {

pbDriverInit_t *pdriver_init = (pbDriverInit_t *)bDRV_INIT_BASE;

memset(&bNullDriver, 0, sizeof(bNullDriver)); for(;pdriver_init < &_bDriverInitEnd;pdriver_init++)

{ (*pdriver_init)(); }

return 0; }

这样就能将注册进来的初始化函数全部执行一次

 

2. 驱动接口

上文描述了驱动部分的整体结构,那么具体的驱动代码如何编写。这部分对驱动接口 内的各个元素所负责的功能进行描述。

typedef struct bDriverIf {

int status;

int (*open)(struct bDriverIf *pdrv);

int (*close)(struct bDriverIf *pdrv);

int (*ctl)(struct bDriverIf *pdrv, uint8_t cmd, void *param);

int (*write)(struct bDriverIf *pdrv, uint32_t offset, uint8_t *pbuf, uint16_t len);

int (*read)(struct bDriverIf *pdrv, uint32_t offset, uint8_t *pbuf, uint16_t len);

void *_hal_if; union { uint32_t v; void *_p; }_private; }bDriverInterface_t;

2.1. Status 在驱动初始化时,若初始化碰到异常则将 status 设为-1 反之设为 0。 在操作设备是会检测此项,如果是-1 则不执行。

2.2. Open Open 主要是负责唤醒的操作,在此处执行设备唤醒。如果设备没有休眠状态,open 赋值为 NULL 即可。

2.3. Close Close 主要负责休眠的操作,在此处执行设备休眠。如果设备没有休眠状态,close 赋值为 NULL 即可。

2.4. Ctl Ctl 主要负责对设备进行配置或者执行特定的操作,例如擦除,切换状态等等。Ctl 的调用需要传入指令 cmd 和对应的参数*param。 因为不同类别的驱动有不同的指令,例如 flash 类驱动需要擦除,而 3 轴传感不需要, 所以驱动是分类存放,bos/driver/inc 目录 b_drv_class_xxx.h 文件是 xxx 类别的公用 头文件,这里面有此类驱动支持的 cmd 以及对应参数的数据类型。 执行指令成功则返回 0,失败或者是不支持的指令返回-1。

2.5. Write Write 主要负责传输数据至设备,例如存储设备,则传入要存储的数据,通讯模组则 传入要发送的数据。 执行成功则返回实际发送的数据长度,执行失败则返回-1。

2.6. Read Read 主要负责从设备获取数据,那么获取数据的最小单元是什么呢,这个依据设备的 功能而定,例如,存储设备,最小可以获取 1 个字节;3 轴加速度设备,则最小单元为 3 个 加速度值;温湿度传感器则最小单元是一组温度湿度值; 关于读取的最小单元是什么,需要在驱动的 h 文件进行说明让使用者能明白。

2.7. _hal_if 指向当前驱动对应的硬件接口的指针,驱动操作硬件时需要使用已绑定的硬件接口。 在 b_driver.h 里提供一个方便获取 pdrv 里硬件接口的宏: #define bDRV_GET_HALIF(name, type, pdrv) type *name = (type *)(pdrv->_hal_if)

2.8. _private 当驱动需要携带私有参数时,则利用这个字段。例如 flash 的 id,可以放在 _private.v。如果需要存放更多的信息,那么就利用_private.p 指向一片数据区域。 以上是关于 BabyOS 驱动部分的描述,如果觉得哪里不合理或者有新的想法,请加入开源开发者群一起学习

 

3、在BabyOS框架中集成驱动方法

1.创建C H文件命名规则 b_drv_xxx.c b_drv_xxx.h

2.c文件在bos/drivers/分类放 h文件放在bos/drivers/inc/目录

3.增加必要的文件注释,至少包含文件名、版本号、修改日期、开源协议和作者名

4.驱动统一接口类型,例如:

typedef bDriverInterface_t bW25X_Driver_t;

5.c文件定义驱动接口变量,指定初始化函数

bW25X_Driver_t bW25X_Driver = { .init = bW25X_Init, };

6.实现接口需要的函数,没有实现的赋值NULL

bW25X_Driver.open = _bW25X_Open;

bW25X_Driver.close = _bW25X_Close;

bW25X_Driver.ctl = _bW25X_Ctl;

bW25X_Driver.read = _bW25X_ReadBuf;

bW25X_Driver.write = _bW25X_WriteBuf;

//如果打开关闭不实现则按照下面方式赋值

bW25X_Driver.open = NULL;

bW25X_Driver.close = NULL;

bW25X_Driver.ctl = _bW25X_Ctl;

bW25X_Driver.read = _bW25X_ReadBuf;

bW25X_Driver.write = _bW25X_WriteBuf;

7.打开、关闭主要是休眠唤醒

8.IO及数字接口的定义在b_hal.h进行定义

9.硬件相关操作使用硬件抽象层提供的API

10.驱动完成后在b_driver.h里进行声明:

extern bDriverInterface_t bW25X_Driver;

11.完成,利用驱动注册一个设备后进行测试

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值