设计ADC驱动:阻塞与非阻塞轮询技术对比
上文探讨了结构良好接口如何将底层驱动细节与应用逻辑分离,提升跨硬件平台可扩展性和可移植性。
本文深入ADC驱动实战实现,聚焦轮询法。对比阻塞与非阻塞设计,展示各自对系统性能的影响。
阻塞 vs 非阻塞驱动
创建微控制器驱动时,开发者须决定API是否阻塞执行直到操作完成。阻塞驱动暂停程序流,确保后续代码仅在任务完成后运行。经典例是UART支持的printf:
printf("Hello World!");
用阻塞UART驱动,此调用后下行代码要等12字节字符串(96位)完全发送才运行。实际延迟取决于波特率:1Mbps约96µs阻塞;9.6kbps拉长至约10ms。
反之,非阻塞驱动启动传输即刻返回控制权给应用。UART可继续处理而数据流出,通常通过中断、DMA或发送缓冲区。此法在延迟敏感场景提效,但增加驱动和应用复杂度。
选择哪模型取决于应用时序需求和硬件配置。高速UART(如1Mbps)下,非阻塞设计开销可能超收益。低速链路(如9.6kbps)下,非阻塞驱动以可控复杂度换取显著性能增益。
ADC驱动架构
强健ADC驱动典型含三层:
- 底层驱动,初始化时接受配置结构体,设置硬件寄存器。
- 应用代码,调用通用HAL函数启动转换、获取结果。
- 配置模块,抽象设备特定参数。
底层驱动提供硬件抽象层(HAL),含简洁可复用API。实战项目示例包括:
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支持直接初始化、转换控制、状态轮询。寄存器访问助手允许开发者扩展HAL实现单通道转换等自定义功能,而不膨胀公共API。
实现简单阻塞ADC驱动
最小阻塞驱动可暴露单个Adc_Sample例程,启动硬件、等待完成、将结果拷贝至调用者提供缓冲区。下文代码演示核心思路:
while循环阻塞直到Adc_ConversionComplete返回真,随后驱动读取转换寄存器存储采样值。
转换为非阻塞ADC驱动
切换非阻塞模型需微调API:调用者现在接收状态标志并须轮询完成。更新后函数可能如下:
应用中典型序列变为:
Adc_Sample(); while (!Adc_ConversionComplete()) { // 执行其他任务 } // 读取结果
此法释放CPU在ADC硬件完成转换时执行无关代码。
要点
阻塞和非阻塞ADC驱动各有优势:
- 阻塞驱动简单、无额外状态管理,但可能阻塞关键路径。
- 非阻塞驱动允许并发执行、提升整体吞吐,但需仔细状态检查、可能更复杂驱动逻辑。
下文将延伸讨论,演示基于中断的ADC驱动,进一步解耦传感器采集与应用逻辑。
嵌入式
- Satellite CCRMA 套件:构建传感器驱动的音频效果器
- 树莓派单 GPIO 引脚读取模拟传感器:RC 充电法实战
- HC‑SR501 PIR 运动传感器与树莓派接线、校准与 Python 编程全指南
- 输送机:破解工程建设卡车司机短缺的智能方案
- Bulgin推出Slimline光电传感器 低成本赋能IIoT集成
- ams 在 2019 传感器博览会展示前沿光学传感技术
- DATA MODUL 扩展触摸传感器系列,新增 LG Innotek 40-86 英寸 PCAP 系统
- Contrinex 2020:云就绪传感器与蓝牙光幕,赋能安全应用
- 集成驱动器简化大功率步进电机设计
- 传感器类型与电路图综合指南
- 模拟与数字传感器:类型、应用与实战案例对比
- 物联网传感器革新空气污染监测与公共健康