Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1680770
  • 博文数量: 124
  • 博客积分: 4078
  • 博客等级: 中校
  • 技术积分: 3943
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-21 11:28
个人简介

新博客:http://sparkandshine.net/

文章分类

全部博文(124)

分类: 嵌入式

2011-10-27 10:33:30

摘要:

    本文基于STM32F103RBT6微控制器,深入源码,详细分析了时钟中断处理程序Systick_isr。


一、Systick_isr源代码

  1. static volatile clock_time_t current_clock = 0;
  2. static volatile unsigned long current_seconds = 0;
  3. static unsigned int second_countdown = CLOCK_SECOND; //详情见2.1

  4. /***时钟中断处理程序***/
  5. void SysTick_Handler(void)
  6. {
  7.   usart_puts("systick isr\n");

  8.   SCB->ICSR = SCB_ICSR_PENDSTCLR; //详情见2.2

  9.   current_clock++;
  10.   if (etimer_pending() && etimer_next_expiration_time() <= current_clock) //timerlist不为空且还没有etimer到期,则执行etimer_request_poll。详情见2.3
  11.   {
  12.     etimer_request_poll(); //详情见2.4
  13.   }
  14.   if (--second_countdown == 0)
  15.   {
  16.     current_seconds++;
  17.     second_countdown = CLOCK_SECOND; //重置second_countdown
  18.   }
  19. }

 注:时钟中断处理程序与硬件相关,我用的是STM32F103RBT6。

二、源码分析

2.1 CLOCK_SECOND宏

    CLOCK_SECOND定义了1秒钟产生时钟中断的次数,默认情况是32次,可以通过宏CLOCK_CONF_SECOND来配置。源代码如下:

  1. /*CLOCK_SECOND宏定义*/
  2. #ifdef CLOCK_CONF_SECOND
  3.   #define CLOCK_SECOND CLOCK_CONF_SECOND
  4. #else
  5.   #define CLOCK_SECOND (clock_time_t)32
  6. #endif

  7. #define CLOCK_CONF_SECOND 10 /*define systick clock interrupt times per second*/

2.2 SCB & ICSR

    该语句主要对寄存器进行设置,SCB指System Control Block,ICSR指Interrupt Control State Register,SCB_ICSR_PENDSTCLR是Clear pending SysTick bit。

  1. #define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000) /*Clear pending SysTick bit */

2.3 etimer_pending函数和etimer_next_expiration_time函数

    etimer_pending函数检查timerlist是否为空(若返回true表示不为空),etimer_next_expiration_time函数返回next_expiration(即到了next_expiration才有etimer到期。另,若timerlist为空则返回0),并与系统当前时间current_clock比较,若next_expiration小于等于current_clock,则表明还没有etimer到期,于是把系统进程etimer_process的needspoll设为1,使其具有更快地再次获得执行。

2.3.1 etimer_pending函数

检查timerlist是否为空,若不为空则返回true,否则返回false,源码如下:

  1. /*Check if there are any non-expired event timers*/
  2. int etimer_pending(void) //如果返回true则表明timerlist不为空
  3. {
  4.   return timerlist != NULL;
  5. }

2.3.2 etimer_next_expiration_time函数

    next_expiration是指timerlist下一个到期的时间,即到了next_expiration就会有etimer到期,由update_time计算,详情见博文《Contiki学习笔记:系统进程etimer_process》。

  1. /*得到next_expiration,如果timerlist为空,则返回0*/
  2. clock_time_t etimer_next_expiration_time(void)
  3. {
  4.   return etimer_pending() ? next_expiration : 0;
  5. }

2.4 etimer_request_poll函数

    将系统进程etimer_process的needspoll设为1,使其获得更高优先级,即让etimer_process更快地再次获得执行。详情见博文《Contiki学习笔记:系统进程etimer_process》。

阅读(7447) | 评论(3) | 转发(1) |
给主人留下些什么吧!~~

hnylcxq2012-10-12 10:57:44

Jelline: hnylcxq,您好,感谢您提出疑问。

我有段时间没看这个了,觉得你说得有道理,但etimer_next_expiration_time() <= current_clock怎么解释呢?函数etimer_ne.....
etimer_next_expiration_time()是返回的最近一个到期的etimer时间,比当前时钟小,说明有时间事件到期了。比如最近一个到期的etimer时间是3点,而系统时间时4点了,这说明那个时间事件已经发生了。

Jelline2012-09-20 22:10:15

hnylcxq: if (etimer_pending() && etimer_next_expiration_time() <= current_clock) //timerlist不为空且还没有etimer到期,则执行etimer_request_poll。详.....
hnylcxq,您好,感谢您提出疑问。

我有段时间没看这个了,觉得你说得有道理,但etimer_next_expiration_time() <= current_clock怎么解释呢?函数etimer_next_expiration_time求得timerlist中最近一个到期的etimer时间,比当前时钟小,说明还没到期?

hnylcxq2012-09-20 17:25:45

if (etimer_pending() && etimer_next_expiration_time() <= current_clock) //timerlist不为空且还没有etimer到期,则执行etimer_request_poll。详情见2.3

这里是不是注释错了,如果if条件成立的话,意味着已经有时间事件发生了,然后调用etimer_request_poll(); 去检查,是那个etimer到时了。