与现代传感器的接口:轮询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. 反病毒攻防研究第005篇:简单木马分析与防范part1

    一.前言 病毒与木马技术发展到今天,由于二者总是相辅相成,你中有我,我中有你,所以它们之间的界限往往已经不再那么明显,相互之间往往都会采用对方的一些技术以达到自己的目的,所以现在很多时候也就将二者直接 ...

  2. 从苏宁电器到卡巴斯基第16篇:我在苏宁电器当营业员 VIII

    其实不想走,其实很想留 我在之前的故事中说过,在大四的时候,我其实是想考研的,但是看了一段时间的书以后,发现自己实在不是那块料,主要是数学实在是学不明白,那么也就只能作罢了.而后来面试中石化的时候,尽 ...

  3. POJ2135 来回最短路(简单费用流)

    题意:       就是从1走到n然后再走回来,一条边只能走一次,要求路径最短. 思路:       比较水,可以直接一遍费用流,不解释了,具体的看看代码,敲这个题就是为了练 练手,好久不敲了,怕比赛 ...

  4. WIN64内核编程-的基础知识

    WIN64内核编程基础班(作者:胡文亮)   https://www.dbgpro.com/x64driver 我们先从一份"简历"说起: 姓名:X86或80x86 性别:? 出生 ...

  5. 5.IA-32寄存器

    寄存器(Register)是CPU内部用来存放数据的一些小型存储区域,它与RAM(Random Access Memory,随机存储器.内存)略有不同.CPU访问(Access)RAM中的数据时要经过 ...

  6. 【Git】5. 远程库(GitHub)相关操作

    之前也提到了,在整个协作的过程中,必不可少的就是远程库了.Github作为一个全球最大的同性交友网站,同样也是一个非常强大的远程库. 现在希望将本地的hello.txt文件也推到github上去,那首 ...

  7. 【JavaScript】【KMP】Leetcode每日一题-实现strStr()

    [JavaScript]Leetcode每日一题-实现strStr() [题目描述] 实现 strStr() 函数. 给你两个字符串 haystack 和 needle ,请你在 haystack 字 ...

  8. 使用jenkins一键打包发布vue项目

    jenkins的安装 Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件. Jenkins 支持各种运行方式,可通过系统包.Docker 或者通过一个独立 ...

  9. JDK库rt包中常用包说明

    日常开发中的api都在rt包中,具体路径为:/jdk1.8.0_162/jre/lib中,注意是在jre中. 每个包中大致包含以下几个部分: 接口 类 枚举 异常 错误 注解 J2EE开发中常用的包 ...

  10. 【软工】个人项目作业——个人软件流程(PSP)

    [软工]个人项目作业--个人软件流程(PSP) 项目 内容 班级:北航2020春软件工程 006班(罗杰.任健 周五) 博客园班级博客 作业:设计程序求几何对象的交点集合 个人项目作业 个人课程目标 ...