[文章]鸿蒙Harmony系统时钟源码解析

阅读量 0
0
0
一.系统时钟初始化 1.main函数的各种调用,验证参数
kernelliteos_aplatformmain.c->main()
kernelliteos_akernelcommonlos_config.c->OsMain()
kernelliteos_aarcharmarmsrclos_hw_tick.c->OsTickInit()
  1. systemClock //vendor里设置的是50000000
  2. tickPerSecond //鸿蒙默认设置的是100
  3. LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond)
  4. { //只是验证了下传入的这两个参数,并未使用
  5. HalClockInit();
  6. return LOS_OK;
  7. }
复制代码
2.先获取当前时钟频率,注册中断
kernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c
  1. OS_TICK_INT_NUM//中断号,在vendor******boardincludeasmhal_platform_ints.h下定义,查手册确定
  2. MIN_INTERRUPT_PRIORITY//优先级
  3. OsTickEntry//中断函数
  4. LITE_OS_SEC_TEXT_INIT VOID HalClockInit(VOID)
  5. { ...
  6. g_sysClock = HalClockFreqRead(); //先获取当前时钟频率

  7. //调用LOS_HwiCreate函数新建中断,系统中断由它注册
  8. ret = LOS_HwiCreate(OS_TICK_INT_NUM, MIN_INTERRUPT_PRIORITY, 0, OsTickEntry, 0);//参数1:中断号、参数4:执行函数
  9. //这个函数就不深入了,大体就是将中断号好和对应的执行函数放到一个数组
  10. //比如这里就是,当发生OS_TICK_INT_NUM这个中断时,执行OsTickEntry()函数
  11. ...
  12. }
复制代码
二.时钟中断的执行函数OsTickEntry()
kernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c
不过此时这是注册了这个函数,时钟并未启动,得执行了(三.启动时钟)之后才会调用这个函数
  1. LITE_OS_SEC_TEXT VOID OsTickEntry(VOID)
  2. {
  3. TimerCtlWrite(0);
  4. OsTickHandler();
  5. TimerCvalWrite(TimerCvalRead() + OS_CYCLE_PER_TICK);
  6. TimerCtlWrite(1);
  7. //使用最后一个cval生成下一个tick的时间是绝对和准确的。不要使用tval来驱动一般时间,在这种情况下tick会变慢。
  8. }
复制代码
三.启动时钟
main() => OsStart(VOID) => OsTickStart() => HalClockStart(VOID)
kernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c => HalClockStart(VOID)
  1. //树莓派2b没有GIC所以这个函数要爆改
  2. LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID)
  3. {
  4. HalIrqUnmask(OS_TICK_INT_NUM); //wendor里定义的 OS_TICK_INT_NUM = 29
  5. TimerCtlWrite(0);
  6. TimerTvalWrite(OS_CYCLE_PER_TICK);
  7. TimerCtlWrite(1);
  8. }
复制代码
1. HalIrqUnmask; //接收中断(通过设置寄存器,允许CPU响应该中断)
  1. HalIrqUnmask(OS_TICK_INT_NUM);
  2. HalIrqUnmask(29);
  3. GIC_REG_32(GICD_ISENABLER(29 >> 5)) = 1U << (29 % 32);

  4. (GICD_ISENABLER(29 >> 5))拆开
  5. GIC_REG_32(GICD_OFFSET + 0x100 + (29 >> 5) * 4) = 1U << (29 % 32);/* 中断使能 Registers */

  6. GIC_REG_32拆开,(29 % 32)=1D
  7. GIC_BASE_ADDR + (GICD_OFFSET + 0x100 + (29 >> 5) * 4) = 1U << (29 % 32)

  8. #define GIC_BASE_ADDR IO_DEVICE_ADDR(0x3F00A100)
  9. #define GICD_OFFSET 0x1000 /* interrupt distributor offset */
复制代码
2.TimerCtlWrite(0); //关闭Timer
  1. WRITE_TIMER_REG32(TIMER_REG_CTL, 0);

    ARM_SYSREG_WRITE(TIMER_REG_CTL, 0)
  2. ARM_SYSREG_WRITE(TIMER_REG(_CTL), 0)
  3. ARM_SYSREG_WRITE(CP15_REG(c14, 0, c2, 1)), 0)
  4. "mcr " (CP15_REG(c14, 0, c2, 1) :: "r" (val)
  5. 反汇编
  6. r8 0
  7. mcr p15, #0, r8, c14, c2, #1 CNTP_CTL,PL1物理定时器控制寄存器
复制代码
3.TimerTvalWrite(OS_CYCLE_PER_TICK); //设置Tval
  1. 反汇编
  2. r0 192000
  3. mcr p15, #0, r0, c14, c2, #0 CNTP_TVAL,PL1物理时间值寄存器
复制代码
4.TimerCtlWrite(1); //再开启Timer
  1. 反汇编
  2. r5 1
  3. mcr p15, #0, r5, c14, c2, #1 CNTP_CTL,PL1物理定时器控制寄存器
复制代码
代码移植
Z:brightharmony-100askkernelliteos_aplatformhwarminterruptgicgic_v2.c
  1. VOID HalIrqUnmask(UINT32 vector)
  2. {
  3. if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) {
  4. return;
  5. }
  6. //GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32); //替换
  7. *(volatile UINT32 *)((UINTPTR)IO_DEVICE_ADDR(0x3F00B218)) = 1; //使能ARM Timer IRQ

  8. }
复制代码
Z:brightharmony-100askkernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c
  1. STATIC_INLINE VOID TimerCtlWrite(UINT32 cntpCtl)
  2. {
  3. //WRITE_TIMER_REG32(TIMER_REG_CTL, cntpCtl);//替换
  4. if(cntpCtl == 0){
  5. *(volatile UINT32 *)((UINTPTR)IO_DEVICE_ADDR(0x3F00B408)) = 0x003E0000;
  6. }
  7. else
  8. {
  9. *(volatile UINT32 *)((UINTPTR)IO_DEVICE_ADDR(0x3F00B408)) = 0x003E00A2;
  10. }
  11. }
复制代码
Z:brightharmony-100askkernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c
  1. STATIC_INLINE VOID TimerTvalWrite(UINT32 tval)
  2. {
  3. //WRITE_TIMER_REG32(TIMER_REG_TVAL, tval);//替换
  4. *(volatile UINT32 *)((UINTPTR)IO_DEVICE_ADDR(0x3F00B400)) = tval; //设置倒计时时间,鸿蒙是10ms
  5. }
复制代码



回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友