|

鸿蒙Harmony系统时钟源码解析,
一.系统时钟初始化
1.main函数的各种调用,验证参数 kernel\liteos_a\platform\main.c->main() kernel\liteos_a\kernel\common\los_config.c->OsMain() kernel\liteos_a\arch\arm\arm\src\los_hw_tick.c->OsTickInit()
- <span role=“presentation“><span class=“cm-variable“>systemclock</span><span class=“cm-tab“ role=“presentation“ cm-text=“ “> </span><span class=“cm-tab“ role=“presentation“ cm-text=“ “> </span><span class=“cm-comment“>//vendor里设置的是50000000</span></span>
- <span role=“presentation“><span class=“cm-variable“>tickPerSecond</span><span class=“cm-tab“ role=“presentation“ cm-text=“ “> </span><span class=“cm-comment“>//鸿蒙默认设置的是100</span></span>
- <span role=“presentation“><span class=“cm-variable“>LITE_OS_SEC_TEXT_INIT</span> <span class=“cm-variable“>UINT32</span> <span class=“cm-def“>OsTickInit</span>(<span class=“cm-variable“>UINT32</span> <span class=“cm-variable“>systemClock</span>, <span class=“cm-variable“>UINT32</span> <span class=“cm-variable“>tickPerSecond</span>)</span>
- <span role=“presentation“>{ <span class=“cm-comment“>//只是验证了下传入的这两个参数,并未使用</span></span>
- <span role=“presentation“> <span class=“cm-variable“>HalClockInit</span>();</span>
- <span role=“presentation“> <span class=“cm-keyword“>return</span> <span class=“cm-variable“>LOS_OK</span>;</span>
- <span role=“presentation“>}</span>
复制代码
2.先获取当前时钟频率,注册中断 kernel\liteos_a\platform\hw\arm\timer\arm_generic\arm_generic_timer.c
- <span role=“presentation“><span class=“cm-variable“>OS_TICK_INT_NUM</span><span class=“cm-comment“>//中断号,在vendor\***\***\board\include\asm\hal_platform_ints.h下定义,查手册确定</span></span>
- <span role=“presentation“><span class=“cm-variable“>MIN_INTERRUPT_PRIORITY</span><span class=“cm-comment“>//优先级</span></span>
- <span role=“presentation“><span class=“cm-variable“>OsTickEntry</span><span class=“cm-comment“>//中断函数</span></span>
- <span role=“presentation“><span class=“cm-variable“>LITE_OS_SEC_TEXT_INIT</span> <span class=“cm-variable“>VOID</span> <span class=“cm-def“>HalClockInit</span>(<span class=“cm-variable“>VOID</span>)</span>
- <span role=“presentation“>{ ...</span>
- <span role=“presentation“> <span class=“cm-variable“>g_sysClock</span> <span class=“cm-operator“>=</span> <span class=“cm-variable“>HalClockFreqRead</span>(); <span class=“cm-comment“>//先获取当前时钟频率</span></span>
- <span role=“presentation“> </span>
- <span role=“presentation“><span class=“cm-tab“ role=“presentation“ cm-text=“ “> </span><span class=“cm-comment“>//调用LOS_HwiCreate函数新建中断,系统中断由它注册</span></span>
- <span role=“presentation“> <span class=“cm-variable“>ret</span> <span class=“cm-operator“>=</span> <span class=“cm-variable“>LOS_HwiCreate</span>(<span class=“cm-variable“>OS_TICK_INT_NUM</span>, <span class=“cm-variable“>MIN_INTERRUPT_PRIORITY</span>, <span class=“cm-number“>0</span>, <span class=“cm-variable“>OsTickEntry</span>, <span class=“cm-number“>0</span>);<span class=“cm-comment“>//参数1:中断号、参数4:执行函数</span></span>
- <span role=“presentation“> <span class=“cm-comment“>//这个函数就不深入了,大体就是将中断号好和对应的执行函数放到一个数组</span></span>
- <span role=“presentation“> <span class=“cm-comment“>//比如这里就是,当发生OS_TICK_INT_NUM这个中断时,执行OsTickEntry()函数</span></span>
- <span role=“presentation“> ...</span>
- <span role=“presentation“>}</span>
复制代码
二.时钟中断的执行函数OsTickEntry() kernel\liteos_a\platform\hw\arm\timer\arm_generic\arm_generic_timer.c 不过此时这是注册了这个函数,时钟并未启动,得执行了(三.启动时钟)之后才会调用这个函数
- <span role=“presentation“><span class=“cm-variable“>LITE_OS_SEC_TEXT</span> <span class=“cm-variable“>VOID</span> <span class=“cm-def“>OsTickEntry</span>(<span class=“cm-variable“>VOID</span>)</span>
- <span role=“presentation“>{</span>
- <span role=“presentation“> <span class=“cm-variable“>TimerCtlWrite</span>(<span class=“cm-number“>0</span>);</span>
- <span role=“presentation“> <span class=“cm-variable“>OsTickHandler</span>();</span>
- <span role=“presentation“> <span class=“cm-variable“>TimerCvalWrite</span>(<span class=“cm-variable“>TimerCvalRead</span>() <span class=“cm-operator“>+</span> <span class=“cm-variable“>OS_CYCLE_PER_TICK</span>);</span>
- <span role=“presentation“> <span class=“cm-variable“>TimerCtlWrite</span>(<span class=“cm-number“>1</span>);</span>
- <span role=“presentation“> <span class=“cm-comment“>//使用最后一个cval生成下一个tick的时间是绝对和准确的。不要使用tval来驱动一般时间,在这种情况下tick会变慢。</span></span>
- <span role=“presentation“>}</span>
复制代码
三.启动时钟 main() => OsStart(VOID) => OsTickStart() => HalClockStart(VOID) kernel\liteos_a\platform\hw\arm\timer\arm_generic\arm_generic_timer.c => HalClockStart(VOID)
- <span role=“presentation“><span class=“cm-comment“>//树莓派2b没有GIC所以这个函数要爆改</span></span>
- <span role=“presentation“><span class=“cm-variable“>LITE_OS_SEC_TEXT_INIT</span> <span class=“cm-variable“>VOID</span> <span class=“cm-def“>HalClockStart</span>(<span class=“cm-variable“>VOID</span>)</span>
- <span role=“presentation“>{</span>
- <span role=“presentation“> <span class=“cm-variable“>HalIrqUnmask</span>(<span class=“cm-variable“>OS_TICK_INT_NUM</span>); <span class=“cm-comment“>//wendor里定义的 OS_TICK_INT_NUM = 29</span></span>
- <span role=“presentation“> <span class=“cm-variable“>TimerCtlWrite</span>(<span class=“cm-number“>0</span>);</span>
- <span role=“presentation“> <span class=“cm-variable“>TimerTvalWrite</span>(<span class=“cm-variable“>OS_CYCLE_PER_TICK</span>);</span>
- <span role=“presentation“> <span class=“cm-variable“>TimerCtlWrite</span>(<span class=“cm-number“>1</span>);</span>
- <span role=“presentation“>}</span>
复制代码
1. HalIrqUnmask; //接收中断(通过设置寄存器,允许CPU响应该中断)
- <span role=“presentation“>HalIrqUnmask(OS_TICK_INT_NUM);</span>
- <span role=“presentation“>HalIrqUnmask(29);</span>
- <span role=“presentation“>GIC_REG_32(GICD_ISENABLER(29 >> 5)) = 1U << (29 % 32);</span>
- <span role=“presentation“><span cm-text=““>
|
|