1:初始化
如果coret_freq=24_000_000Hz,CONFIG_SYSTICK_HZ=100,通过以下初始化,可以知道coret_freq / CONFIG_SYSTICK_HZ = 多少次后进入中断;CONFIG_SYSTICK_HZ为csi_tick变量增加一次的频率(时间)=100hz(10ms)
csi_coret_config((soc_get_coret_freq()/ CONFIG_SYSTICK_HZ), CORET_IRQn);
2:中断
void tick_irq_handler(void *arg)
{
csi_tick++;
CORET->CTRL;
}
3:判断1ms间隔差,(soc_get_coret_freq()/ CONFIG_SYSTICK_HZ)
以下算法=当前tick时间+下一次进入中断前内部时间差量(0-10ms);这个算法有正负一误差
uint32_t csi_tick_get_ms(void)
{
uint32_t time;
while (1) {
time = (csi_tick * (1000U / CONFIG_SYSTICK_HZ)) + ((csi_coret_get_load() - csi_coret_get_value()) / (soc_get_coret_freq() / 1000U));
if (time >= last_time_ms) {
break;
}
}
last_time_ms = time;
return time;
}
4:1ms间隔差,但是没有正负一误差
static void _1000usdelay(void)
{
uint32_t load = csi_coret_get_load();
uint32_t start = csi_coret_get_value();
uint32_t cur;
uint32_t cnt = (soc_get_coret_freq() / 1000U);
while (1) {
cur = csi_coret_get_value();
if (start > cur)
{
if ((start - cur) >= cnt)
{
break;
}
}
else
{
if (((load - cur) + start) > cnt)
{
break;
}
}
}
}
5:判断1us时间间隔差,有正负一误差
uint64_t csi_tick_get_us(void)
{
uint32_t temp;
uint64_t time;
while (1) {
// the time of coretim pass
temp = csi_coret_get_load() - csi_coret_get_value();
time = ((uint64_t)temp) / ((uint64_t)soc_get_coret_freq() / 1000000U);
//the time of csi_tick
time += ((uint64_t)csi_tick * (1000000U / CONFIG_SYSTICK_HZ));
if (time >= last_time_us) {
break;
}
}
last_time_us = time;
return time;
}
6:1us间隔差,但是没有正负一误差
void _1udelay(void)
{
uint32_t load = csi_coret_get_load();
uint32_t start = csi_coret_get_value();
uint32_t cnt = (soc_get_coret_freq() / 1000U / 1000U);
while (1) {
uint32_t cur = csi_coret_get_value();
if (start > cur) {
if ((start - cur) >= cnt) {
break;
}
} else {
if (((load - cur) + start) > cnt) {
break;
}
}
}
}