问题条件:Systick使用外部低速32K时钟,CPU主频196M
原始代码及问题点:
STATIC UINT64 SysTickReload(UINT64 nextResponseTime)
{
if (nextResponseTime > g_archTickTimer.periodMax) {
nextResponseTime = g_archTickTimer.periodMax;
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->LOAD = (UINT32)(nextResponseTime - 1UL); /* set reload register /
SysTick->VAL = 0UL; / Load the SysTick Counter Value */
NVIC_ClearPendingIRQ(SysTick_IRQn); // 无法使用NVIC_ClearPendingIRQ清除SysTick中断,请使用SCB->ICS|= SCB_ICSR_PENDSTCLR_Msk;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
return nextResponseTime;
}
STATIC UINT64 SysTickCycleGet(UINT32 period)
{
UINT32 hwCycle = 0;
UINT32 intSave = LOS_IntLock();
UINT32 val = SysTick->VAL;
period = SysTick->LOAD; ** //LOAD时减了1,此时获取的period需要加1,改为period = SysTick->LOAD +1*
if (val != 0) {
hwCycle = *period - val;
}
LOS_IntRestore(intSave);
return (UINT64)hwCycle;
}
当前产品自己修复后的代码:
UINT64 OsSysTimerCycleGet(UINT32 *period)
{
*period = (SysTick->LOAD + 1); //LOAD时减了1
return ((SysTick->VAL != 0) ? (*period - SysTick->VAL) : 0); //为什么是SysTick->LOAD + 1 - SysTick->VAL?因为LOAD配置好后,需要一个cycle VAL的值才会同步成LOAD
}
UINT64 OsSysTimerReload(UINT64 period)
{
if (period > LOSCFG_BASE_CORE_TICK_RESPONSE_MAX) {
period = LOSCFG_BASE_CORE_TICK_RESPONSE_MAX;
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->LOAD = (UINT32)(period - 1); // LOAD从0到翻转需要一个cycle,即使配置0,也要一个cycle产生中断
SysTick->VAL = 0;
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
return period;
}
感谢提交Issue!关于Issue的交互操作,请访问OpenHarmony社区支持命令清单。如果有问题,请联系 @zhushengle @LeonChan @JerryH 。如果需要调整订阅PR、Issue的变更状态,请访问链接。
Thanks for submitting the issue. For more commands, please visit OpenHarmony Command List. If you have any questions, please refer to committer @zhushengle @LeonChan @JerryH for help. If you need to change the subscription of a Pull Request or Issue, please visit the link.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
登录 后才可以发表评论