从零构建RK3588定时器驱动:设备树、中断与工作队列实战解析

从零构建RK3588定时器驱动:设备树、中断与工作队列实战解析

在嵌入式Linux开发中,定时器驱动是连接硬件与操作系统的关键桥梁。RK3588作为一款高性能处理器,其内置的硬件定时器为系统提供了精确的时间基准。本文将深入探讨如何从零开始构建一个完整的RK3588定时器驱动,涵盖设备树配置、寄存器操作、中断处理以及工作队列机制,帮助开发者深入理解硬件定时器驱动的实现原理。

1. RK3588定时器硬件架构解析

RK3588的定时器子系统包含三种不同类型的定时器:普通递减计数TIMER、普通递增计数TIMER和特殊功能递增计数TIMER。普通定时器共有12个通道,Linux内核通常只使用其中1个通道,其余11个通道可供开发者使用。

每个定时器通道都包含以下关键寄存器:

  • TIMER_LOAD_COUNT0/1: 加载计数值寄存器(64位,分为高低32位)
  • TIMER_CURRENT_VALUE0/1: 当前计数值寄存器
  • TIMER_CONTROL_REG: 控制寄存器
  • TIMER_INT_STATUS: 中断状态寄存器

定时器的工作频率为24MHz,这意味着每秒可以计数24,000,000次。通过设置合适的计数值,可以实现从微秒到秒级别的精确定时。

#define TIMER_LOAD_COUNT0   0x00
#define TIMER_LOAD_COUNT1   0x04
#define TIMER_CURRENT_VALUE0 0x08
#define TIMER_CURRENT_VALUE1 0x0C
#define TIMER_CONTROL_REG   0x10
#define TIMER_INT_STATUS    0x18

#define TIMER_DISABLE       0x0
#define TIMER_ENABLE        0x1
#define TIMER_IRQ_ENABLE    0x4
#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
#define TIMER_INT_UNMASK    (1 << 2)

2. 设备树节点配置与地址映射

设备树是Linux内核中描述硬件资源的重要机制。对于RK3588定时器,我们需要在设备树中添加相应的节点来声明硬件资源。

2.1 基地址与中断分析

通过查阅RK3588编程手册,普通定时器的寄存器基地址为0xFEAE0000。每个定时器通道占用32字节空间,通道0-5的控制寄存器映射到该基地址上。

定时器通道1的中断号为322(GIC_SPI 290)。为了避免与系统原有定时器驱动冲突,我们需要使用自定义的compatible属性。

2.2 设备树节点实现

arch/arm64/boot/dts/rockchip/rk3588s.dtsi中添加以下节点:

timer@0xfeae0020 {
    compatible = "rk3588-timer";
    reg = <0x0 0xfeae0020 0x0 0x20>;
    interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER1>;
    clock-names = "pclk", "timer";
};

这个节点定义了:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值