s3c2410多通道adc驱动及测试程序(使用write控制多通道)

2024-02-10 03:18

本文主要是介绍s3c2410多通道adc驱动及测试程序(使用write控制多通道),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

免责声明:

本文所涉及的驱动是在SeonKon Choi于2003年编写的适合2.4版本内核的ADC驱动基础上结合网络能找得到的代码片段经过自己的修改并实践通过的。测试过程中的ADC并不涉及其它驱动(比如与ADC有很密切关系的触摸屏驱动)。本文作者本着GNU共享精神发表此文并附录源代码——其实公布源代码是必须的,因为代码使用GPL(而如何行文则是作者的自由)。至于如何使用文中知识点及代码,无论正确与否,概与文章作者无关,风险自担。不过,趁文章作者还有激情研究驱动之时,欢迎一起讨论,大家共同学习,天天向上。

 

杂项:

本文上接《s3c2410多通道adc驱动及测试程序》,里面承诺了用write来传递数据到内核中。那篇文章使用ioctl来控制通道,而本文使用write控制通道。而两者的驱动,在本质上是一致的——除了针对内核版本不同而有所修改外。

 

收获:

在修改人家驱动代码过程中,对于一些不确定的函数(比如位于哪个头文件,每个函数参数的含义),逐一google之,并查看内核源代码。个人认为,学习代码、驱动这种事情,最好在实践中学习,看书与实践结合起来。话虽如此,真正做到的人却不多。如果不去动手写,看再多的LDD3、ELDD、ULK、APUE、CSAPP也收获不丰,印象不深。说来惭愧,正是这个观点,让我一直不去看书,至今连LDD3也没看完,APUE也刚开了个头。

 

未尽及将来可能会做的事:

1、与TS共享中断,使用信号量进行互斥访问。

2、其它的。

 

正文:

如想直接抄代码,可忽略行文,直接到文章后面下载附录的工程压缩包或源代码。

1、对于头文件,不必说太多,2.4版本的内核有些头文件已经删除或修改或合并等等,比如像<linux/config.h>已经不在了。

2、使用ioremap,这使得代码整洁、易看。举一例:

网上使用如下代码片段(示意性代码)设置通道,读取ADC数据:

writel((1<<14) | PRSCVL(adcdev.prescale) | ADC_INPUT(adcdev.channel) | 0x01 | 0x01, S3C2410_ADCCON);

ret = readl(S3C2410_ADCDAT0);

 

使用宏后:

 START_ADC_AIN(adcdev.channel, adcdev.prescale);

 ret = ADCDAT0;

 

其中START_ADC_AIN将设置通道、启动ADC等合在一起,ADCDAT0是经过ioremap后加上一偏移得到的“寄存器”。

如此一来,是不是觉得后面的代码很直观很容易看?不过这也有一点不好,封闭得太多了,对于想知道其中原理的人来说可不是件好事。比如声明一个信号量,使用DECLARE_MUTEX(ADC_LOCK)或DEFINE_SEMAPHORE(ADC_LOCK),这很好懂,但是这个宏到底做了些什么呢?这就要深入到这个宏定义所在文件中研究了(在<linux/semaphore.h>文件中)。

 

对于这两宏,想说几句,因为最近一次移植新版本的内核(2.6.37.3),就是因为DECLARE_MUTEX不再使用而导致我浪费了几天的时间。据本人考查,最早说要将DECLARE_MUTEX改为DEFINE_SEMAPHORE是在08年10月底,参见地址http://lwn.net/Articles/304725/。而在Linux Cross Reference(网站如http://lxr.free-electrons.com/等等)中发现,直到2.6.36才出现DEFINE_SEMAPHORE,而且这个版本中两个宏同时存在。但是到了2.6.37,DECLARE_MUTEX这个宏却不存在了。

不由得想到某个论坛的签名,原文是英文的,原文及出处一时不知道去哪找了。大意是说UNIX最好的地方是什么?答曰:有社区,再问UNIX不好的地方是什么?答曰:有太多的社区。像Linux内核这东西,版本更新太快了,各种结构体名称变化、成员变化及新增函数、删除函数,让人目不暇接。虽说一味追求新版本不好,但是心理作用,还是选择新的版本来移植。新的东西当然有它的好,像买台android的手机,就得不停的刷机,不断折腾,这跟搞Linux在某种程度上是一样的。

 

3、硬件寄存器

ADC驱动涉及的寄存器不多,都可以在datasheet中找到说明的。如:

#define PRSCVL(x)              ((x) << 6)
#define ADC_INPUT(x)        ((x) << 3)
#define ADC_START            (1 << 0)

 

第一个是设置AD转换器预定频率(注:该术语可能不标准),左移6位,是因为ADCCON寄存器的6~13位就是这个值。而ADC_INPUT是选择通道的,位于ADCCON寄存器的3~5位。最后一行是使能ADC(启动ADC),位于ADCCON第0位,1表示开始转换(注:根据datasheet英文理解)。

其实这些不难理解的,看多代码了,自然也知道了。自从当年学AVR后,我对这种方式的移位特别有好感,甚至一度上瘾,常常跟别人说,不过没多少人理解,后来就算了,自己独自享受这种便捷了。

 

4、与原来代码的改动:

1)、去掉MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT,这个据说在2.6中不再使用了。

2)、对于request_irq函数,将IRQ_ADC_DONE改为IRQ_ADC,最后一个参数改为&adcdev。

3)、将adcdone_int_handler函数返回类型由原来的void改为irqreturn_t。

4)、另外添加cdev类型的变量,因为注册字符设备需要使用到。

5)、判断copy_from_user、copy_to_user两个函数的返回值,正常返回0,出错则返回没有复制成功的字节数。出错时返回-EFAULT。如果不判断,会出现一个警告,比如:

warning: ignoring return value of 'copy_to_user', declared with attribute warn_unused_result

内核中很多地方都使用这两个函数,都作了判断。

 

其它的修改不一一道来了。

 

测试过程:

测试手段很多,由于本人的网络驱动一直不成功,不能使用方便快捷的NFS方式来测试。将编译好的驱动模块和交叉编译后的测试程序拷贝到U盘,再用U盘复制到开发板上,在这个过程中,文件丢失了可执行性,又得在开发板上用chmod恢复可执行性。很是麻烦。

 

原想将未修改的代码与修改后的代码作一个patch的,不过有10KB那么大,就不帖出来了(附件里有)。下面附上工程目录及源代码。如果网页显示与工程文件不一致,以工程目录中的文件为准。实际代码中没有中文注释,由此带来的各种质问及不解,本人不作解释。

 

整个工程下载(压缩文件名称为s3c2410-adc-latelee.org.tar.bz2,md5sum为0aa975c62eaefb8d05430bca8d7df088):

---

 

应用层的测试代码:

---

本人得到的原始的源代码如下:

---

经过修改后的源代码:

---

原文出处:www.latelee.org/embedded-linux/mutil-channel-adc-of-s3c2410-write.html

这篇关于s3c2410多通道adc驱动及测试程序(使用write控制多通道)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695995

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud