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

Interfacing with modern sensors: Polled ADC drivers

我们研究了在现代嵌入式应用程序中,开发人员应该如何创建一个接口,将底层驱动程序实现细节与应用程序代码分离。这个接口提供了一个体系结构抽象,通过减少对硬件的依赖,提高了应用程序代码的可伸缩性和可移植性。

现在我们将开始研究几种不同的方法,开发人员可以根据我们在3个微控制器驱动程序设计技术中讨论的技术来实现ADC驱动程序。在本文中,我们将更详细地研究如何使用轮询技术,并讨论阻塞和非阻塞驱动程序之间的区别。

阻止还是不阻止,这是个问题

当为微控制器开发任何驱动程序时,开发人员必须决定他们的驱动程序是阻塞的还是非阻塞的。阻塞驱动程序基本上会暂停代码的执行,直到驱动程序完成其任务为止。例如,printf映射到UART的典型实现是阻塞的。

当你打电话时:

printf(“你好,世界!”);

开发人员知道,无论该语句后面的哪一行代码都不会执行,直到整个“Hello World!“声明已经在通用异步收发器上打印出来了。“你好,世界!“包含12个字节,96位,但语句阻塞的时间取决于UART波特率。对于配置为1Mbps的UART,您将期望大约96微秒。对于配置为9600bps的UART,您将期望大约10000微秒!这是一个很大的区别,这取决于硬件的配置,它可以显著地影响程序的执行,UART驱动程序被配置为阻塞驱动程序。

非阻塞驱动程序是在驱动程序完成其任务时不会暂停程序执行的驱动程序。例如,上一个例子中的printf和UART驱动程序可以被配置成不阻塞,而是允许应用程序在每个字节被发送出UART时继续执行。这可以在适当的情况下实现更有效的应用,但需要额外的设置,例如使用中断、DMA或至少一个传输缓冲区。

如何设计驱动程序取决于应用程序和硬件。例如,如果UART被配置为1Mbps,那么从效率的角度来看,编写非阻塞驱动程序可能不会获得太多好处,实际上可能会导致更多的问题,而不是通过增加程序复杂性来解决问题。然而,如果应用程序调用9600bps,其中应用程序代码被阻塞10毫秒,那么拥有一个非阻塞驱动程序可以显著提高程序效率,并且额外的时间复杂度问题的风险更小,也更易于管理。

嵌入式ADC驱动程序概述

需要注意的是,在一个博客中,我无法完成编写完整ADC驱动程序所需的所有步骤。我可以很容易地写一篇20页的论文,或者开一个完整的网络研讨会,它可能还不能涵盖所有的细节,但我们至少可以看看一些核心部分。

低级驱动程序在初始化时接收配置模块,并根据配置设置硬件。低级驱动程序提供了一个公共硬件抽象层(HAL),应用程序代码可以使用它。ADC-HAL调用应该是通用的,以便高级应用程序可以以任何必要的方式配置硬件,并且可以重用和扩展。例如,我过去使用的一些ADC HAL调用包括:

·       AdcError_t Adc_Init(const AdcConfig_t * Config);

·       AdcError_t Adc_StartConversion(void);

·       bool Adc_ConversionComplete(void);

·       void Adc_RegisterWrite(uint32_t const Address, uint32_t const Value);

·       uint32_t Adc_RegisterRead(uint32_t Address);

·       void Adc_CallbackRegister(AdcCallback_t const Function, TYPE (*CallbackFunction)(type));

前三个API提供初始化ADC硬件、启动转换并检查转换状态的功能。最后三个函数的设计是为了允许低层硬件的可伸缩性。例如,如果HAL不提供应用程序所需的选项(例如转换单个ADC信道),则可以使用ADC_RegisterRead和ADC_RegisterWrite函数扩展HAL。这提供了基于应用程序需求的灵活性,而不需要创建一个压倒性的API。

编写一个简单的阻塞ADC驱动程序

我们可以编写一个非常简单的ADC驱动程序,它位于硬件层之上。例如,我们可以创建一个名为Adc_Sample的简单函数,该函数启动Adc硬件,然后将所有结果存储在缓冲区中,然后应用程序可以访问该缓冲区。存储模拟值计数值的缓冲区不一定只需要存储一个值,而是可以存储多个值,这些值以后可以根据应用程序的需要进行平均或过滤。采样函数的阻塞版本可能如下所示:

正如您在这段代码中看到的,while循环会阻止执行,直到ADC硬件完成转换,然后将值存储在应用程序缓冲区中。

编写一个简单的无阻塞ADC驱动程序

将阻塞驱动程序转换为非阻塞代码非常简单,但是需要对更高级别的应用程序代码进行更改。例如,现在,如果应用程序要对传感器进行采样,开发人员会调用:

Adc_Sample();

在非阻塞版本中,开发人员必须检查Adc_Sample的返回值,以查看示例是否已完成并可以使用。这使示例可以在后台运行,应用程序代码在驱动程序代码的以下更新后继续运行:

结论

正如我们在这篇文章中看到的,有多种方法来编写ADC,并且实现可以是阻塞的,也可以是非阻塞的,这取决于我们的需要。阻塞驱动程序往往比非阻塞驱动程序更简单、更不完整,但它们可能效率低下。非阻塞驱动程序允许其他代码在驱动程序工作时运行,但是应用程序代码仍然需要检查状态,这在轮询实现中本身效率低下。

与现代传感器的接口:轮询ADC驱动程序的更多相关文章

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

    现代传感器的接口:中断驱动的ADC驱动程序 Interfacing with modern sensors: Interrupt driven ADC drivers 研究了如何编写一个阻塞的模数转换 ...

  2. Apollo 8 — ConfigService 异步轮询接口的实现

    源码 Apollo 长轮询的实现,是通过客户端轮询 /notifications/v2 接口实现的.具体代码在 com.ctrip.framework.apollo.configservice.con ...

  3. Postman实现数字签名,Session依赖, 接口依赖, 异步接口结果轮询

    Script(JS)为Postman赋予无限可能 基于Postman 6.1.4 Mac Native版 演示结合user_api_demo实现 PS 最近接到任务, 要把几种基本下单接口调试和持续集 ...

  4. 【轮询】【ajax】【js】【spring boot】ajax超时请求:前端轮询处理超时请求解决方案 + spring boot服务设置接口超时时间的设置

    场景描述: ajax设置timeout在本机测试有效,但是在生产环境等外网环境无效的问题 1.ajax的timeout属性设置 前端请求超时事件[网络连接不稳定时候,就无效了] var data = ...

  5. 《连载 | 物联网框架ServerSuperIO教程》- 5.轮询通讯模式开发及注意事项。附:网友制作的类库说明(CHM)

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  6. php和ajax 服务器端做轮询推送(定义)

    基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性. 一.什么是长连接.长轮询? 用通俗易 ...

  7. 如何从线程返回信息——轮询、回调、Callable

    考虑有这样一个LiftOff类: /** * 类LiftOff.java的实现描述:显示发射之前的倒计时 * * @author wql 2016年9月21日 下午1:46:46 */ public ...

  8. 网页实时聊天之js和jQuery实现ajax长轮询

    众所周知,HTTP协议是无状态的,所以一次的请求都是一个单独的事件,和前后都没有联系.所以我们在解决网页实时聊天时就遇到一个问题,如何保证与服务器的长时间联系,从而源源不段地获取信息. 一直以来的方式 ...

  9. Web 通信 之 长连接、长轮询(转)

    Web 通信 之 长连接.长轮询(long polling) 基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强 ...

随机推荐

  1. hdu 1814 字典序最小的2sat(暴力深搜)

    题意:      题意就是最基础的2sat,关系只有矛盾关系,然后二选一,关键是这个题目是输出字典序最小的那组解. 思路:      输出字典序最小,用强连通那个实现不了(起码没看到有人实现),其实我 ...

  2. hdu4662 简单搜索打表

    题意:      给你一个初始串"MI",这个串有三种操作, (1)M后卖弄可以直接复制 ,MI -> MII (2)三个III可以变成一个U,MUIII -> MUU ...

  3. hdu2830 可交换行的最大子矩阵

    题意:       求最大子矩阵,但是相邻的列之间可以相互交换... 思路:       回想下固定的情况,记得那种情况是开俩个数组 L[i] ,R[i],记录小于等于i的最左边和最右边在哪个位置,对 ...

  4. DVWA之Brute Force

    DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...

  5. hdu4901 枚举状态(找集合对S(xor) ==T(and))

    题意:      给你一个串数字,然后让你在这里面挑取两个集合S ,T,集合的要求是 (1)不能为空 (2)S集合的所有元素必须在T集合的左边 (3)S集合的XOR == T集合的AND      问 ...

  6. Xposed学习一:初探

    学习Xposed框架,在github:https://github.com/rovo89 下载XposedInstaller安装到手机上来管理Xposed的模块. 本文记录根据官方文档(资料1)在an ...

  7. Linux-鸟菜-6-文件与目录管理

    Linux-鸟菜-6-文件与目录管理 这章主要是说一些对目录和文件的增删改查等等命令. .    代表当前目录 ..    代表前一个目录   / 的 . 和 .. 一样 -    代表前一个工作目录 ...

  8. 获取InputStream对象的方法

    获取InputStream对象的方法 getResourceAsStream(String path) 默认path路径位于Class所在Module的src目录下 . InputStream is ...

  9. 一、jmeter基础介绍及http请求取样器

    jmeter的下载安装这里不再赘述,百度都有, 1.jmeter是以线程的方式来运行的:2.通过非GUI运行对负载机的资源消耗更小:3.控制机.负载机 安装JDK时jdk路径与jmeter路径避免有中 ...

  10. 一、postman基础