现代传感器的接口:中断驱动的ADC驱动程序

Interfacing with modern sensors: Interrupt driven ADC drivers

研究了如何编写一个阻塞的模数转换器(ADC)驱动程序和一个使用轮询技术不阻塞应用程序流的驱动程序。轮询外围设备的驱动程序效率低下,如果系统处于低功耗状态,可能会浪费宝贵的时钟周期,否则会浪费能量。开发人员实现ADC驱动程序的一种有效方法是使用中断来通知应用程序转换周期已经完成。在本文中,将研究如何做到这一点。
更新ADC驱动程序示例函数

有几种不同的方法可以编写ADC驱动程序来使用中断。在本文中,将介绍如何修改上一篇文章中介绍的非阻塞ADC驱动程序。应用程序可以通过调用函数ADC_Sample来启动ADC转换。

这是一个很好的例子,为什么有一个好的硬件抽象层(HAL)可以派上用场。无论是阻塞,还是阻塞、轮询或中断,都会调用完全相同的函数,其行为只是根据驱动程序的配置设置而改变,或者可能会根据应用程序的需要链接到不同版本的Adc_Sample函数中。
非阻塞系统的Adc_Sample函数如下所示:

bool Adc_Sample(void)

{

AdcPin_t AdcPin = AdcChannel0;static bool SampleInProgress = false;bool SampleComplete = false;if(SampleInProgress == false){if(Adc_SampleIndex == ADC_SAMPLE_SIZE){Adc_SampleIndex = 0;}

SampleInProgress = true;

    Adc_StartConversion();}else{if(Adc_ConversionComplete == true){for(AdcPin = AdcChannel0; AdcPin

< NUM_ANALOG_PINS; AdcPin++)

        {Adc_SampleBuffer[i][Adc_SampleIndex]

= *AD1BufPtr++;

        }Adc_SampleIndex++;SampleComplete = true;}return SampleComplete;}

新版本中,Adc_Sample函数可能实现如下所示:

bool Adc_Sample(void){ Adc_StartConversion(); return true; }

非阻塞驱动程序有各种各样的检查和对缓冲区的访问等。对于基于中断的驱动程序,所要做的就是启动基于外围设备的ADC通道转换,这是在初始化期间配置的。因此,例如,如果要对通道0、1和3进行采样,这些通道将是在初始化过程中启用的通道。这个驱动程序是一次采样所有指定的通道,而不是只采样一个或两个。正如所提到的,有很多方法可以做到这一点,并帮助澄清概念,正在使用最简单的解决方案。
此时,如果调用Adc_StartConversion,希望Adc外围设备对通道进行采样,但是当中断触发时,此时不会发生任何事情。需要填充ADC中断处理程序,但是在驱动程序中这样做是有问题的。相反,如果可以的话,希望尝试抽象中断处理程序代码。
中断的抽象化

开发人员在编写驱动程序时经常遇到的一个问题是,当开发一个中断驱动的解决方案时,常常将中断与应用程序代码紧密耦合。最佳情况下,中断将驻留在驱动程序层中的驱动程序代码中,而不是位于体系结构中最高层的应用程序代码中。将中断与应用程序代码紧密耦合会使移植代码变得困难,甚至在某些情况下甚至会对其进行缩放。

开发人员可以使用一个解决方案,将中断保留在驱动程序层中,并仍然为应用程序自定义,这就是使用回调。回调函数是对可执行代码的引用,该代码作为参数传递给其代码,后者允许较低级别的软件层调用在高级层中定义的函数[1]。回调函数最简单的就是作为参数传递给另一个函数的函数指针。在大多数情况下,回调将包含三个部分:

回调函数

回调注册

回调执行

在典型的回调实现中,这三个部分是如何协同工作的,如下图所示:

Figure: Typical callback architecture.

ADC驱动程序HAL包含以下功能:

void Adc_CallbackRegister(AdcCallback_t const Function, void (*CallbackFunction)(void));

如果仔细看一下,这个函数被设计成从应用程序代码向ADC驱动程序注册一个回调函数。第一个参数指定回调将分配给哪个中断,而第二个参数通过向函数传递函数指针来指定要调用的函数。

此时的低级驱动程序会将函数指针分配给指定的中断。这是非常灵活的,因为开发人员可以轻松地更新和更改中断执行的函数,而不必返回、修改和重新编译adc驱动程序。这有助于将应用程序代码从驱动程序代码中分离出来,从而创建一个可伸缩和灵活的解决方案。

有了这些知识,可以实现ADC中断处理程序,如下所示:

void ADC_IRQHandler(void){ (*ADC_Interrupt1)(); }

中断只不过是取消对通过Adc_CallbackRegister()函数分配的指针的引用。
编写中断处理程序

对于使用这种方法的开发人员来说,中断处理程序将被写在应用程序层中,并且可以有喜欢的几乎任何函数名。把命名为Adc_InterruptCallback,该回调的实现可能因应用程序而异。例如,在一个应用程序中,回调可能如下所示:

void Adc_CallbackRegister(void){ tx_semaphore_pu(&Adc1Semaphore);}

在本例中,回调只是简单地放置一个信号量来通知任务ADC数据可用。另一个示例可能如下所示:

void Adc_CallbackRegister(void){ AdcPin = AdcChannel0; // Loop through and store the buffer data for(AdcPin = AdcChannel0; AdcPin < NUM_ANALOG_PINS; AdcPin++) { Adc_SampleBuffer[i][Adc_SampleIndex] = *AD1BufPtr++; } Adc_SampleIndex++; if(Adc_SampleIndex == ADC_SAMPLE_SIZE) { Adc_SampleIndex = 0; }}

如所见,由开发人员决定如何在中断处理程序中处理模拟数据,并且根据应用程序及其需要,会有很大的不同。

需要注意的是,对于这些真正是中断处理程序的回调函数,遵循中断处理程序的最佳实践是很重要的。这意味着最小化代码,并使其尽可能快地减少对系统其余性能的影响。

结论

正如在本文中看到的,使用中断驱动驱动程序设计模式可以显著提高驱动程序的效率。使用回调可以将中断实现保留在应用程序代码中,并通过驱动程序的回调机制分配给中断。这使得解决方案和代码具有高度可重用性、灵活性和可伸缩性。

现代传感器的接口:中断驱动的ADC驱动程序相关推荐

  1. 与现代传感器的接口:轮询ADC驱动程序

    与现代传感器的接口:轮询ADC驱动程序 Interfacing with modern sensors: Polled ADC drivers 我们研究了在现代嵌入式应用程序中,开发人员应该如何创建一 ...

  2. linux下ad键盘驱动,led、键盘、ADC驱动程序

    LED,键盘,AD驱动程序开发 一:硬件平台及系统平台 CPU: S3C2410A SDRAM: 64M FLASH: K9F1208(64MB) NET: CS8900 友善之臂2410,优龙241 ...

  3. JESD204B与LVDS接口并行 管线式ADC延迟问题分析及解答

    JESD204B为业界标准序列通信链接,数据转换器与现场可编程门阵列(FPGA).数字信号处理器(DSP).特定应用集成电路(ASIC)等装置间的数字数据接口因此能化繁为简,这项标准减少装置间路由进而 ...

  4. poll接口《来自Linux驱动程序开发实例》

    您所在的位置:读书频道 > 操作系统 > Linux > 1.2.7 poll接口 1.2.7 poll接口 2012-05-22 13:38 冯国进 机械工业出版社 我要评论(0) ...

  5. 称重传感器及HX711 24位ADC的重量参数检测

    一.HX711 24位ADC HX711采用了海芯科技集成电路专利技术,是一款专为高精度电子秤而设计的24位A/D转换器芯片.与同类型其它芯片相比,该芯片集成了包括稳压电源.片内时钟振荡器等其它同类型 ...

  6. ADC驱动程序XPT2046(四-十二)

    XPT2406 xpt2046.h ADC触摸芯片驱动头文件 #ifndef __XPT2046_H_ #define __XPT2046_H_//---包含头文件---// #include < ...

  7. 漏刻有时物联网传感器API接口对接说明文档

    项目说明 门店配备传感器,能获取到店的人数.但是无法满足将本地的数据记录到数据库和传输到服务器,但是需要将数据传到数据库,进行日月年自然日的筛选统计和可视化图表展示. 解决方案 服务器配置url参数链 ...

  8. 驱动程序开发:基于ICM20608六轴传感器 --- 使用Regmap API 的 SPI 读取数据 之 IIO驱动

    目录 一.IIO 子系统简介 二.IIO子系统使用的一些相关的结构体.函数等 1.iio_dev 结构体   ①modes:是选择iio驱动设备支持的工作模式,模式分别有如下:   ②dev:其是一个 ...

  9. 工程监测仪器振弦模拟信号采集仪VTN的传感器接口

    工程监测仪器振弦模拟信号采集仪VTN的传感器接口 传感器接口 VTN4XX 具有 16 组传感器物理接口(每组 5 个端子), 从右向左依次为公共端.线圈.温度/线圈.模拟信号输入.模块信号输入/高精 ...

最新文章

  1. 「摸鱼」神器来了,Python 实现人脸监测制作神器
  2. Cpp 对象模型探索 / 带有虚继承类的构造函数的调用顺序
  3. activex for chrome扩展程序 下载”_chrome系列-扩展程序开发学习-从无到有
  4. showmodaldialog 为什么不能复制_防复制的门禁读头可以防止UID和FUID读卡器
  5. RabbitMQ简介和六种工作模式详解
  6. WPF的WebBrowser屏蔽弹出脚本错误窗口
  7. springboot+openFeign+nacos开发实战
  8. 英特尔发布首款支持 5G NR试验平台 ,离2020年5G商用又进一步
  9. 从零开始学Android(一)
  10. 如何破解HIT的孤岛效应,一起关于患者主索引的案例分享
  11. linux无线网卡信道,linux如何列出网卡支持的wifi信道?
  12. CTC算法详解之训练篇
  13. Python爬虫之堆糖网图片(二)
  14. oracle19c windows 桌面版 安装
  15. [ZT]狄马:老子与美国南北战争
  16. 日期格式不一致问题处理
  17. cadence中测输出功率方法
  18. 产品经理常用词汇汇总
  19. 如何在 Linux 中使用 Calibre 将 PDF 文件转换为 EPUB 格式?
  20. Android Socket IQ聊天软件 之 聊天气泡编码步骤讲解

热门文章

  1. C++ OJ 中多行数据输入(大小写转换、通过移位运算实现2的n次方、多组输入,每行输入数量不一样)
  2. 【VS实践】如何在vs中自动添加注释
  3. Linux BSP非标准HDMI分辨率
  4. 使用Jittor实现Conditional GAN
  5. RGB Color Codes Chart
  6. c语言程序设计第二版第五章课后答案甘勇,郑州工程技术学院副院长甘勇来校讲学和指导工作...
  7. python list 的乘法
  8. Andriod TextView typeface
  9. android EditText 修改光标的颜色值
  10. Java 构造方法与成员方法的区别