Edit online

关键流程设计

26 Nov 2024
Read time: 2 minute(s)

校准算法设计

校准的算法原理是,将输入的 32 KHz 晶振时钟校准到理想的 32 KHz,公式如下:
(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 的处理:

  1. WRI

    负责记录 硬件可监测 到的 Reboot 原因,如过温保护、看门狗复位、外部输入复位等。

  2. SYS_BAK

    负责记录 软件可监测 到的 Reboot 原因,如 Suspend、Panic、进入烧写模式、正常重启等。

关于 Reboot 原因,梳理分类如下:


reboot_reason

1. 各种情况的 reason 梳理
提示:

其中“外部 IO 复位”指常用的 Reset 按键。

定义 SYS_BAK0 寄存器(4~7bit) 的值如下:(详见 include/linux/reboot-reason.h)
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_RSTCOLD
shell 中执行 reboot 命令WDOG_RSTCMD_REBOOT
shell 执行 aicupg 命令进入烧写WDOG_RSTUPGRADE

正常关机

长按 PowerOn 按键SYS_PORCOLD
shell 中执行 poweroff 命令SYS_PORCMD_SHUTDOWN
进入深度休眠状态SYS_PORSUSPEND

异常重启

过温保护OTPCOLD
通过 Jtag 执行 reset 命令DM_RSTCOLD
RTC 模块断电RTC_PORCOLD
内核中发生 SW LockWDOG_RSTSW_LOCKUP
内核中发生 HW LockWDOG_RSTHW_LOCKUP
内核中发生 PanicWDOG_RSTPANIC
内核中触发进入 RamdumpWDOG_RSTRAMDUMP
电源电压不稳定CMP_RSTCOLD
注:

其中按 Reset 按键的情况,因为软件来不及设置 BAK,所以是初始值 0 (COLD)。