关键流程设计
初始化流程
RTC 驱动的初始化过程见 aic_rtc_probe() 函数,除了普通 platform 设备的处理过程(申请 regs 资源、clk、reset)外,需要调用 RTC 子系统的接口 rtc_register_device() 来注册 RTC 设备。
#define rtc_register_device(device) __rtc_register_device(THIS_MODULE, device)
static const struct rtc_class_ops aic_rtc_ops = {
.read_time = aic_rtc_read_time,
.set_time = aic_rtc_set_time,
.read_alarm = aic_rtc_read_alarm,
.set_alarm = aic_rtc_set_alarm,
.alarm_irq_enable = aic_rtc_alarm_irq_enable,
};
校准算法设计
(100 * 1024 * 1024 + 100 * calibrate) / (clock-rate / 32) = 1024
=> calibrate = (clock-rate * 32 - 100 * 1024 * 1024) / 100;
其中:
-
clock-rate: 是用户实测 32K 晶振的频率值 * 100,需要配置在 DTS 中,详见 RTC 自定义参数
-
calibrate: 最终要填入 RTC 控制器的校准值
注:校准值 calibrate 分正负,正 - 表示 32K 晶振实际偏快了,负 - 表示 32K 晶振偏慢了。
系统状态的备份功能
RTC 控制器提供了 128-bit 备份寄存器 SYS_BAK,用于掉电时一些重要状态或者参数的保存。RTC 驱动将这几个寄存器封装为对外接口(
EXPORT_SYMBOL_GPL()
的形式),Linux 中其他驱动都可以调用。
Reboot Reason 的设计
将系统状态的备份功能 中 系统备份寄存器 保存不同情况的 Reboot reason,可用于分析终端运行稳定性问题、进入快速启动模式等场景。
SYS_BAK 寄存器需要和 WRI 模块一起配合来完成 reason 的处理:
- WRI
负责记录 硬件可监测 到的 Reboot 原因,如过温保护、看门狗复位、外部输入复位等。
- SYS_BAK
负责记录 软件可监测 到的 Reboot 原因,如 Suspend、Panic、进入烧写模式、正常重启等。
关于 Reboot 原因,梳理分类如下:
其中“外部 IO 复位”指常用的 Reset 按键。
enum aic_reboot_reason {
REBOOT_REASON_COLD = 0,
REBOOT_REASON_CMD_REBOOT = 1,
REBOOT_REASON_CMD_SHUTDOWN = 2,
REBOOT_REASON_SUSPEND = 3,
REBOOT_REASON_UPGRADE = 4,
REBOOT_REASON_FASTBOOT = 5,
/* Some software exception reason */
REBOOT_REASON_SW_LOCKUP = 8,
REBOOT_REASON_HW_LOCKUP = 9,
REBOOT_REASON_PANIC = 10,
REBOOT_REASON_RAMDUMP = 11,
/* Some hardware exception reason */
REBOOT_REASON_RTC = 17,
REBOOT_REASON_EXTEND = 18,
REBOOT_REASON_DM = 19,
REBOOT_REASON_OTP = 20,
REBOOT_REASON_UNDER_VOL = 21,
};
针对不同场景,SYS_BAK0 寄存器中的 reason 和 WRI 中的 FLAG 值对应如下:
场景 | 触发行为 | WRI 状态 | SYS_BAK 状态值 |
---|---|---|---|
正常重启 |
按 Reset 按键 | EXT_RST | COLD |
shell 中执行 reboot 命令 | WDOG_RST | CMD_REBOOT | |
shell 执行 aicupg 命令进入烧写 | WDOG_RST | UPGRADE | |
正常关机 |
长按 PowerOn 按键 | SYS_POR | COLD |
shell 中执行 poweroff 命令 | SYS_POR | CMD_SHUTDOWN | |
进入深度休眠状态 | SYS_POR | SUSPEND | |
异常重启 |
过温保护 | OTP | COLD |
通过 Jtag 执行 reset 命令 | DM_RST | COLD | |
RTC 模块断电 | RTC_POR | COLD | |
内核中发生 SW Lock | WDOG_RST | SW_LOCKUP | |
内核中发生 HW Lock | WDOG_RST | HW_LOCKUP | |
内核中发生 Panic | WDOG_RST | PANIC | |
内核中触发进入 Ramdump | WDOG_RST | RAMDUMP | |
电源电压不稳定 | CMP_RST | COLD |
其中按 Reset 按键的情况,因为软件来不及设置 BAK,所以是初始值 0 (COLD)。