关闭

lk中的timer

419人阅读 评论(0) 收藏 举报
分类:
kmain中会调用timer_init来初始timer_queue,并通过
void timer_init(void)
{
list_initialize(&timer_queue);


/* register for a periodic timer tick */
platform_set_periodic_timer(timer_tick, NULL, 10); /* 10ms */
}
并通过platform_set_periodic_timer 设定timer每10ms中断一次,中断callback是timer_tick
我们看一个平台的实现
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval)
{
enter_critical_section();


t_callback = callback;


*REG(PIT_CLEAR) = 1;
*REG(PIT_INTERVAL) = interval;
*REG(PIT_START_PERIODIC) = 1;


unmask_interrupt(INT_PIT);


exit_critical_section();


return NO_ERROR;
}
将callback 赋值给t_callback,并写寄存器设定中断间隙为10ms
void platform_init_timer(void)
{
register_int_handler(INT_PIT, &platform_tick, NULL);
}
我们会在提前调用platform_init_timer,在其中调用register_int_handler 来设定timer的irq number INT_PIT的callback函数是platform_tick。
static enum handler_return platform_tick(void *arg)
{
*REG(PIT_CLEAR_INT) = 1;
if (t_callback) {
return t_callback(arg, current_time());
} else {
return INT_NO_RESCHEDULE;
}
}


最终在platform_tick这个函数中调用t_callback


最终结论就是在timer的中断函数中最后会调用timer_tick函数.
static enum handler_return timer_tick(void *arg, time_t now)
{
timer_t *timer;
enum handler_return ret = INT_NO_RESCHEDULE;


#if THREAD_STATS
thread_stats.timer_ints++;
#endif


for (;;) {
/* see if there's an event to process */
timer = list_peek_head_type(&timer_queue, timer_t, node);
if (likely(!timer || now < timer->scheduled_time))
break;


/* process it */
DEBUG_ASSERT(timer->magic == TIMER_MAGIC);
list_delete(&timer->node);
// timer = list_remove_head_type(&timer_queue, timer_t, node);
// ASSERT(timer);


#if THREAD_STATS
thread_stats.timers++;
#endif


// TRACEF("firing callback %p, arg %p\n", timer->callback, timer->arg);
if (timer->callback(timer, now, timer->arg) == INT_RESCHEDULE)
ret = INT_RESCHEDULE;
}


/* let the scheduler have a shot to do quantum expiration, etc */
if (thread_timer_tick() == INT_RESCHEDULE)
ret = INT_RESCHEDULE;


return INT_RESCHEDULE;
}
timer_tick 是个死循环,会从变量timer_queue 中是否有到期的时间
if (likely(!timer || now < timer->scheduled_time))
如果有的话,就从timer_queue 中删除,
list_delete(&timer->node);
并调用这个timer 到期时间需要执行的callback
if (timer->callback(timer, now, timer->arg) == INT_RESCHEDULE)


然后在坚持当前thread的时间片是否用完了,如果完了,就要重新调度.




timer系统部分运作原理解讲完了,我们下来看看是否使用timer


我们以gpio_keypad.c 为例
timer_initialize(&keypad->timer);
timer_set_oneshot(&keypad->timer, 0, gpio_keypad_timer_func, NULL);


可以看到先调用timer_initialize 初始化一个timer_t 结构体
void timer_initialize(timer_t *timer)
{
timer->magic = TIMER_MAGIC;
list_clear_node(&timer->node);
timer->scheduled_time = 0;
timer->periodic_time = 0;
timer->callback = 0;
timer->arg = 0;
}


在调用timer_set_oneshot 来加入到timer_queue 中
void timer_set_oneshot(timer_t *timer, time_t delay, timer_callback callback, void *arg)
{
time_t now;


// TRACEF("delay %d, callback %p, arg %p\n", delay, callback, arg);


DEBUG_ASSERT(timer->magic == TIMER_MAGIC);


if (list_in_list(&timer->node)) {
panic("timer %p already in list\n", timer);
}


now = current_time();
timer->scheduled_time = now + delay;
timer->periodic_time = 0;
timer->callback = callback;
timer->arg = arg;


// TRACEF("scheduled time %u\n", timer->scheduled_time);


enter_critical_section();


insert_timer_in_queue(timer);


exit_critical_section();
}


设定到期时间和callback
timer->scheduled_time = now + delay;
timer->periodic_time = 0;
timer->callback = callback;


然后插入到timer_queue list中
static void insert_timer_in_queue(timer_t *timer)
{
timer_t *entry;


list_for_every_entry(&timer_queue, entry, timer_t, node) {
if (entry->scheduled_time > timer->scheduled_time) {
list_add_before(&entry->node, &timer->node);
return;
}
}


/* walked off the end of the list */
list_add_tail(&timer_queue, &timer->node);
}


可见timer_queue中是按scheduled_time 来从小到大排序的


下来接timer到期,然后再timer中的callback函数中调用gpio_keypad_timer_func。


如果需要continue time的话,就在gpio_keypad_timer_func 中继续调用timer_set_oneshot。
static enum handler_return
gpio_keypad_timer_func(struct timer *timer, time_t now, void *arg)
{

kp->current_output = out;
if (out < kpinfo->noutputs) {
gpio = kpinfo->output_gpios[out];
if (kpinfo->flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set(gpio, polarity);
else
gpio_config(gpio, polarity ? GPIO_OUTPUT : 0);
timer_set_oneshot(timer, kpinfo->settle_time,
 gpio_keypad_timer_func, NULL);
goto done;
}


}
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

MTK lk源码解析5( lk 阶段aboot.c 解析)

http://blog.csdn.net/xichangbao/article/details/51484610 现在开始分析关键函数aboot_init(),岔开一句lk在分区表的名称...
  • ffmxnjm
  • ffmxnjm
  • 2017-04-18 17:24
  • 281

OpenCV21(金字塔LK光流算法)

最好的教程,就是看Blog,然后最后一定要回归书本。   一、LK算法提到了三个假设 (高深:就是用你认识的字写你看不懂的东西。办法:多看几遍,查阅Blog上接地气的说法) 1.灰度不变  ...
  • u014488388
  • u014488388
  • 2016-10-20 22:13
  • 681

(转)Android bootloader(LK)启动流程

转自:http://blog.csdn.net/jmq_0000/article/details/7378348 LK是什么            LK 是 Little Kernel 它是 ...
  • wangbin344
  • wangbin344
  • 2016-08-05 13:41
  • 1025

android源码编译

在前一篇文章中,我们介绍了如何在Ubuntu上为Android系统编写Linux内核驱动程序。在这个名为hello的Linux内核驱动程序中,创建三个不同的文件节点来供用户空间访问,分别是传统的设备文...
  • LK1105010206
  • LK1105010206
  • 2015-10-27 09:21
  • 781

lk启动流程详细分析

转载请注明来源:cuixiaolei的技术博客  这篇文章是lk启动流程分析(以高通为例),将会详细介绍下面的内容:1).正常开机引导流程2).recovery引导流程3).fastboot引导流程4...
  • LoongEmbedded
  • LoongEmbedded
  • 2016-08-29 19:58
  • 3197

LK源码解析 2 main.c

kmain()。 /* called from crt0.S */ void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE; void...
  • xichangbao
  • xichangbao
  • 2016-05-23 20:38
  • 1320

光流(三)--LK算法改进(金字塔LK)

原文: http://blog.csdn.net/u010684134/article/details/49185535 OpenCV之光流法运动目标跟踪 [光流Optical Flow]的概念是Gi...
  • App_12062011
  • App_12062011
  • 2016-07-11 14:57
  • 10470

总结:光流--LK光流--基于金字塔分层的LK光流--中值流

最近的一个月完成了TLD、CF、Muster等一些算法的学习和整理,由于是在word中整理,不便于再在csdn中编辑,就直接截图发上来了,尽请谅解。(其实还是我自己太懒了,不想再重新编辑一遍了...)...
  • sgfmby1994
  • sgfmby1994
  • 2017-03-30 17:13
  • 1237

高通平台lk下调屏小结

在lk下调试屏幕,可先了解下lk的代码流程,方便接下来的调试。这里以msm8996平台为例,描述lk的代码结构。 bootable/bootloader/lk/kernel/maic.c
  • mike8825
  • mike8825
  • 2016-12-31 01:08
  • 1254

高通平台LK传递参数给kernel参考serialno的方式实现

该需求主要是为了能够获取自定义的版本号,或者需要bootloader里,定制代码的执行结果需要传递到bootloader从而控制启动等。 首先可以从shell里查看LK传入的值。 cat proc...
  • LEAD_SOLO
  • LEAD_SOLO
  • 2017-10-24 11:22
  • 173
    个人资料
    • 访问:259835次
    • 积分:12819
    • 等级:
    • 排名:第1245名
    • 原创:1062篇
    • 转载:0篇
    • 译文:11篇
    • 评论:9条
    最新评论