与现代传感器的接口:轮询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. 技术面试问题汇总第003篇:猎豹移动反病毒工程师part3

    从现在开始,面试的问题渐渐深入.这次的三个问题,都是对PE格式的不断深入的提问.从最初的概念,到病毒对PE格式的利用,再到最后的壳的问题.这里需要说明的是,由于壳是一个比较复杂的概念,面试中也仅仅只能 ...

  2. Portswigger web security academy:Cross-site request forgery (CSRF)

    Portswigger web security academy:Cross-site request forgery (CSRF) 目录 Portswigger web security acade ...

  3. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

  4. php单列模式和工厂模式

    一.单例模式又称为职责模式,它用来在程序中创建一个单一功能的访问点,通俗地说就是实例化出来的对象是唯一的.所有的单例模式至少拥有以下三种公共元素: 1. 它们必须拥有一个构造函数,并且必须被标记为pr ...

  5. 将mysql数据同步到ES6.4(全量+增量)

    下载安装包时注意下载到指定文件夹 这里我放在OPT文件夹下一:安装logstash进入到opt文件夹打开终端 执行以下命令wget -c https://artifacts.elastic.co/do ...

  6. pass在if中

    pass在if中是停止if成立后的操作. 如 num=1 while num<=100: if num==50: pass        #当作先占位 elif num>=60 and n ...

  7. 移动应用开发 第5讲 Activity课堂综合练习

    作业总要求使用附件"素材"压缩包中的素材完成下列任务: 1.完成小游戏主程序,如图mainActivity.png. 2.在主程序界面当按下游戏介绍按钮时进行游戏介绍界面如图gam ...

  8. 山东浪潮超越3B4000申泰RM5120-L

    龙芯解决方案 首页 > 龙芯业务 > 龙芯解决方案和产品生态 > 整机产品 > 服务器 > 详情 超越申泰RM5120-L 服务器 超越申泰RM5120-L 服务器 20 ...

  9. python 运算及注释

    """ 上面的两行代码,在2.0的python中,若想执行含有汉字的代码,是必不可少的,且两行代码必写在单个py文件最上方,之间不可有任何字节.且该两行代码,可在pych ...

  10. RHEL sosreport

    RHEL sosreport简介 sosreport对很多RedHat爱好者来说应该并不陌生! 它是一款在RedHat Linux下帮你收集系统信息打成一个tar包的工具,你可以将这个tar包发给供应 ...