现代传感器的接口:中断驱动的ADC驱动程序
现代传感器的接口:中断驱动的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_put(&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驱动程序的更多相关文章
- 与现代传感器的接口:轮询ADC驱动程序
与现代传感器的接口:轮询ADC驱动程序 Interfacing with modern sensors: Polled ADC drivers 我们研究了在现代嵌入式应用程序中,开发人员应该如何创建一 ...
- JZ2440 裸机驱动 第14章 ADC和触摸屏接口
本章目标: 了解S3C2410/S3C2440和触摸屏的结构: 了解电阻触摸屏的工作原理和等效电路图: 了解S3C2410/S3C2440触摸屏控制器的多种工作模式: ...
- Linux驱动程序接口
§1. Linux驱动程序接口 系统调用是操作系统内核与应用程序之间的接口,设备驱动程序则是操作系统内核与机器硬件的接口.几乎所有的系统操作最终映射到物理设备,除了CPU.内存和少数其它设备,所有的设 ...
- 关于esp32的ADC采集
对于ADC采集 程序源码如下: /* ADC1 Example This example code is in the Public Domain (or CC0 licensed, at your ...
- 玩转X-CTR100 l STM32F4 l ADC 模拟数字转换
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 AD转换接 ...
- 第44章 MPU6050传感器—姿态检测—零死角玩转STM32-F429系列
第44章 MPU6050传感器—姿态检测 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...
- jdbc java数据库连接 2)jdbc接口核心的API
JDBC接口核心的API java.sql.* 和 javax.sql.*(java2.0以后更新的扩展) |- Driver接口: 表示java驱动程序接口.所有的具体的数据库厂商要来实现此接 ...
- sja1000芯片can驱动程序
应用层使用socketCan的方法:http://pan.baidu.com/s/1ntsvbb7#path=%252Floongson1%252Ftools%252Fcan 功能:对can驱动程序的 ...
- 基于WDF的PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)
原文出处:http://www.cnblogs.com/jacklu/p/4687325.html 本篇文章将对PCIe驱动程序的源文件代码作详细解释与说明.整个WDF驱动程序工程共包含4个头文件(已 ...
随机推荐
- Java中的结构语句
目录 循环语句 While循环 do...While循环 for循环 增强型for语句 条件语句 if..else语句 if...else if...else 语句 嵌套的 if-else 语句 sw ...
- 将一个eclipse的SSM项目用IDEA打开并运行
项目部署 将一个eclipse项目用idea打开,并且 部署到tomcat中 .或者你tomcat部署成功,但是启动就是404,下面的步骤就要更认真看了 项目配置 打开idea,Import Proj ...
- 解决Failed to execute goal se.eris:notnull-instrumenter-maven-plugin:0.6.8
https://blog.csdn.net/fanrenxiang/article/details/80864908 github拉起来的项目,jdk是11,而我电脑上的jdk是1.8.原因是jdk版 ...
- 前端实操案例丨如何实现JS向Vue传值
摘要:项目开发过程中,组件通过render()函数渲染生成,并在组件内部定义了自定义拖拽指令.自定义拖拽指令规定了根据用户可以进行元素拖拽.缩放等一系列逻辑处理的动作. 本文分享自华为云社区<[ ...
- 在Visual Studio 中使用git——文件管理-下(六)
在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...
- select执行顺序
先from 找到表on过滤 找到两张表有对应关系的记录按join的方式添加外部行where 过滤group by分组having 过滤select 从having 过滤出来的字段中选择需要的字段dis ...
- Taro使用多线程Worker相关问题解决
JavaScript 语言采用的是单线程模型,HTML5标准中的Web Worker ,为 JavaScript 创造多线程环境.微信小程序也有相应的Worker,同样具备多线程运行的能力 主页面中创 ...
- 『动善时』JMeter基础 — 19、JMeter配置元件【随机变量】
目录 1.随机变量介绍 2.随机变量界面详解 3.随机变量的使用 (1)测试计划内包含的元件 (2)线程组界面内容 (3)随机变量界面内容 (4)HTTP请求界面内容 (5)查看结果 1.随机变量介绍 ...
- 6.注册CRT 以及SecureCRT访问
1.什么是 SecureCRT SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录Unix或Linux服务器主 机的软件. 1)准备工作:安装好Se ...
- [bug] Python:“TabError: inconsistent use of tabs and spaces in indentation”
原因 代码中混用了Tab和4个空格 参考 https://blog.csdn.net/dongdong9223/article/details/82745068