目前分類:嵌入式系統 (2)

瀏覽方式: 標題列表 簡短摘要
http://www.mcuos.com/viewthread.php?tid=70

时间管理是操作系统的一项重要功能,硬件必须提供一个周期性的时钟或者定时器,以支持系统中与时间相关的功能部件。一般,大多数CPU都有一个或多个内置定时器,提供周期性的中断,即使没有内置定时器,也必须使用外部定时器或时钟。
    
ecos抽象了时间相关硬件的本质,提供了通用的时间管理机制。这些定时机制包括:计数器(Counter)、时钟(Clock)、告警器(Alarm)和定时器(Timer)。有了这些抽象概念,我们就不必做一些搭架子的重复性工作了,也不必在硬件细节上浪费时间,而是集中精力在功能实现上。针对抽象平台接口编程的好处是移植性好,以不变应万变。
    

  • 计数器---对指定事件进行单调递增计数
  • 时钟-----对具有一定周期性的时间滴答(tick)进行计数的计数器(对时间进行计数)
  • 告警器---在计数器的基础上增加一个提示功能的机制,或者基于计数器的值产生具有周期性的事件
  • 定时器---简单地附加在时钟上的告警器

    
这些时间相关API函数的定义都在<cyg/kernel/kapi.h>内,使用时必须包含该头文件。
    
==========
计数器 *
==========

创建:
void cyg_counter_create(cyg_handle_t *handle, cyg_handle_t *counter)

该函数创建一个性的计数器,新计数器的句柄通过handle返回。cyg_handle_t---cyg表示cygnus公司定义,handle是句柄,t是type的缩写(类型),合起来的意思是cygnus公司定义的句柄类型,很好理解吧。所有计数器函数都是cyg_counter开头的,只要看到有counter,就知道和计数器有关。counter是应用程序提供给该计数器所需的内存,从而减少了在内核中进行动态内存分配的需求。ecos里很多函数都是由应用程序提供目标对象所需内存,使用静态内存分配而不是动态分配符合嵌入式系统的特点。
    
删除:
void cyg_counter_delete(cyg_handle_t counter)

读指定计数器当前值
cyg_tick_count_t cyg_counter_current_value(cyg_handle_t counter)

设置指定计数器值
void cyg_counter_set_value(cyg_handle_t counter, cyg_tick_count_t new_value)

计数器加1
void cyg_counter_tick(cyg_handle_t counter)

创建一个新的计数器不会自动将事件源连接到该计数器上,无论相对应的时间何时发生,都需要调用cyg_counter_tick函数使计数器加1计数。一般在事件中断的DSR里调用此函数。

计数器值增加指定tick数
void cyg_counter_multi_tick(cyg_handle_t counter, cyg_tick_count_t ticks)
    
========
时钟 *
========

内核级的所有与时钟相关的操作包括延时、超时和告警等都是以时钟滴答为单位进行工作的,而不是以秒或微秒为单位。如果应用程序或其他软件需要使用秒或微秒这样的时间单位,则需要将这些时间单位转换为时钟滴答。这是因为只有时钟滴答才能精确地反映出硬件的支持条件。而且如果使用传统意义上的时间单位如纳秒(ns),则硬件有可能不能提供支持。另一个原因是在时钟滴答和传统意义上的时间单位之间的转换需要浪费很多代码和数据,采用时钟滴答为单位可以节省代码量和CPU时间。

时钟单位间的转换需要一个分辨率,如100Hz运行的时钟,1秒内产生100次tick,则分辨率为1000000000(ns) : 100(tick)。同样,60Hz的分辨率为1000000000 : 60。

将一个以纳秒为单位的延时除以分辨率就可以转换为对应的时钟滴答。如一个50ms的延时(50000000ns),时钟频率为100Hz(即分辨率1000000000 : 100),那么可以通过下面的计算转换为时钟滴答:50000000 ÷ (1000000000/100) = 5,即:50ms的延时在100Hz时钟分辨率下对应5个tick。
    
创建:
void cyg_clock_create(cyg_resolution_t resolution, cyg_handle_t *handle, cyg_clock *clock)
使用给定分辨率创建一个新的时钟,新时钟的句柄由handle带回。
    
删除:
void cyg_clock_delete(cyg_handle_t clock)
调用此函数前应确保系统中已经没有使用该时钟的组件。  
  
将时钟转换为计数器
void cyg_clock_to_counter(cyg_handle_t clock, cyg_handle_t *counter)    

设置时钟分辨率
void cyg_clock_set_resolution(cyg_handle_t clock, cyg_resolution_t resolution)

获取时钟分辨率
cyg_resolution_t cyg_clock_get_resolution(cyg_handle_t clock)

获取系统的实时时钟(RTC,不是外部RTC,是内核抽象的clock)
cyg_handle_t cyg_real_time_clock(void)

获取当前的系统时间,单位为时钟滴答。系统时间用64位的数字表示。
cyg_tick_count_t cyg_current_time(void)
    
==========
告警器 *
==========

内核告警器与计数器一起使用,使得当某种时间发生了一定的次数时采取响应的动作。如果与计数器一起使用的是时钟,那么当时间滴答的个数达到适当的值也就是在一定的时间周期后将发生告警行为。
    
创建:

复制内容到剪贴板
代码:
    void cyg_alarm_create
    (
        cyg_handle_t counter,  //和告警器一起使用的计数器
        cyg_alarm_t *alarmfn,  //告警时的回调函数
        cyg_addrword_t data,   //传给回调函数的参数
        cyg_handle_t *handle,  //返回的告警器句柄
        cyg_alarm *alarm       //告警器对象
    )

其中alarmfn对应的回调函数格式如下:

复制内容到剪贴板
代码:
    void alarm_fun(cyg_handle_t alarm, cyg_addrword_t data)
    {
        ......
    }


    
删除:
void cyg_alarm_delete(cyg_handle_t alarm)

初始化并启动一个告警器

复制内容到剪贴板
代码:
    void cyg_alarm_initialize
    (
        cyg_handle_t alarm,         //告警器句柄
        cyg_tick_count_t trigger,   //绝对触发时间
        cyg_tick_count_t interval   //触发间隔
     )
返回告警器的下一次触发的绝对时间和它的触发间隔
复制内容到剪贴板
代码:
    void cyg_alarm_get_times
    (
        cyg_handle_t alarm,         //待查询的告警器的句柄
        cyg_tick_count_t trigger,   //下一次触发时的绝对时间
        cyg_tick_count_t interval   //当前触发间隔
     )

    使能告警器
    void cyg_alarm_enable(cyg_handle_t alarm)

    禁止告警器
    void cyg_alarm_disable(cyg_handle_t alarm)

下面用一个具体实验来说明时间相关API函数的用法。

使用时钟函数统计程序执行时间,在程序开始执行前和执行完毕后分别调用cyg_current_time获得开始时间和结束时间,将tick单位转换为毫秒单位,计算单位时间内执行循环次数和单个循环执行时间。使用告警器,以2秒为周期,让蜂鸣器交替发声和静音。

注意:cyg_current_time得到的时间是64位的,printf显示64位整数时使用“%lld”格式;另外不要在告警器回调函数里使用printf函数。

测试SmartARM2200的结果为(循环0x80000次):每秒执行195527.8次循环,每循环执行时间为5us。蜂鸣器响2秒,停2秒,周而复始。
复制内容到剪贴板
代码:
//测试程序
#include 
#include 
#include 
#define STACK_SIZE 4096
#define ALARM_INTERVAL 200  //2秒
#define BEEPCON 0x0000080
#define LOOPNUM 0x80000

char stack[STACK_SIZE];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;

cyg_handle_t counter_handle;
cyg_handle_t alarm_handle;
cyg_alarm    alarm_object;

void alarm_func(cyg_handle_t alarm_handle, cyg_addrword_t data)
{
    int i;
        
    HAL_READ_UINT32(LPC2XXX_GPIO_IO0SET,i);
   
    if((i&BEEPCON) == 0 )
        {
        HAL_WRITE_UINT32(LPC2XXX_GPIO_IO0SET,BEEPCON);
        }
    else
        {
        HAL_WRITE_UINT32(LPC2XXX_GPIO_IO0CLR,BEEPCON);
        }
}

void
alarm(cyg_addrword_t data)
{
    cyg_tick_count_t t1, t2, t;
    int i, sum;
   
    printf("\n\n\n");
    printf("\t    *******************************\n");
    printf("\t    *     Hello! Alarm test.      *\n");
    printf("\t    *******************************\n\n\n");
   
    printf("Test speed:\n");
    sum = 0;
    t1 = cyg_current_time();
    for(i = 0; i < LOOPNUM; i++)
        {
        sum = sum + i;
        }
    t2 = cyg_current_time();
    t = abs(t2-t1) * 10;
    printf("start=%lld\nend=%lld\n", t1, t2);
    printf("Total time = %lldms\n",t);
    printf("Total loop = %lld\n", LOOPNUM);
    if(t == 0)
        {
        t = 1;
        }
    printf("%lf(loop/sec) , %lf(sec/loop)\n", LOOPNUM * 1000.0 / t, t / 1000.0 / LOOPNUM);
    //设置输出到BEEP
    HAL_WRITE_UINT32(LPC2XXX_GPIO_IO0DIR,BEEPCON);
    //禁止刚一开始就BEEP,上电缺省输出是低电平,导致一开始就鸣叫。
    HAL_WRITE_UINT32(LPC2XXX_GPIO_IO0SET,BEEPCON);
    //将时钟转换为计数器。cyg_real_time_clock()函数获取系统实时时钟(RTC)。实时时钟用于系统的延时、阻塞等待等操作。
    cyg_clock_to_counter(cyg_real_time_clock(), &counter_handle);
    //创建警告器
    cyg_alarm_create(counter_handle, alarm_func, 0, &alarm_handle, &alarm_object);
    //初始化警告器
    cyg_alarm_initialize(alarm_handle, cyg_current_time() + ALARM_INTERVAL, ALARM_INTERVAL);
    //使能警告器
    cyg_alarm_enable(alarm_handle);
    while(1)
        {
        cyg_thread_delay(2000);
        }
}
void
cyg_start(void)
{
    // Create a main thread, so we can run the scheduler and have time 'pass'
    cyg_thread_create(10,                // Priority - just a number
                      alarm,              // entry
                      0,                 // entry parameter
                      "alarm",            // Name
                      &stack,         // Stack
                      STACK_SIZE,        // Size
                      &thread_handle, // Handle
                      &thread_data    // Thread data structure
            );
    cyg_thread_resume(thread_handle); // Start it
    cyg_scheduler_start();
}

 

freestyler 發表在 痞客邦 留言(0) 人氣()

轉錄來自 http://bbs.eeworld.com.cn/thread-68460-1-1.html

 

1:   C语言类:
(1)C/C++ 编码规范
http://bbs.eeworld.com.cn/thread-68459-1-1.html
(2)C语言测试:想成为嵌入式程序员应知道的0x10个基本问题
http://bbs.eeworld.com.cn/thread-68453-1-1.html
  (3)C语言进阶 (东南大学 凌明 非常不错)
http://bbs.eeworld.com.cn/thread-67996-1-1.html
(4)C-51语言程序设计基础
http://bbs.eeworld.com.cn/thread-68379-1-1.html
(5)C语言嵌入式系统编程(收集大发送) 
http://bbs.eeworld.com.cn/thread-55233-1-2.html
(6)C语言嵌入式系统编程修炼之道
http://bbs.eeworld.com.cn/thread-67662-1-2.html
(7)嵌入式系统C语言编程
http://bbs.eeworld.com.cn/thread-63986-1-2.html
(8)嵌入式C精华
http://bbs.eeworld.com.cn/thread-54905-1-2.html
(9)嵌入式C C++语言精华
http://bbs.eeworld.com.cn/thread-62349-1-9.html
(10)C语言嵌入式系统编程(收集大发送之3——嵌入式系统的C程序设计)
http://bbs.eeworld.com.cn/thread-60594-1-10.html
2:   系统类:
(1)时间触发和状态机思想的嵌入式系统 分析都给大家传上去了!
http://bbs.eeworld.com.cn/thread-67442-1-1.html
(2)嵌入式系统可靠性设计
http://bbs.eeworld.com.cn/thread-68457-1-1.html
(3)中断驱动多任务--- 单片机(MCU) 下的一种软件设计结构
http://bbs.eeworld.com.cn/thread-68452-1-1.html
(4)单片机及嵌入式系统应用-常用输入/输出电路设计 
http://bbs.eeworld.com.cn/thread-68239-1-1.html
(5)实时多任务系统内核分析 & OSII_CHM
http://bbs.eeworld.com.cn/thread-64937-1-6.html
(6)嵌入式构架206页
http://bbs.eeworld.com.cn/thread-15774-1-2.html
(7)uCOS2精华快速掌握
http://bbs.eeworld.com.cn/thread-65272-1-2.html
(8)uCOS-II 实时操作系统在嵌入式平台进行移植的一般方法和技巧
http://bbs.eeworld.com.cn/thread-55238-1-2.html
(9)VxWorks操作系统及实时多任务程序设计
http://bbs.eeworld.com.cn/thread-66298-1-2.html
(10)Linux V0.11 源程序
http://bbs.eeworld.com.cn/thread-66798-1-2.html
(11)补充: linux设备驱动程序(中文第三版) 2.6内核(完整版)
http://bbs.eeworld.com.cn/thread-53022-1-2.html
(12)实时嵌入式系统设计综述
http://bbs.eeworld.com.cn/thread-67447-1-3.html
(13)ARM嵌入式系统开发:软件设计与优化》PDF 690页
http://bbs.eeworld.com.cn/thread-66826-1-3.html
(14)嵌入式LINUX开发入门V1.5
http://bbs.eeworld.com.cn/thread-64978-1-6.html
(15)一步一步教你开发嵌入式Linux 应用程序
http://bbs.eeworld.com.cn/thread-64746-1-6.html
(16)Linux实用培训学习教程1.0
http://bbs.eeworld.com.cn/thread-63066-1-6.html
3:arm入门与提高
(1)轻松入门开发ARM 程序
http://bbs.eeworld.com.cn/thread-68380-1-1.html
(2)arm体系结构与应用系统设计
http://bbs.eeworld.com.cn/thread-68327-1-1.html
(3)轻松入门开发ARM 程序
http://bbs.eeworld.com.cn/thread-63991-1-7.html
4:嵌入式微处理器系统教程
(1)北大:嵌入式微处理器系统教程 PDF
http://bbs.eeworld.com.cn/thread-68320-1-1.html
(2)北京大学嵌入式开发讲义
http://bbs.eeworld.com.cn/thread-53903-1-2.html
(3)Keil环境下Wiggler和H-JTAG使用简明教程(一)
http://bbs.eeworld.com.cn/thread-68118-1-2.html
(4)英倍特uCOS-II 的教学课件
http://bbs.eeworld.com.cn/thread-64749-1-4.html
5:WinCE
(1):Microsoft内部关于WinCE培训资料
http://bbs.eeworld.com.cn/thread-50692-1-1.html
(2)4篇最新的硕博论文下载(WinCE相关)
http://bbs.eeworld.com.cn/thread-52539-1-3.html
(3)一个入门的windowsCE开发资料
http://bbs.eeworld.com.cn/thread-51145-1-10.html
6:硬件
(1)硬件工程师面试试题
http://bbs.eeworld.com.cn/thread-66778-1-2.html
(2)硬件工程师必读攻略
http://bbs.eeworld.com.cn/thread-63512-1-2.html

7:stm32
(1)如何使用 STM32F101xx 和 STM32F103xx 微控制器的链路系统实现32位定时器的分辨率
http://bbs.eeworld.com.cn/thread-67575-1-3.html
(2)STM32 中断与嵌套NVIC 快速入门
http://bbs.eeworld.com.cn/thread-67574-1-3.html
(3)STM32F10使用USART的应用中编程
http://bbs.eeworld.com.cn/thread-63990-1-5.html
(4)ucosii在STM32中的移植
http://bbs.eeworld.com.cn/thread-64794-1-5.html
(5)[原创]STM32学习笔记之—ADC
http://bbs.eeworld.com.cn/thread-63692-1-7.html
(6)STM32学习体会-STM32F单纯的TIM2定时器溢出中断试验程序
http://bbs.eeworld.com.cn/thread-63988-1-7.html
(7)STM32学习笔记之—RTC
http://bbs.eeworld.com.cn/thread-63918-1-8.html
(8)STM32 中断与嵌套NVIC 快速入门。
http://bbs.eeworld.com.cn/thread-63690-1-8.html
为STM32移植FATFS,读取SD卡上FAT12_16_32文件系统
http://bbs.eeworld.com.cn/viewthread.php?tid=69121&pid=127579&page=1&extra=page%3D1#pid127579
8:ARM嵌入式开发视频教程
    http://bbs.eeworld.com.cn/thread-68592-1-1.html
9:嵌入式系统或者单片机的开发规范化问题
   http://bbs.eeworld.com.cn/thread-69755-1-1.html
10:44B0X中文资料
   http://bbs.eeworld.com.cn/thread-69584-1-1.html
11:ARM入门调试笔记
    http://bbs.eeworld.com.cn/thread-69583-1-1.html
12:uCOS-II 实时操作系统在嵌入式平台进行移植的一般方法和技巧
   http://bbs.eeworld.com.cn/thread-55238-1-1.html
13:S3C44B0X全套培训资料及源代码
    http://bbs.eeworld.com.cn/thread-69123-1-1.html

STM32资料集锦
  http://bbs.eeworld.com.cn/thread-75235-1-1.html

freestyler 發表在 痞客邦 留言(0) 人氣()