Linux 内核驱动 - ADC 驱动

1. ADC内核驱动实现框架

ADC 内核驱动的实现是基于 ARM ADC BSP 驱动 与 Linux 内核驱动的框架进行衔接,主要分为以下几个部分构成:

在底层采用的 Linux 内核设备模型,基于 platform 平台总线

在 VFS 层使用的是 Linux 内核字符设备驱动框架,用于实现 VFS 层 相应的驱动访问接口

2. ADC 内核驱动 platfrom 总线实现

2.1 platfrom 总线的注册

基于 platfrom 总线部分,主要用于衔接 BSP 驱动 与上层的 字符设备驱动的访问接口.

platfrom 总线实现包含驱动描述与设备描述,其中设备描述在 Linux 内核设备树中描述. 需要在 exynos4412-fs4412.dts 中添加如下描述

adc@126c0000{

compatible        = "Samsung,exynos4412-adc"; reg  = <0x126c0000 0x20>;

adc-io-channer    = <3>;

clocks            = <&clock 326>;

clock-names       = "adc"; interrupt-parent = <&combiner>;

interrupts           = <10 3>;

= "okay";            status      

};platfrom 驱动描述结构定义如下:

在上述结构中, of_match_table 成员的描述如下:

#if defined(CONFIG_OF)

static const struct of_device_id exynos_adc_dt_ids[] = {

{ .compatible = "Samsung,exynos4412-adc" },

{ /* sentinel */ },

};

MODULE_DEVICE_TABLE(of, exynos_adc_dt_ids);

#endif

在 platfrom 平台总线注册与卸载 ADC 驱动,具体代码如下:

int adc_device_init(void)

{//注册  platfrom driver

return platform_driver_register(&exynosadc_driver);}void adc_device_exit(void)

{//卸载  platfrom driver

return platform_driver_unregister(&exynosadc_driver);}

2.1 probe 函数的实现

在 probe 实现以下功能:

分配 adc 设备描述结构体的空间获取 platfrom 驱动私有数据

申请中断资源

获取IO内存资源

申请IO资源的使用

寄存器地址的映射获取 ADC 的通道注册 ADC 字符设备初始化等待队列

在 remove 函数中主要实现相关资源的释放

2.2.1 adc 设备描述与内存分配

在 Linux 内核中描述 ADC 使用下面的结构,这是我们自己定义的:

struct adc_device

{

void *reg;//寄存器映射地址int major_num;//主设备号int irq_num;//中断号

int adc_data;//adc 设备数据

int io_channer;//io 通 道

struct clk *adc_clk;//adc 时钟资源

struct resource *res;//adc io 资 源

struct class *cls;//adc 设备类

struct device *dev;//adc 设备对象

struct cdev cdev;//adc 字符设备对象

wait_queue_head_t read_event_wait;//等待队列头

};

在分配 adc 结构体时,使用的是 kzalloc 函数,具体实现如下:

2.2.2 设置 platform 平台私有数据

获取 platform 私有数据,需要调用 platform_set_drvdata 数据

static inline void platform_set_drvdata(struct platform_device

*pdev,void *data)

@param pdev : platform 平台总线设备描述结构

@param data : 需要存储的

这里主要是将对应的 struct adc_device 对象的地址存储在 struct device 结构体中的

driver_data 成员中,方便其他函数访问,主要是针对有过平台设备时,不同的平台设备有不同

的结构来描述,在匹配成功之后要进行区分

2.2.3 获取中断资源

这里获取中断资源主要是获取中断号,通过 platform_get_irq 函数来实现

padc->irq_num = platform_get_irq(pdev, 0);

if(padc->irq_num < 0){

printk("Fail to platform_get_irq\n");

ret = padc->irq_num;

goto err_platform_get_irq;

}

2.2.4 获取 IO 内存资源

这里获取的资源为 ADC 寄存器的资源,具体代码如下:

在设备树已经有相应的描述

2.2.5 IO资源的占用

在 Linux 内核中,相应的寄存器资源需要申请才能使用,一旦申请成功之后,则不允许别人来访问这段空间.

一般在映射寄存器地址空间之前,就需要申请,这里需要调用 ****

#define request_mem_region(start,n,name)

@param start : 申请资源开始的地址

@param n : 申请资源的长度

@param name : 申请的资源的设备的名字

具体实现如下:

if(!request_mem_region(padc->res->start,io_resource_size,pdev->name))

{

printk("Fail to request_mem_region\n"); ret = -EBUSY;

goto err_request_mem_region;

当需要解除相应的 IO 资源时,则需要调用 release_resource 函数

int release_resource(struct resource *old)

参数:

@param resource : 指定 adc 资源结构对象的指针

2.2.6 获取 adc 的数据通道

adc 的数据通道是在设备树中进行描述,在这里只是获取,具体需要调用:

of_property_read_u32(pdev->dev.of_node, "adc-io-channer", &padc->io_cha

nner);

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。(点击找小助理领取)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值