Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
linux adc是什么设备_创想鸟

linux adc是什么设备

linux adc是混杂设备驱动;在linux2.6.30.4中,系统已经自带有了ADC通用驱动文件“arch/arm/plat-s3c24xx/adc.c”,它是以平台驱动设备模型的架构来编写的,里面是一些比较通用稳定的代码。

linux adc是什么设备

本教程操作环境:linux2.6.30.4系统、Dell G3电脑。

linux adc是什么设备?

linux 混杂设备驱动之adc驱动

linux2.6.30.4中,系统已经自带有了ADC通用驱动文件—arch/arm/plat-s3c24xx/adc.c,它是以平台驱动设备模型的架构来编写的,里面是一些比较通用稳定的代码,但是linux2.6.30.4版本的ADC通用驱动文件并不完善,居然没有读函数。后来去看了linux3.8版本的ADC通用文件—-arch/arm/plat-samsung/adc.c才是比较完善的。

但是本节并不是分析这个文件,而是以另外一种架构来编写ADC驱动,因为ADC驱动实在是比较简单,就没有使用平台驱动设备模型为架构来编写了,这次我们使用的是混杂(misc)设备驱动。

问:什么是misc设备驱动?

答:miscdevice共享一个主设备号MISC_MAJOR(10),但次设备号不同。所有的miscdevice设备形成一条链表,对设备访问时内核根据设备号来查找对应的miscdevice设备,然后调用其file_operations结构体中注册的文件操作接口进行操作。

struct miscdevice  {int minor;//次设备号,如果设置为MISC_DYNAMIC_MINOR则系统自动分配const char *name;//设备名const struct file_operations *fops;//操作函数struct list_head list;struct device *parent;struct device *this_device;};

dev_init入口函数分析:

static int __init dev_init(void){int ret;base_addr=ioremap(S3C2410_PA_ADC,0x20);if (base_addr == NULL){printk(KERN_ERR "failed to remap register blockn");return -ENOMEM;}adc_clock = clk_get(NULL, "adc");if (!adc_clock){printk(KERN_ERR "failed to get adc clock sourcen");return -ENOENT;}clk_enable(adc_clock);ADCTSC = 0;ret = request_irq(IRQ_ADC, adcdone_int_handler, IRQF_SHARED, DEVICE_NAME, &adcdev);if (ret){iounmap(base_addr);return ret;}ret = misc_register(&misc);printk (DEVICE_NAME" initializedn");return ret;}

首先是映射ADC寄存器地址将其转换为虚拟地址,然后获得ADC时钟并使能ADC时钟,接着申请ADC中断,其中断处理函数为

adcdone_int_handler,而flags为IRQF_SHARED,即共享中断,因为触摸屏里也要申请ADC中断,最后注册一个混杂设备。

当应用程序open (“/dev/adc”,…)时,就会调用到驱动里面的open函数,那么我们来看看open函数做了什么?

static int tq2440_adc_open(struct inode *inode, struct file *filp){/* 初始化等待队列头 */init_waitqueue_head(&(adcdev.wait));/* 开发板上ADC的通道2连接着一个电位器 */adcdev.channel=2;//设置ADC的通道adcdev.prescale=0xff;DPRINTK( "ADC openedn");return 0;}

很简单,先初始化一个等待队列头,因为入口函数里既然有申请ADC中断,那么肯定要使用等待队列,接着设置ADC通道,因为TQ2440的ADC输入通道默认是2,设置预分频值为0xff。

当应用程序read时,就会调用到驱动里面的read函数,那么我们来看看read函数做了些什么?

static ssize_t tq2440_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){char str[20];int value;size_t len;/* 尝试获得ADC_LOCK信号量,如果能够立刻获得,它就获得信号量并返回0  * 否则,返回非零,它不会导致调用者睡眠,可以在中断上下文使用 */if (down_trylock(&ADC_LOCK) == 0){/* 表示A/D转换器资源可用 */ADC_enable = 1;/* 使能预分频,选择ADC通道,最后启动ADC转换*/START_ADC_AIN(adcdev.channel, adcdev.prescale);/* 等待事件,当ev_adc = 0时,进程被阻塞,直到ev_adc>0 */wait_event_interruptible(adcdev.wait, ev_adc);ev_adc = 0;DPRINTK("AIN[%d] = 0x%04x, %dn", adcdev.channel, adc_data, ((ADCCON & 0x80) ? 1:0));/* 将在ADC中断处理函数读取的ADC转换结果赋值给value */value = adc_data;sprintf(str,"%5d", adc_data);copy_to_user(buffer, (char *)&adc_data, sizeof(adc_data));ADC_enable = 0;up(&ADC_LOCK);}else{/* 如果A/D转换器资源不可用,将value赋值为-1 */value = -1;}/* 将ADC转换结果输出到str数组里,以便传给应用空间 */len = sprintf(str, "%dn", value);if (count >= len){/* 从str数组里拷贝len字节的数据到buffer,即将ADC转换数据传给应用空间 */int r = copy_to_user(buffer, str, len);return r ? r : len;}else{return -EINVAL;}}

tq2440_adc_read函数首先尝试获得ADC_LOCK信号量,因为触摸屏驱动也有使用ADC资源,两者互有竞争关系,获得ADC资源后,使能预分频,选择ADC通道,最后启动ADC转换,接着就调用wait_event_interruptible 函数进行等待,直到ev_adc>0进程才会继续往下跑,往下跑就会将adc_data数据读出来,调用copy_to_user函数将ADC数据传给应用空间,最后释放ADC_LOCK信号量。

问:什么时候ev_adc>0?默认ev_adc = 0

造物云营销设计 造物云营销设计

造物云是一个在线3D营销设计平台,0基础也能做电商设计

造物云营销设计 37 查看详情 造物云营销设计

答:在adcdone_int_handler中断处理函数里,等数据读出后,ev_adc被设置为1。

ADC中断处理函数adcdone_int_handler

/* ADC中断处理函数 */static irqreturn_t adcdone_int_handler(int irq, void *dev_id){/* A/D转换器资源可用 */if (ADC_enable){/* 读ADC转换结果数据 */adc_data = ADCDAT0 & 0x3ff;/* 唤醒标志位,作为wait_event_interruptible的唤醒条件 */ev_adc = 1;wake_up_interruptible(&adcdev.wait);}return IRQ_HANDLED;}

当AD转换完成后就会触发ADC中断,就会进入adcdone_int_handler,这个函数就会讲AD转换数据读到adc_data,接着将唤醒标志位ev_adc置1,最后调用wake_up_interruptible函数唤醒adcdev.wait等待队列。
总结一下ADC的工作流程:

一、open函数里,设置模拟输入通道,设置预分频值

二、read函数里,启动AD转换,进程休眠

三、adc_irq函数里,AD转换结束后触发ADC中断,在ADC中断处理函数将数据读出,唤醒进程

四、read函数里,进程被唤醒后,将adc转换数据传给应用程序

ADC驱动参考源码:

/*************************************NAME:EmbedSky_adc.cCOPYRIGHT:www.embedsky.net*************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include #include  #include #include #include #include #include "tq2440_adc.h"#undef DEBUG//#define DEBUG#ifdef DEBUG#define DPRINTK(x...) {printk(KERN_DEBUG "EmbedSky_adc: " x);}#else#define DPRINTK(x...) (void)(0)#endif#define DEVICE_NAME"adc"/* 设备节点: /dev/adc */static void __iomem *base_addr;typedef struct{wait_queue_head_t wait;/* 定义等待队列头 */int channel;int prescale;}ADC_DEV;DECLARE_MUTEX(ADC_LOCK);/* 定义并初始化信号量,并初始化为1 */static int ADC_enable = 0;/* A/D转换器资是否可用标志位 */static ADC_DEV adcdev;/* 用于表示ADC设备 */static volatile int ev_adc = 0;/* 作为wait_event_interruptible的唤醒条件 */static int adc_data;static struct clk*adc_clock;#define ADCCON(*(volatile unsigned long *)(base_addr + S3C2410_ADCCON))//ADC control#define ADCTSC(*(volatile unsigned long *)(base_addr + S3C2410_ADCTSC))//ADC touch screen control#define ADCDLY(*(volatile unsigned long *)(base_addr + S3C2410_ADCDLY))//ADC start or Interval Delay#define ADCDAT0(*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT0))//ADC conversion data 0#define ADCDAT1(*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT1))//ADC conversion data 1#define ADCUPDN(*(volatile unsigned long *)(base_addr + 0x14))//Stylus Up/Down interrupt status#define PRESCALE_DIS(0 << 14)#define PRESCALE_EN(1 << 14)#define PRSCVL(x)((x) << 6)#define ADC_INPUT(x)((x) << 3)#define ADC_START(1 << 0)#define ADC_ENDCVT(1 <0 */wait_event_interruptible(adcdev.wait, ev_adc);ev_adc = 0;DPRINTK("AIN[%d] = 0x%04x, %dn", adcdev.channel, adc_data, ((ADCCON & 0x80) ? 1:0));/* 将在ADC中断处理函数读取的ADC转换结果赋值给value */value = adc_data;sprintf(str,"%5d", adc_data);copy_to_user(buffer, (char *)&adc_data, sizeof(adc_data));ADC_enable = 0;up(&ADC_LOCK);}else{/* 如果A/D转换器资源不可用,将value赋值为-1 */value = -1;}/* 将ADC转换结果输出到str数组里,以便传给应用空间 */len = sprintf(str, "%dn", value);if (count >= len){/* 从str数组里拷贝len字节的数据到buffer,即将ADC转换数据传给应用空间 */int r = copy_to_user(buffer, str, len);return r ? r : len;}else{return -EINVAL;}}static int tq2440_adc_open(struct inode *inode, struct file *filp){/* 初始化等待队列头 */init_waitqueue_head(&(adcdev.wait));/* 开发板上ADC的通道2连接着一个电位器 */adcdev.channel=2;//设置ADC的通道adcdev.prescale=0xff;DPRINTK( "ADC openedn");return 0;}static int tq2440_adc_release(struct inode *inode, struct file *filp){DPRINTK( "ADC closedn");return 0;}static struct file_operations dev_fops = {owner:THIS_MODULE,open:tq2440_adc_open,read:tq2440_adc_read,release:tq2440_adc_release,};static struct miscdevice misc = {.minor = MISC_DYNAMIC_MINOR,.name = DEVICE_NAME,.fops = &dev_fops,};static int __init dev_init(void){int ret;base_addr=ioremap(S3C2410_PA_ADC,0x20);if (base_addr == NULL){printk(KERN_ERR "failed to remap register blockn");return -ENOMEM;}adc_clock = clk_get(NULL, "adc");if (!adc_clock){printk(KERN_ERR "failed to get adc clock sourcen");return -ENOENT;}clk_enable(adc_clock);ADCTSC = 0;ret = request_irq(IRQ_ADC, adcdone_int_handler, IRQF_SHARED, DEVICE_NAME, &adcdev);if (ret){iounmap(base_addr);return ret;}ret = misc_register(&misc);printk (DEVICE_NAME" initializedn");return ret;}static void __exit dev_exit(void){free_irq(IRQ_ADC, &adcdev);iounmap(base_addr);if (adc_clock){clk_disable(adc_clock);clk_put(adc_clock);adc_clock = NULL;}misc_deregister(&misc);}EXPORT_SYMBOL(ADC_LOCK);module_init(dev_init);module_exit(dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("www.embedsky.net");MODULE_DESCRIPTION("ADC Drivers for EmbedSky SKY2440/TQ2440 Board and support touch");

ADC应用测试参考源码:

/*************************************NAME:EmbedSky_adc.cCOPYRIGHT:www.embedsky.net*************************************/#include #include #include #include #include #include #include #include #include #include int main(void){int fd ;char temp = 1;fd = open("/dev/adc", 0);if (fd  0){buffer[len] = '';int value;sscanf(buffer, "%d", &value);printf("ADC Value: %dn", value);}else{perror("read ADC device !");exit(1);}sleep(1);}adcstop:close(fd);}

测试结果:

[WJ2440]# ./adc_test ADC Value: 693ADC Value: 695ADC Value: 694ADC Value: 695ADC Value: 702ADC Value: 740ADC Value: 768ADC Value: 775ADC Value: 820ADC Value: 844ADC Value: 887ADC Value: 937ADC Value: 978ADC Value: 1000ADC Value: 1023ADC Value: 1023ADC Value: 1023

相关推荐:《Linux视频教程》

以上就是linux adc是什么设备的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/249149.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何备份和恢复MySQL连接?
上一篇 2025年11月4日 04:41:33
Windows上FLV文件打不开怎么办?教你安装FLV播放器的详细步骤
下一篇 2025年11月4日 04:41:39

相关推荐

  • python 基准测试(cProfile kcachegrind line_profiler memory_profiler)

    learn from 《python高性能(第2版)》 类似工具:pycharm profile对函数调用效率进行测试 1. 例子 一个圆周运动的动画 代码语言:javascript代码运行次数:0运行复制 from matplotlib import pyplot as pltfrom matpl…

    2026年9月22日
    100
  • VSCode安装C/C++开发环境 最新VSCode配置C语言教程详解

    答案:搭建VSCode的C/C++环境需安装编译器、C/C++扩展并配置项目文件。首先安装MinGW(Windows)、Clang(macOS)或GCC(Linux),配置环境变量并验证;然后在VSCode中安装Microsoft的C/C++扩展;最后创建.c_cpp_properties.json…

    2026年9月22日
    200
  • Linux平台下的Eclipse配置

    在linux平台上配置eclipse时,可能会遇到一些常见的问题和优化需求。本文将详细介绍如何解决这些问题,并提供优化eclipse的建议。 启动Eclipse报错 启动Eclipse时,如果遇到以下错误: A Java Runtime Environment (JRE) or Java Devel…

    2026年9月22日
    000
  • 常见分布式任务调度工具浅析

    一、背景 在日常业务中,经常会遇到需要在特定时间执行任务或周期性执行任务的需求。这些任务通常被归类为定时任务。为了满足这种需求,各种任务调度框架应运而生,如Timer、ScheduledThreadPoolExecutor(没错,它也可以用于定时任务)、Quartz等。然而,随着分布式和微服务的发展…

    2026年9月22日
    100
  • VSCode安全更新机制解析

    VSCode通过自动检查、数字签名验证和用户可控策略确保更新安全。启动时后台定期HTTPS请求检查新版本,每日一次;安装包经平台特定签名(Windows Authenticode、macOS代码签名、Linux GPG)验证完整性;用户可选自动更新、提示或关闭,企业可集中管控;微软通过安全入口响应漏…

    2026年9月22日
    100
  • Linux系统中文件属性和权限实战操作

    Linux系统中文件属性和权限实战操作Linux系统中文件属性和权限实战操作Linux系统中文件属性和权限实战操作Linux系统中文件属性和权限实战操作

    —–原本今天的文章是昨天晚上就要更新的,但是由于昨天晚上下班回到住的地方,发现停电了,所以就没写成。今天是在上一篇文章–linux系统中文件类型的基础上,继续进行深入的学习。好了,直接开干。 一、文件的操作权限: 1、在这之前我想还是很有必要介绍对文件的操作权限(…

    2026年9月22日 用户投稿
    200
  • 如何在Linux命令行中进行文件查找?

    最常用Linux查找文件方法是使用find命令。按名称搜索用-name选项,如find . -name “*.log”;忽略大小写用-iname;按类型查用-type f(文件)或d(目录);按大小查用-size,如+100M表示大于100MB;按修改时间用-mtime,-7…

    2026年9月22日
    000
  • VSCode配置C语言调试环境 从零开始VSCode搭建C开发工具

    要从零开始在#%#$#%@%@%$#%$#%#%#$%@_e2fc++805085e25c9761616c00e065bfe8中搭建c语言开发和调试环境,首先需安装vscode本体、c/c++编译器(如mingw或gcc)并配置系统环境变量,接着安装vscode的c/c++扩展,然后创建项目并编写c…

    2026年9月22日
    000
  • 每个 Linux 用户都应该知道的 5 个简单的 Bash 历史技巧

    每个 Linux 用户都应该知道的 5 个简单的 Bash 历史技巧每个 Linux 用户都应该知道的 5 个简单的 Bash 历史技巧每个 Linux 用户都应该知道的 5 个简单的 Bash 历史技巧每个 Linux 用户都应该知道的 5 个简单的 Bash 历史技巧

    无论您是bash 初学者还是专家,如果不使用超级有用的 bash 历史记录功能,您将无法继续在命令行中工作。 您可能已经知道,如果您在 Linux 终端中使用向上或向下箭头键,您可以查看之前运行的命令。 这要归功于bash history 命令。 1.查看您的 bash 历史记录 查看您之前键入的命…

    2026年9月22日 用户投稿
    000
  • VSCode搭建Python开发环境(附详细截图,小白也能学会)

    答案:搭建VSCode Python环境需安装Python并添加至PATH,安装VSCode及Python扩展,创建项目文件并选择正确解释器,通过虚拟环境隔离依赖,利用Pylance、Black、Flake8等工具提升开发效率,常见问题多为路径或环境配置错误,可通过检查解释器选择和安装路径解决。 在…

    2026年9月22日
    100
  • Vision Transformer 必读系列之图像分类综述(三): MLP、ConvMixer 和架构分析

    Vision Transformer 必读系列之图像分类综述(三): MLP、ConvMixer 和架构分析Vision Transformer 必读系列之图像分类综述(三): MLP、ConvMixer 和架构分析Vision Transformer 必读系列之图像分类综述(三): MLP、ConvMixer 和架构分析Vision Transformer 必读系列之图像分类综述(三): MLP、ConvMixer 和架构分析

    号外号外!awesome-vit 上新啦, 欢迎大家 Star Star Star ~ https://github.com/open-mmlab/awesome-vit 前言 在 Vision Transformer 必读系列之图像分类综述(一):概述 一文中对 Vision Transforme…

    2026年9月22日 用户投稿
    200
  • 解决PHP应用中本地文件更新后网页视图不刷新的缓存问题

    本文探讨了PHP应用中,本地JSON或图片文件更新后,网页视图无法实时刷新的常见问题。核心原因在于浏览器缓存机制。文章将提供多种解决方案,包括强制刷新、隐身模式诊断、以及通过URL参数、服务器配置(.htaccess)和文件版本控制来有效管理缓存,确保用户始终获取最新数据。 理解问题:本地文件更新与…

    2026年9月22日
    200
  • VSCode安装C/C++代码格式化 专业VSCode开发环境配置

    配置VSCode进行C/C++开发需安装C/C++扩展包和clang-format,设置自动格式化与调试环境,推荐使用CMake Tools、Include Autocomplete等扩展,结合快捷键、代码片段和任务自动化提升效率。 配置VSCode以实现C/C++代码的专业格式化和高效开发环境,核…

    2026年9月22日
    500
  • Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)

    could not find doxygen (missing: doxygen_executable)  使用cmake .. 有时候会遇到如下问题: 代码语言:javascript代码运行次数:0运行复制 $ cmake ..– The CXX compiler identification …

    2026年9月22日
    100
  • MySQL自动化备份如何实现_适合企业级部署吗?

    MySQL自动化备份如何实现_适合企业级部署吗?MySQL自动化备份如何实现_适合企业级部署吗?MySQL自动化备份如何实现_适合企业级部署吗?MySQL自动化备份如何实现_适合企业级部署吗?

    mysql的自动化备份对企业级部署是必要的,且可通过多种方式实现。1. 使用mysqldump+定时任务(crontab)是最基础的方式,操作简单适合中小规模数据库,但备份时可能锁表影响业务;2. 增量备份结合二进制日志(binary log)更高效,适用于频繁变更的数据,支持精确恢复到某时间点;3…

    2026年9月21日 用户投稿
    100
  • Online Config VS Code

    Online Config VS CodeOnline Config VS CodeOnline Config VS CodeOnline Config VS Code

    run vs view Install Code Server Update Code Server Database:It is recommended to create a Docker container for the database. Code Language: JavaScript…

    2026年9月21日 用户投稿
    200
  • 一键PHP环境怎么解决网页空白问题_空白页故障诊断

    答案是开启错误提示并检查文件路径与代码逻辑。先启用PHP错误显示,确认配置正确;再核对网站根目录和入口文件是否存在;接着排查代码致命错误及输出缓冲问题,确保无BOM头且session前无输出。 遇到一键PHP环境安装后出现网页空白或空白页问题,通常不是环境完全失效,而是某些关键环节出了错。这类问题在…

    2026年9月21日
    100
  • Bun 1.3 正式发布

    2025年10月10日,高性能 javascript 运行时 bun 发布了 1.3 版本。这是 bun 项目迄今为止最重大的版本更新,标志着 bun 从单纯的运行时工具演变为一个功能完备的全栈 javascript 开发平台。 从运行时到全栈平台的跨越 Bun 1.3 的核心突破在于将前端开发能力…

    2026年9月21日
    100
  • Linux文件系统mv命令使用详解

    mv命令用于移动或重命名文件和目录,若目标不存在则重命名,存在且为目录则移动,为文件则覆盖;常用选项包括-i(交互确认)、-f(强制覆盖)、-u(更新移动)、-v(显示过程);可重命名如mv oldname.txt newname.txt,或移动如mv file.txt /dir/;建议使用alia…

    2026年9月21日
    100
  • VSCode怎么手动保存代码_VSCode禁用自动保存与手动保存设置教程

    手动保存代码只需按Ctrl + S(Windows/Linux)或Cmd + S(macOS),可通过设置将“files.autoSave”设为“off”来禁用自动保存,并结合版本控制保障代码安全。 VSCode手动保存代码其实很简单,默认情况下,按下 Ctrl + S (Windows/Linux…

    2026年9月21日
    300

发表回复

登录后才能评论
关注微信