Talkweb开发者社区
直播中

拓维信息

3年用户 34经验值
私信 关注
[经验]

OpenHarmony3.1Beta喂狗源码解读之内核态源码

  • 一、喂狗的芯片手册资料
    • 1.概述
    • 2.特点
    • 3.DG 寄存器概览
  • 二、内核态代码分析
    • 1.定义喂狗IO地址
    • 2.代码函数接口分析
      • 设置超时函数代码
      • 喂狗函数代码:
      • 喂狗开始函数
      • 内核接口函数
      • 寄存器的读写
      • watchdog_init函数中创建字符设备接口和接口函数进行注册
      • 内核线程喂狗




一、喂狗的芯片手册资料
1.概述看门狗 WatchDog 用于系统异常情况下,一定时间内发出复位信号,以复位整个系统。系统提供 2 个 WatchDog 模块。

2.特点WatchDog 具备以下特点:
内部具有一个 32bit 减法计数器。
支持超时时间间隔(即计数初值)可配置。
支持寄存器锁定,防止寄存器被误改。
支持超时中断产生。
支持复位信号产生。
支持调试模式

3.DG 寄存器概览

具体详细的内核请查看附件芯片手册






二、内核态代码分析
1.定义喂狗IO地址
  • 代码位置
  1. devicehisiliconhispark_taurussdk_linuxsocsrcinterdrvcommonwtdgarchhi3516cv500hi_wtdg_hal.h
  2. #define HIWDT_BASE      0x12051000    /* define watchdog IO */


2.代码函数接口分析
  • 设置超时函数代码:
  1. static void hidog_set_timeout(unsigned int nr)
  2. {
  3.     unsigned int cnt_0 = ~0x0;
  4.     unsigned int cnt = cnt_0 / g_rate;  /* max cnt */
  5.     unsigned long flags;

  6.     osal_spin_lock_irqsave(&g_hidog_lock, &flags);

  7.     if ((nr == 0) || (nr > cnt)) {
  8.         cnt = ~0x0;
  9.     } else {
  10.         cnt = nr * g_rate;
  11.     }
  12.     /* unlock watchdog registers */
  13.     hiwdt_writel(HIWDT_UNLOCK_VAL, HIWDT_LOCK);
  14.     hiwdt_writel(cnt, HIWDT_LOAD);
  15.     hiwdt_writel(cnt, HIWDT_VALUE);
  16.     /* lock watchdog registers */
  17.     hiwdt_writel(0, HIWDT_LOCK);
  18.     osal_spin_unlock_irqrestore(&g_hidog_lock, &flags);
  19. }


  • 喂狗函数代码:
  1. static void hidog_feed(void)
  2. {
  3.     unsigned long flags;

  4.     /* read the RIS state of current wdg */
  5.     unsigned int v = (unsigned int)hiwdt_readl(HIWDT_RIS);
  6.     v &= 0x1; /* 0x1: get INT bit [1] */
  7.     if (v == 0) { /* no INT on current wdg */
  8.         return;
  9.     }

  10.     osal_spin_lock_irqsave(&g_hidog_lock, &flags);
  11.     /* unlock watchdog registers */
  12.     hiwdt_writel(HIWDT_UNLOCK_VAL, HIWDT_LOCK);
  13.     /* clear watchdog */
  14.     hiwdt_writel(0x00, HIWDT_INTCLR);
  15.     /* lock watchdog registers */
  16.     hiwdt_writel(0, HIWDT_LOCK);
  17.     osal_spin_unlock_irqrestore(&g_hidog_lock, &flags);
  18. }


  • 喂狗开始函数:
  1. static void hidog_start(void)
  2. {
  3.     unsigned long flags;

  4.     osal_spin_lock_irqsave(&g_hidog_lock, &flags);
  5.     /* unlock watchdog registers */
  6.     hiwdt_writel(HIWDT_UNLOCK_VAL, HIWDT_LOCK);
  7.     hiwdt_writel(0x00, HIWDT_CTRL);     /* 0x00: disable watch dog reset signal and interrupt */
  8.     hiwdt_writel(0x00, HIWDT_INTCLR);   /* 0x00: clear interrupt */
  9.     hiwdt_writel(0x03, HIWDT_CTRL);     /* 0x03: enable watch dog reset signal and interrupt */
  10.     /* lock watchdog registers */
  11.     hiwdt_writel(0, HIWDT_LOCK);
  12.     osal_spin_unlock_irqrestore(&g_hidog_lock, &flags);

  13.     g_options = WDIOS_ENABLECARD;
  14. }


  • 内核接口函数:
  1. /* Kernel Interfaces */
  2. static struct osal_fileops g_hidog_fops = {
  3.     .unlocked_ioctl = hidog_ioctl,
  4.     .open           = hidog_open,
  5.     .release        = hidog_release,
  6. };


hidog_open 是用户态句柄代码开始喂狗
hidog_release是用户态停止喂狗,设置喂狗超时时间,并喂一次狗;
hidog_ioctl是设置喂狗参数,获取喂狗参数或者喂狗的函数接口;


  • 寄存器的读写:
  1. g_wtdg_reg_base = (volatile void *)osal_ioremap(HIWDT_BASE, 0x1000); /* 0x1000: watch dog reg length */
  2. #define hiwdt_io_address(x) ((uintptr_t)g_wtdg_reg_base + (x) - HIWDT_BASE)

  3. #define hiwdt_readl(x)       osal_readl(hiwdt_io_address(hiwdt_reg(x)))
  4. #define hiwdt_writel(v, x)   osal_writel(v, hiwdt_io_address(hiwdt_reg(x)))


寄存器的读写是寄存器的物理地址通过ioremap转换成虚拟内存地址再进行读写的,程序退出需要对ioremap的地址进行iounmap。

  • watchdog_init函数中创建字符设备接口和接口函数进行注册:
  1. g_hidog_miscdev = osal_createdev("watchdog");
  2. g_hidog_miscdev->minor = WATCHDOG_MINOR;
  3.     g_hidog_miscdev->fops = &g_hidog_fops;
  4.     if (osal_registerdevice(g_hidog_miscdev) != 0) {


  • 内核线程喂狗
  1. dog = osal_kthread_create(hidog_deamon, NULL, "hidog");



喂狗模块watchdog_init初始化之后开始喂狗,先有内核喂狗,内核是慢喂狗 30.01s喂一次狗;而用户态(watchdog_service 10 2)接管喂狗是重新设置的了超时时间12s,快于内核的喂狗时间,只要用户态设置的时间超过30s那么用户态停止喂狗,将继续有内核态喂狗。

更多回帖

发帖
×
20
完善资料,
赚取积分