加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

裸机驱动模板

发布时间:2020-12-15 20:08:00 所属栏目:百科 来源:网络整理
导读:编写裸机驱动,一般都比较随意。这通常导致代码不统一,移植性差。 本例以SPI FLASH来分析一种优秀的裸机驱动编写模板。 ? 首先定义一个设备类。 ? /* ?*flash device class ?*/ typedef struct flash_dev_s{ ?const struct flash_dev_funs *funs;?????????

编写裸机驱动,一般都比较随意。这通常导致代码不统一,移植性差。

本例以SPI FLASH来分析一种优秀的裸机驱动编写模板。

?

首先定义一个设备类。

?

/*

?*flash device class

?*/

typedef struct flash_dev_s{

?const struct flash_dev_funs *funs;????????? /* Function pointers */

?uint32?????????????????????flags;????????? /* Devicecharacteristics */

?hsaddr_t???????????????????start;????????? /* First address*/

?hsaddr_t???????????????????end;??????????? /* Last address */

?uint32?????????????????????num_block_infos;/* Number of entries */

?const flash_block_info_t???*block_info;??? /* Info about oneblock size */

?

?const void?????????????????*priv;????????? /* Devices privatedata */

} flash_dev_t;

?

/* Structure of pointers to functions inthe device driver */

Struct ?flash_dev_funs {

?sys_error_t (*flash_init) (struct flash_dev_s *dev) REENTRANT;

?sys_error_t (*flash_erase_block) (struct flash_dev_s *dev,

??????????????????????????????????? hsaddr_tblock_base) REENTRANT;

?sys_error_t (*flash_program) (struct flash_dev_s *dev,

??????????????????????????????? hsaddr_t base,

??????????????????????????????? const void*ram_base,size_t len) REENTRANT;

?sys_error_t (*flash_read) (struct flash_dev_s *dev,

???????????????????????????? const hsaddr_tbase,

???????????????????????????? void* ram_base,size_t len) REENTRANT;

};

同一种设备类型可能有不同厂家和不同参数的差异,但它的大体功能属性是一致的。我们首先把一致的属性剥离出来,构建一个设备类。类似C++的类,包含数据和操作方法。一个设备驱动模板的雏形就出来了。

?

我们来看一个设备实例来看它的方便之处。

struct flash_dev_funs mx25l_funs = {

???mspi_init,

???m25lxx_erase_block,

???m25lxx_program,

???m25lxx_read,

???NULL

};

?

flash_dev_t n25q256_dev = {

???&mx25l_funs,

???FLAG_FSR_POLL,

???CFG_FLASH_START_ADDRESS,

???0,

???1,

???&n25q256_info,

???NULL };

flash_dev_t w25q16_dev = {

???&mx25l_funs,

?? 0,

??CFG_FLASH_START_ADDRESS,

?? 1,

??&w25q16cv_info,

??NULL };

/*end*/

?

flash_dev_t w25q64cv_dev = {

???&mx25l_funs,

???&w25q64cv_info,

NULL };

?

这里用一个通用设备结构体定义和初始化了多个不同的spi设备实例。我们看到每个设备的不同之处在它们的功能函数和设备属性。当我们需要新增一个设备时,只需定义一个通用设备类,再去添加它自己的操作方法和数据属性就行了。实现这些之后,对外部调用来说就简单了,直接操作这个设备类的统一接口,上层代码不需要做任何改动,提高了驱动移植性。


我们还可以做进一步的函数封装。

例如:把设备操作完全屏蔽,上层代码不需要管是什么设备。

sys_error_t
flash_read(hsaddr_t flash_base,void *ram_base,size_t len)
{

? ? dev = board_get_flash_dev();
? ? if (!dev) {
? ? ? ? return SYS_ERR;
? ? }

? ? rv = (*dev->funs->flash_read)(dev,addr,ram,this_read);

? ? ......

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读