zephyr驱动开发流程

驱动开发涉及查看原理图和数据手册以理解设备操作,然后进行驱动初始化,注册到内核,并可能处理中断。内核注册使用Z_DEVICE_DEFINE宏,包括设备实例、初始化函数、API接口等。中断服务函数包括屏蔽、处理和清除中断。最后,驱动需编译进内核或作为模块加载,并进行测试。
摘要由CSDN通过智能技术生成

驱动开发流程包括:

1、需要查看原理图,数据手册,了解设备的操作方法,属于业务方面内容,在此不做赘述;

2、实现驱动程序的初始化,比如内核注册这个驱动程序,如果该设备有中断响应需要处理,则还要进行中断的定义和初始化工作,内核注册需要用到

Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, pm_device,\
                        data_ptr, cfg_ptr, level, prio, api_ptr, state_ptr, ...)

完成定义设备实例并声明其初始化函数的工作,其中init_fn为驱动及中断响应的定义及初始化工作,api_ptr为注册的设备驱动API接口,data_ptr为设备实例私有数据(在data_ptr设置的信息可以通过device handle->data直接使用),cfg_ptr为设备实例配置信息(在cfg_ptr设置的cfg信息可以通过device handle->config直接使用),举例如下:

typedef struct {
    uint32_t cfg_reg_base_addr;
    uint32_t cmd_queue_base_addr;
} test_device_cfg_t;

static test_device_cfg_t s_test_device_cfg = {
    .cfg_reg_base_addr = 0x40000000,
    .cmd_queue_base_addr = 0x40001000,
};

typedef struct {
    hal_test_device_callback_t callback;
    void *userdata;
} test_device_data_t;

static test_device_data_t s_test_device_data = {
    .callback = NULL,
    .userdata = NULL,
};

static xerror_t test_device_enable_irqs(hal_test_device_handle_t handle, 
                                        uint32_t irqs)
{
    test_device_cfg_t *test_device_cfg = 
                        (test_device_cfg_t *) ((hal_device_handle_t) handle)->config;
    .........................................................................
    在函数内就可以使用test_device_cfg处理和struct test_device_cfg_t字段相关的内容
    .........................................................................
    return SUCCESS;
}

/*test_device_register_callback调用点在业务代码侧,实现并注册callback,
在业务代码侧以初始化方式注册到操作系统中,在实际业务调度时生效*/
static xerror_t test_device_register_callback(hal_test_device_handle_t handle, 
                                        void *callback, void *userdata)
{
    test_device_data_t *test_device_data = 
                            (test_device_data_t *) ((hal_device_handle_t) handle)->data;

    test_device_data->callback = callback;
    test_device_data->userdata = userdata;

    return XRTE_SUCCESS;
}

hal_test_device_api_t s_test_device_api = {
    ...
    .register_callback = test_device_register_callback,
    ...
}

Z_DEVICE_DEFINE(..., ..., &s_test_device_data, &s_test_device_cfg, 
                ..., ..., ..., ..., &s_test_device_api )

内核注册主要是一些设备设备相关内容,所以需要每次操作都可以获取设备句柄(如上述例子中的hal_test_device_handle_t handle),获取方式为通过static inline const struct device * device_get_binding(const char * name)即可,其中name即为设备树中lable属性的值信息。

3、设计所要实现的操作:比如open、close、read、writ、设备寄存器操作等函数;

4、实现中断服务,并不是每个设备驱动都必须的,处理中断函数模型如下

TEST_DEV_FUNC_IRQ_MASK = GENMASK(11, 0),

/*处理中断前首先需要屏蔽该设备的中断功能*/
test_dev_mask_func_inter(test_dev_cfg->cfg_reg_base_addr, TEST_DEV_FUNC_IRQ_MASK);

............
处理中断
............

/*中断处理结束后需要将该中断清掉*/
test_dev_clr_func_irq(test_dev_cfg->cfg_reg_base_addr, func_irq_status & TEST_DEV_FUNC_IRQ_MASK);
/*处理中断前首先需要打开该设备的中断功能*/
test_dev_unmask_func_inter(test_dev_cfg->cfg_reg_base_addr, TEST_DEV_FUNC_IRQ_MASK);

5、编译驱动到内核,或作为模块动态加载;

通过CMakeLists.txt实现编译进内核

6、测试驱动;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值