一.系统时钟初始化1.main函数的各种调用,验证参数kernelliteos_aplatformmain.c->main()
kernelliteos_akernelcommonlos_config.c->OsMain()
kernelliteos_aarcharmarmsrclos_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.先获取当前时钟频率,注册中断kernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c
- <span role="presentation"><span class="cm-variable">OS_TICK_INT_NUM</span><span class="cm-comment">//中断号,在vendor******boardincludeasmhal_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()kernelliteos_aplatformhwarmtimerarm_genericarm_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)
kernelliteos_aplatformhwarmtimerarm_genericarm_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=""></span></span>
- <span role="presentation">(GICD_ISENABLER(29 >> 5))拆开</span>
- <span role="presentation">GIC_REG_32(GICD_OFFSET + 0x100 + (29 >> 5) * 4) = 1U << (29 % 32);/* 中断使能 Registers */</span>
- <span role="presentation"><span cm-text=""></span></span>
- <span role="presentation">GIC_REG_32拆开,(29 % 32)=1D</span>
- <span role="presentation">GIC_BASE_ADDR + (GICD_OFFSET + 0x100 + (29 >> 5) * 4) = 1U << (29 % 32)</span>
- <span role="presentation"><span cm-text=""></span></span>
- <span role="presentation">#define GIC_BASE_ADDR IO_DEVICE_ADDR(0x3F00A100)</span>
- <span role="presentation">#define GICD_OFFSET 0x1000 /* interrupt distributor offset */</span>
复制代码 2.TimerCtlWrite(0); //关闭Timer- <p cid="n55" mdtype="paragraph" class="md-end-block md-p">WRITE_TIMER_REG32(TIMER_REG_CTL, 0);</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n57" mdtype="fences"><span role="presentation">ARM_SYSREG_WRITE(TIMER_REG_CTL, 0)</span>
- <span role="presentation">ARM_SYSREG_WRITE(TIMER_REG(_CTL), 0)</span>
- <span role="presentation">ARM_SYSREG_WRITE(CP15_REG(c14, 0, c2, 1)), 0)</span>
- <span role="presentation">"mcr " (CP15_REG(c14, 0, c2, 1) :: "r" (val)</span>
- <span role="presentation">反汇编</span>
- <span role="presentation">r8 0</span>
- <span role="presentation">mcr<span class="cm-tab" role="presentation" cm-text=" "> </span>p15, #0, r8, c14, c2, #1<span class="cm-tab" role="presentation" cm-text=" "> </span>CNTP_CTL,PL1物理定时器控制寄存器</span></pre>
复制代码3.TimerTvalWrite(OS_CYCLE_PER_TICK); //设置Tval
- <span role="presentation">反汇编</span>
- <span role="presentation">r0 192000</span>
- <span role="presentation">mcr<span class="cm-tab" role="presentation" cm-text=" "> </span>p15, #0, r0, c14, c2, #0<span class="cm-tab" role="presentation" cm-text=" "> </span>CNTP_TVAL,PL1物理时间值寄存器</span>
复制代码 4.TimerCtlWrite(1); //再开启Timer- <span role="presentation">反汇编</span>
- <span role="presentation">r5 1</span>
- <span role="presentation">mcr<span class="cm-tab" role="presentation" cm-text=" "> </span>p15, #0, r5, c14, c2, #1<span class="cm-tab" role="presentation" cm-text=" "> </span>CNTP_CTL,PL1物理定时器控制寄存器</span>
复制代码 代码移植Z:brightharmony-100askkernelliteos_aplatformhwarminterruptgicgic_v2.c
- <span role="presentation"><span class="cm-variable">VOID</span> <span class="cm-def">HalIrqUnmask</span>(<span class="cm-variable">UINT32</span> <span class="cm-variable">vector</span>)</span>
- <span role="presentation">{</span>
- <span role="presentation"> <span class="cm-keyword">if</span> ((<span class="cm-variable">vector</span> <span class="cm-operator">></span> <span class="cm-variable">OS_USER_HWI_MAX</span>) <span class="cm-operator">||</span> (<span class="cm-variable">vector</span> <span class="cm-operator"><</span> <span class="cm-variable">OS_USER_HWI_MIN</span>)) {</span>
- <span role="presentation"> <span class="cm-keyword">return</span>;</span>
- <span role="presentation"> }</span>
- <span role="presentation"> <span class="cm-comment">//GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32); //替换</span></span>
- <span role="presentation" class="cm-tab-wrap-hack"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-operator">*</span>(<span class="cm-keyword">volatile</span> <span class="cm-variable">UINT32</span> <span class="cm-operator">*</span>)((<span class="cm-variable">UINTPTR</span>)<span class="cm-variable">IO_DEVICE_ADDR</span>(<span class="cm-number">0x3F00B218</span>)) <span class="cm-operator">=</span> <span class="cm-number">1</span>; <span class="cm-comment">//使能ARM Timer IRQ<span class="cm-tab" role="presentation" cm-text=" "> </span></span></span>
- <span role="presentation"><span cm-text=""></span></span>
- <span role="presentation">}</span>
复制代码Z:brightharmony-100askkernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c
- <span role="presentation"><span class="cm-variable">STATIC_INLINE</span> <span class="cm-variable">VOID</span> <span class="cm-def">TimerCtlWrite</span>(<span class="cm-variable">UINT32</span> <span class="cm-variable">cntpCtl</span>)</span>
- <span role="presentation">{</span>
- <span role="presentation"> <span class="cm-comment">//WRITE_TIMER_REG32(TIMER_REG_CTL, cntpCtl);//替换</span></span>
- <span role="presentation"> <span class="cm-keyword">if</span>(<span class="cm-variable">cntpCtl</span> <span class="cm-operator">==</span> <span class="cm-number">0</span>){</span>
- <span role="presentation"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-operator">*</span>(<span class="cm-keyword">volatile</span> <span class="cm-variable">UINT32</span> <span class="cm-operator">*</span>)((<span class="cm-variable">UINTPTR</span>)<span class="cm-variable">IO_DEVICE_ADDR</span>(<span class="cm-number">0x3F00B408</span>)) <span class="cm-operator">=</span> <span class="cm-number">0x003E0000</span>;</span>
- <span role="presentation"> <span class="cm-tab" role="presentation" cm-text=" "> </span>}</span>
- <span role="presentation"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-keyword">else</span></span>
- <span role="presentation"><span class="cm-tab" role="presentation" cm-text=" "> </span>{</span>
- <span role="presentation"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-operator">*</span>(<span class="cm-keyword">volatile</span> <span class="cm-variable">UINT32</span> <span class="cm-operator">*</span>)((<span class="cm-variable">UINTPTR</span>)<span class="cm-variable">IO_DEVICE_ADDR</span>(<span class="cm-number">0x3F00B408</span>)) <span class="cm-operator">=</span> <span class="cm-number">0x003E00A2</span>;</span>
- <span role="presentation"><span class="cm-tab" role="presentation" cm-text=" "> </span>}</span>
- <span role="presentation">}</span>
复制代码Z:brightharmony-100askkernelliteos_aplatformhwarmtimerarm_genericarm_generic_timer.c
- <span role="presentation"><span class="cm-variable">STATIC_INLINE</span> <span class="cm-variable">VOID</span> <span class="cm-def">TimerTvalWrite</span>(<span class="cm-variable">UINT32</span> <span class="cm-variable">tval</span>)</span>
- <span role="presentation">{</span>
- <span role="presentation"> <span class="cm-comment">//WRITE_TIMER_REG32(TIMER_REG_TVAL, tval);//替换</span></span>
- <span role="presentation" class="cm-tab-wrap-hack"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-operator">*</span>(<span class="cm-keyword">volatile</span> <span class="cm-variable">UINT32</span> <span class="cm-operator">*</span>)((<span class="cm-variable">UINTPTR</span>)<span class="cm-variable">IO_DEVICE_ADDR</span>(<span class="cm-number">0x3F00B400</span>)) <span class="cm-operator">=</span> <span class="cm-variable">tval</span>; <span class="cm-comment">//设置倒计时时间,鸿蒙是10ms<span class="cm-tab" role="presentation" cm-text=" "> </span></span></span>
- <span role="presentation">}</span>
复制代码