与现代传感器的接口:轮询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. Docker搭建开发环境(Nginx+MySQL+PHP)

    注意事项 1.像MySQL配置文件.Nginx配置文件.网站根目录这种比较经常操作的需要先使用 docker cp 将文件从容器里复制到主机目录,docker run的时候直接挂载目录就可以了 2.d ...

  2. java 多线程 实现多个线程的顺序执行

    场景 编写一个程序,启动三个线程,三个线程的name分别是A,B,C:,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC... 使用 synchronized 实现 public cla ...

  3. MSSQL·最长输出长度限制之解决方案

    阅文时长 | 0.11分钟 字数统计 | 234.4字符 主要内容 | 1.引言&背景 2.声明与参考资料 原文『MSSQL·最长输出长度限制之解决方案』 编写人 | SCscHero 编写时 ...

  4. 5Spring动态代理开发小结

    5Spring动态代理开发小结 1.为什么要有动态代理? 好处 1.利于程序维护 2.利于原始类功能的增强 3.得益于JDK或者CGlib等动态代理技术使得程序扩展性很强 为什么说使得程序扩展性很强? ...

  5. 网络安全服务(Network Security Services, NSS

    网络安全服务(Network Security Services, NSS)是一套为网络安全服务而设计的库 支持支持安全的客户端和 服务器应用程序.使用NSS构建的应用程序可以支持SSL v2 和v3 ...

  6. CentOS7配置kdump

    CentOS7配置kdump 简单生活,简单爱 2020-10-27 16:29:56  56  收藏 1 分类专栏: Linux实际开发总结 版权 文章目录 1.kdump简介 2.配置kdump ...

  7. 在python的class中的,self到底是什么?

    答案:self可以理解为一个字典变量,内部存的就是对象的数据属性.如:{'name':'zhang','age':'18'}就是这些. 注意只有数据属性,并没有创建新的类的方法.  类-----> ...

  8. Rust模块化

    Rust模块化 模块化有助于代码的管理和层次逻辑的清晰 Rust模块化有多种方式: 1.嵌套模块 嵌套模块就是直接在要使用模块的文件中声明模块 mod food{//声明模块 pub struct C ...

  9. Datatables 实现前端分页处理

    引言 Datatables 是一款 jquery 表格插件.它是一个高度灵活的工具,可以将任何 HTML 表格添加高级的交互功能. 支持分页(包括即时搜索和排序) 支持几乎任何数据源(DOM.java ...

  10. 2.7循环_while

    循环 目标 程序的三大流程 while 循环基本使用 break 和 continue while 循环嵌套 01. 程序的三大流程 在程序开发中,一共有三种流程方式: 顺序 -- 从上向下,顺序执行 ...