0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深入解析RK3576平台U-Boot下ADC驱动实现|从架构到实战

jf_44130326 来源:Linux1024 作者:Linux1024 2026-04-26 07:08 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式开发中,ADC模拟数字转换器)堪称“模拟世界与数字世界的桥梁”——电池电压检测、温度采集、按键识别,几乎所有需要感知物理量的场景都离不开它。

今天我们就聚焦RK3576平台,从驱动架构、核心代码、实战使用三个维度,彻底讲透U-Boot下ADC驱动的实现逻辑,无论是调试ADC功能,还是定制化开发,看完这篇都能落地!

一、先搞懂:RK3576 ADC驱动的整体架构

RK3576的ADC驱动基于U-Boot的Driver Model(DM)框架设计,核心是“通用框架+芯片专属驱动”的分层思路,既保证了接口统一,又适配了硬件特性。

1.1核心文件结构

整个驱动的代码都集中在u-boot/drivers/adc/目录下,关键文件就这几个:

u-boot/drivers/adc/├── adc-uclass.c     # ADC通用框架(提供统一API,上层调用不用管底层差异)├── rockchip-saradc-v2.c # RK3576专属驱动(新版SARADC v2,重点分析这个)├── rockchip-saradc.c  # 旧版驱动(适配老芯片,RK3576不用)├── Kconfig       # 驱动编译配置└── Makefile       # 编译规则

1.2核心分层逻辑

•上层:ADC通用框架(adc-uclass.c)提供标准化API(比如启动转换、读取数据),开发者只用调用这些接口,不用关心底层硬件;

•下层:rockchip-saradc-v2.c处理RK3576 ADC的硬件细节(寄存器操作、时钟/复位配置、时序控制)。

二、核心代码拆解:读懂驱动的“底层逻辑”

想要定制ADC驱动,核心是搞懂3个关键部分:寄存器定义、驱动初始化、转换与数据读取。

2.1先认识:新版SARADC v2的寄存器

RK3576的SARADC v2寄存器结构更完善,覆盖了转换控制、时序配置、中断、数据存储等全流程,核心寄存器如下(挑关键的讲):

structrockchip_saradc_regs {  u32 conv_con;   // 转换控制(启动转换、选择通道、模式)  u32 t_pd_soc;   // 上电延时(配置ADC上电后的稳定时间)  u32 t_das_soc;   // 数据采集时间(决定采样精度)  u32 end_int_en;  // 转换结束中断使能(判断转换是否完成)  u32 status;    // ADC状态寄存器  u32 data0-15;   // 16通道数据寄存器(转换结果存在这里)};

2.2驱动初始化:probe函数

驱动加载时首先执行probe函数,核心是完成“时钟+复位”的初始化,为ADC工作做准备:

staticintrockchip_saradc_probe(structudevice *dev){ structrockchip_saradc_priv *priv = dev_get_priv(dev); structclk clk; intret; // 1. 获取复位控制(后续复位ADC用)  ret = reset_get_by_name(dev,"saradc-apb", &priv->rst); // 2. 获取并配置时钟(设置ADC工作时钟频率)  ret = clk_get_by_index(dev,0, &clk);  ret = clk_set_rate(&clk, priv->data->clk_rate); // 3. 等待PLL稳定(硬件要求,避免时钟不稳导致采样错误)  mdelay(5);  priv->active_channel =-1;// 初始化当前激活通道为-1(无激活) return0;}

核心逻辑:ADC工作前必须先配置时钟(保证时序稳定),获取复位控制(后续启动转换前复位ADC)。

2.3启动通道转换:开始采样

想要读取某个通道的ADC值,第一步是启动该通道的转换,核心函数rockchip_saradc_start_channel:

static int rockchip_saradc_start_channel(struct udevice *dev, int channel){  struct rockchip_saradc_priv *priv = dev_get_priv(dev);  intval; // 1. 检查通道是否有效(RK3576最多支持8个通道) if(channel < 0 || channel >= priv->data->num_channels) {    pr_err("Requested channel is invalid!");   return-EINVAL;  } // 2. 复位ADC(保证每次转换的初始状态一致)  reset_assert(&priv->rst);  udelay(10);  reset_deassert(&priv->rst); // 3. 配置时序参数(上电延时、数据采集时间)  writel(0x20, &priv->regs->t_pd_soc);  writel(0xc, &priv->regs->t_das_soc); // 4. 使能转换结束中断(方便判断转换完成) val= SARADC2_EN_END_INT << 16 | SARADC2_EN_END_INT;    writel(val, &priv->regs->end_int_en); // 5. 启动单次转换(选择通道+单次模式+启动) val= SARADC2_START | SARADC2_SINGLE_MODE | channel;  writel(val<< 16 | val, &priv->regs->conv_con);  udelay(100);  priv->active_channel = channel;// 标记当前激活通道 return0;}

核心逻辑:先复位清状态→配置时序(保证采样精度)→使能中断→启动单次转换,每一步都是为了让ADC稳定输出数据。

2.4读取转换数据:拿到最终值

启动转换后,通过rockchip_saradc_channel_data读取数据,核心是“等中断+读寄存器+清标志”:

staticintrockchip_saradc_channel_data(structudevice *dev,intchannel,                   unsignedint*data){ structrockchip_saradc_priv*priv =dev_get_priv(dev);  u32 status; // 1. 检查通道是否匹配(只能读当前激活的通道) if(channel != priv->active_channel) {   pr_err("Requested channel is not active!");   return-EINVAL;  } // 2. 等待转换完成(超时则返回错误) if(readl_poll_timeout(&priv->regs->end_int_st, status,             status & SARADC2_EN_END_INT, SARADC_TIMEOUT)) {   pr_err("Wait for end conversion interrupt status timeout!n");   return-ETIMEDOUT;  } // 3. 清除中断标志(避免影响下一次转换) writel(0x1, &priv->regs->end_int_st); // 4. 读取数据并应用掩码(RK3576是12位精度,掩码过滤无效位)  *data =readl(&priv->regs->data0 + priv->active_channel);  *data &= uc_pdata->data_mask; return0;}

三、一张图看懂:ADC完整工作流程

把上面的代码逻辑串起来,RK3576 ADC的工作流程可以总结为这张图,一目了然:

wKgZO2ntScmAbDYPAACu_SSLfUo205.png

四、设备树配置:硬件参数的“入口”

RK3576的ADC硬件参数都定义在设备树arch/arm/dts/rk3576.dtsi里,核心配置如下,改参数不用动驱动,改设备树即可:

saradc: adc@2ae00000{  compatible ="rockchip,rk3576-saradc","rockchip,rk3588-saradc";  reg = <0x0 0x2ae00000 0x0 0x10000>;//寄存器基地址  interrupts = ;//中断号 #io-channel-cells = <1>;  clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;//时钟源  clock-names ="saradc","apb_pclk";  resets = <&cru SRST_P_SARADC>;//复位控制 reset-names ="saradc-apb";  status ="disabled";//默认禁用,启用改"okay"};

关键参数解读

•compatible:驱动匹配标识(RK3576复用RK3588的驱动);

•reg:ADC寄存器的物理基地址,驱动通过这个地址操作硬件;

•clocks:ADC的工作时钟和APB时钟,决定采样速率;

•resets:复位控制器,驱动通过它复位ADC模块。

五、实战:U-Boot中如何读取ADC值

驱动最终是为了用,U-Boot提供了通用API,几行代码就能读取ADC值,还能转换成实际电压:

unsignedintadc_value;intret;//读取通道0的ADC值(设备名对应设备树里的saradc@2ae00000)ret = adc_channel_single_shot("saradc@2ae00000",0, &adc_value);if(ret) { printf("ADC read failed:%dn", ret);}else{ printf("ADC value:%dn", adc_value); //转换为电压(12位精度,参考电压1.8V → 1LSB =1.8V/4095≈0.439mV) intvoltage = (adc_value *1800) /4095; printf("Voltage:%dmVn", voltage);}

六、新旧版本对比:为什么RK3576用v2版驱动?

RK3576弃用旧版rockchip-saradc.c,改用rockchip-saradc-v2.c,核心是v2版功能更强大:

特性 旧版(rockchip-saradc.c) 新版(rockchip-saradc-v2.c)
通道数 最多6个 最多8个
精度 10/12位 12位(固定,精度更高)
中断支持 基本(仅转换结束) 完整(高低阈值、中阈值等)
复位控制 有(每次转换复位,稳定性更高)
支持芯片 RK3066/RK3399等老芯片 RK3562/RK3576/RK3588等新芯片

七、总结

RK3576的ADC驱动设计,完美体现了U-Boot DM框架的核心思想:分层解耦

•通用框架层:屏蔽硬件差异,提供统一API,上层应用不用改;

•硬件驱动层:专注处理RK3576的硬件细节(寄存器、时钟、复位),适配新芯片只需改这层;

这种设计不仅让代码易维护、易扩展,也给我们开发带来启示:嵌入式驱动开发,优先复用框架,聚焦硬件差异即可。

如果你的项目中需要调试RK3576的ADC功能,比如电池检测、温度采集,不妨从这篇文章的思路入手——先看架构,再拆代码,最后结合设备树和实战示例,问题往往能迎刃而解。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • adc
    adc
    +关注

    关注

    100

    文章

    7950

    浏览量

    556931
  • u-boot
    +关注

    关注

    0

    文章

    140

    浏览量

    39955
  • rk3576
    +关注

    关注

    1

    文章

    304

    浏览量

    1678
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    吃透RK3576 U-Boot.map文件!嵌入式开发调试、性能优化、代码裁剪全攻略

    “宝藏文件”,解锁调试、分析、优化的全套实战技巧。 一、U-Boot.map 是什么? U-Boot.map 是 U-Boot 编译链接阶段生成的内存布局映射文件,记录了可执行文件在内
    的头像 发表于 04-27 07:11 475次阅读
    吃透<b class='flag-5'>RK3576</b> <b class='flag-5'>U-Boot</b>.map文件!嵌入式开发调试、性能优化、代码裁剪全攻略

    深度解析 RK 平台 U-Boot 环境变量(env):原理、配置与实战

    环境变量(env)是 U-Boot 的核心配置机制,无需重新编译即可灵活调整启动参数。在 Rockchip(RK平台上,环境变量不仅继承了 U-Boot 的通用特性,还针对 
    的头像 发表于 04-27 07:11 486次阅读
    深度<b class='flag-5'>解析</b> <b class='flag-5'>RK</b> <b class='flag-5'>平台</b> <b class='flag-5'>U-Boot</b> 环境变量(env):原理、配置与<b class='flag-5'>实战</b>

    深度剖析U-Boot ADC Uclass:架构实战的全维度解析

    、数据流到实战开发,全方位拆解 U-Boot ADC Uclass 的设计精髓,帮你吃透这一核心子系统。 一、架构概览:三层架构,职责分明
    的头像 发表于 04-26 07:08 22次阅读
    深度剖析<b class='flag-5'>U-Boot</b> <b class='flag-5'>ADC</b> Uclass:<b class='flag-5'>从</b><b class='flag-5'>架构</b><b class='flag-5'>到</b><b class='flag-5'>实战</b>的全维度<b class='flag-5'>解析</b>

    【硬核拆解】“芯”开始,一工业级迅为RK3576开发板的自我修养

    【硬核拆解】“芯”开始,一工业级迅为RK3576开发板的自我修养
    的头像 发表于 03-02 15:43 486次阅读
    【硬核拆解】<b class='flag-5'>从</b>“芯”开始,一<b class='flag-5'>台</b>工业级迅为<b class='flag-5'>RK3576</b>开发板的自我修养

    深入解析U-Boot image.c:RK平台镜像处理核心逻辑

    在瑞芯微(RK平台的嵌入式开发中,U-Boot作为核心的启动加载程序,负责完成镜像解析、校验、加载等关键流程。而image.c正是U-Boot
    的头像 发表于 02-24 16:46 1822次阅读
    <b class='flag-5'>深入</b><b class='flag-5'>解析</b><b class='flag-5'>U-Boot</b> image.c:<b class='flag-5'>RK</b><b class='flag-5'>平台</b>镜像处理核心逻辑

    基于米尔RK3576的环视实时性方案解析

    MYD-LR3576开发板功能实现: 基于米尔MYD-LR3576开发板的RK3576平台完全具备实现
    发表于 11-28 16:57

    深入理解 RK3506 U-Boot 重定位:代码原理

    的启动代码,拆解 RK3506 平台 U-Boot 重定位的实现逻辑、关键步骤与底层原理。 路径:u-boot/arch/arm/cpu/a
    的头像 发表于 11-28 07:05 1011次阅读
    <b class='flag-5'>深入</b>理解 <b class='flag-5'>RK</b>3506 <b class='flag-5'>U-Boot</b> 重定位:<b class='flag-5'>从</b>代码<b class='flag-5'>到</b>原理

    迅为如何在RK3576上部署YOLOv5;基于RK3576构建智能门禁系统

    迅为如何在RK3576开发板上部署YOLOv5;基于RK3576构建智能门禁系统
    的头像 发表于 11-25 14:06 1979次阅读
    迅为如何在<b class='flag-5'>RK3576</b>上部署YOLOv5;基于<b class='flag-5'>RK3576</b>构建智能门禁系统

    RK3576驱动高端显控系统升级:多屏拼控与AI视觉融合解决方案

    系统依赖多工控主机、外接显卡和解码器,存在功耗高、延迟大的问题。而瑞芯微 RK3576 打造的新一代 AI 多媒体平台,凭借 “三屏异显 + 八路摄像头输入 + AI 边缘计算” 的架构,全面提升高端显
    发表于 11-21 17:51

    360环视硬件平台为什么推荐使用米尔RK3576开发板?

    实现低延迟显示与存储。然而,传统硬件平台在接入路数、实时性与稳定性方面常有瓶颈,难以支撑更大规模、更高质量的视频处理场景。为此,越来越多的企业在构建360环视硬件平台时选择 米尔RK3576
    发表于 09-19 17:38

    【作品合集】米尔RK3576开发板测评

    测试 作者:鲁治驿【米尔RK3576开发板免费体验】测评综合解析 【米尔RK3576开发板免费体验】集成MQ-2烟雾传感器和ADS1263模块实现气体监测 【米尔
    发表于 09-11 10:19

    瑞芯微RK3576平台FFmpeg硬件编解码移植及性能测试实战攻略 触觉智能RK3576开发板演示

    本文介绍瑞芯微RK3576平台,FFmpeg硬件编解码移植及性能测试方法。演示设备:触觉智能RK3576开发板FFmpeg简介与实测数据FFmpeg简介FFmpeg是一套多媒体框架,能够解码、编码
    的头像 发表于 09-08 13:58 1514次阅读
    瑞芯微<b class='flag-5'>RK3576</b><b class='flag-5'>平台</b>FFmpeg硬件编解码移植及性能测试<b class='flag-5'>实战</b>攻略 触觉智能<b class='flag-5'>RK3576</b>开发板演示

    瑞芯微RK3576RK3576S有什么区别,性能参数配置与型号差异解析

    瑞芯微第二代8nm高性能AIOT平台RK3576家族再添新成员-RK3576S,先说结论:相较主型号的RK3576/RK3576J,性能略有
    的头像 发表于 08-14 23:57 2738次阅读
    瑞芯微<b class='flag-5'>RK3576</b>与<b class='flag-5'>RK3576</b>S有什么区别,性能参数配置与型号差异<b class='flag-5'>解析</b>

    RK3576 vs RK3588:为何越来越多的开发者转向RK3576

    (图形性能更强) 分析: RK3576 的 A72+A53+M0 组合 在能效比上更优,适合需要长时间运行的设备(如 IoT、平板)。 RK3588 的 A76 架构 单核性能更强,适合高性能计算场景(如
    发表于 05-30 08:46

    RK3576 Android 14.0 SDK开发指南(第一集)

    对应的boot.img及dts: 其中 BOOT_IMG=../rockdev/Image-rk3576_u/boot.img 这里指定的是旧的bo
    发表于 05-20 08:43