当前位置:  编程技术>移动开发
本页文章导读:
    ▪STM32移栽contiki进阶之三(中):timer 中文版        STM32移植contiki进阶之三(中):timer 中文版        鉴于自己英语水平不高,在这里,将上一篇关于contiki 的timer的文章翻译为中文,让自己在学习的时候,更方便点。文中有许多不是很通.........
    ▪ 数据结构(五)之单链表的操作(补充)        数据结构(5)之单链表的操作(补充)1 前言     上次我们讲到单链表的存储和一些简单的算法,今天我们来学习一下单链表的初始化和销毁操作。 2 详述 2.1 单链表的整表创建 思路: ·声.........
    ▪ IT English Collection(九) of Objective-C       IT English Collection(9) of Objective-C1 前言     今天我们来解除一篇有关Objective-C的介绍文章,详情如下。 2 详述 2.1 原文     Objective-C defines a small but powerful set of extensions to the ANSI C programming language.........

[1]STM32移栽contiki进阶之三(中):timer 中文版
    来源: 互联网  发布时间: 2014-02-18
STM32移植contiki进阶之三(中):timer 中文版

        鉴于自己英语水平不高,在这里,将上一篇关于contiki 的timer的文章翻译为中文,让自己在学习的时候,更方便点。文中有许多不是很通顺的地方,将就吧。

 

Timers

        Contiki系统提供了一套时钟库用于应用程序和系统本身。时钟库包含了检查时间超出、将系统从低功耗模式唤醒到预定时间,以及实时任务安排等功能。时钟也用于应用程序,让系统和其他一起工作,或者在恢复执行前进入低功耗模式一段时间。

The Contiki Timer Modules

         Contiki有一个时钟模块和一套时钟:timer,stimer,ctimer,etimer和rtimer。不同的时钟有不同的用处:有的时钟提供了长运行时间低密度(时间间隔长),有的时钟提供了短运行时间和高密度(时间间隔短),有的时钟可以用在中断上下文(rtimer),而其他时钟则不行。

    时钟模块提供了操作系统时间的功能,以及短时间阻塞CPU的功能。定时器库是实现时钟模块的功能的基础。

        timer和stimer库提供了最简单形式的定时器,用于检查一段时间是否到期。应用程序需要问计时器,他们是否已经过期。然而两者的区别在于:timer使用系统嘀嗒,而stimer 使用秒,允许更长的时间。不同于其他timer的是,timer和stimer库可以从中断中安全的使用,这使得他们在底层的驱动中特别有用。

         Etimer库提供事件时间,他能用于contiki进程在一段时间后的计划事件。他用于contiki的进程中,等待一段时间,在此时,其他的部分可以工作或进入低功耗模式。

        Ctimer提供回调时间,他用于在一段时间之后,安排调用回调函数。就像事件定时器一样,他们是用来等待一些时间,而在这段时间内,系统其他的部分可以工作或进入低功耗模式。当时间到期之后,回调定时器调用函数,他在任何代码中都非常有用,以致没有一个想协议实现那样的显式的contiki进程。(这里我翻译的不是很好,原文:they are especially useful in any code that do not have an explicit Contiki process such as protocol implementations)在其他方面,使用的回调定时器在Rime协议栈处理通信超时。

        Rtimer库提供实时任务调度。Rtimer库抢占任何运行着的contiki进程,让实时任务在预定的时间里执行。实时任务用在关键代码处理时间里,例如X-MAC实现收音机开启或关闭这种没有延时的情况下。

The Clock Module

    时钟模块提供操作系统时间的功能。

        Contiki时钟模块的API接口所示如下:clock_time()函数以时钟嘀嗒的形式返回当前系统时间。每秒时钟嘀嗒的数是和平台相关的,通常被指定为常数CLOCK_SECOND。系统时间被指定为和平台相关的类型clock_time_t,在大多数情况下这是一个有限的无符号值,运行时会变很大。时钟模块也提供clock_seconds()函数,以秒的形式获得系统时间,其值为一个无符号的长整型数,这个时间值会变的很大,直到他增加到最大,(在MSP430平台上为136年),然后系统重新开始,时间也从零开始。

    时钟模块提供两个函数阻塞CPU:clock_delay(),阻塞CPU一个指定的延迟,clock_wait(),阻塞CPU一个指定的时钟嘀嗒。这些函数通常只用于底层驱动程序,在有必要等待很短的时间,但并不放弃控制CPU的情况。

    函数clock_init()由系统启动,初始化时钟模块的时候调用。

时钟模块API:

clock_time_t clock_time():获得系统时间。

unsigned long clock_seconds() :以秒的形式获得系统时间。

void clock_delay(unsigned int delay):CPU延时。

void clock_wait(int delay):CPU延时一定数量的系统嘀嗒。

void clock_init(void):初始化时钟模块。

CLOCK_SECOND:每秒系统嘀嗒数。

Porting the Clock Module

     时钟模块与平台相关,他的应用在clock.c文件里面。时钟模块处理系统时间,他的实现通常需要适时检查事件计时器是否到时,然后通知etimer库处理。

The Timer Library

       Contiki时钟库提供设置、重置、重启时钟的函数,并检查一个时钟是否到期。一个应用程序

    需要“手动”地检查定时器是否到期,而不是自动完成的。在时钟模块中,时钟库使用clock_timer()获得当前的系统时间。

    定时器被声明为struct类型,所有访问定时器都是经过指针指向被声明的定时器。

        Contiki定时器库的API如下所示。定时器由timer_set()完成初始化,设置定时器从当前时间到指定时间的延迟,而且他还存储了定时器的时间间隔。Timer_reset()可以从之前的到期时间重置定时器,timer_restart()从当前时间重新启动定时器。Timer_reset()和timer_restart()都是调用timer_set(),用时间间隔设置定时器。这些函数的区别是:timer_reset()用完全相同的时间间隔设置定时器延时,而timer_restart()从当前时间设置时间间隔,使时间推移。

        Timer_expired()函数用来检查定时器是否到期,timer_remaining()获得一个定时器到期的剩余时间。如果定时器已经过期,他的返回值未知的。

        Timer库可以从中断中安全的使用。下面的代码显示了一个简单的例子:一个定时器如何在中断中检测超时。

 Timer库API:

void timer_set(struct timer *t, clock_time_t interval) :启动定时器。

void timer_reset(struct timer *t):从以前到期时间重新启动定时器。

void timer_restart(struct timer *t):从当前时间重启定时器。

int timer_expired(struct timer *t) :检查定时器是否到期。

clock_time_t timer_remaining(struct timer *t):获得剩余时间。

     一个例子展示了一个定时器如何检测超时:

static struct timer rxtimer; 

 void init(void) {

   timer_set(&rxtimer, CLOCK_SECOND / 2);

 }

 interrupt(UART1RX_VECTOR)

 uart1_rx_interrupt(void)

 {

   if(timer_expired(&rxtimer)) {

     /* Timeout */

     /* ... */

   }

   timer_restart(&rxtimer);

   /* ... */

 }

The Stimer Library

        Contiki Stimer 库提供的定时机制类似于timer库,但是他的时间使用是秒,允许更长的到期时间,stimer库在时钟模块中用clock_seconds()以秒的形式获得当前的系统时间。

        Contiki stimer库的API如下所示,他非常类似于timer的库。不同的是,他以秒为单位,而timer是以系统嘀嗒为单位。

        Stimer库可以从中断中安全的使用。

Stimer库的API:

void stimer_set(struct stimer *t, unsigned long interval) :启动timer。

void stimer_reset(struct stimer *t):从到期时间中重启timer。

void stimer_restart(struct stimer *t):从当前时间重启timer。

nt stimer_expired(struct stimer *t):检查时间是否到期。

unsigned long stimer_remaining(struct stimer *t):获得剩余时间。

The Etimer Library

        Contiki etimer库提供了一个定时器机制,产生定时事件。当事件时间到期时,事件定时器将向进程标示PROCESS_EVENT_TIMER来设置定时器。在时钟模块中,Etimer库使用clock_time()获得系统当前时间。

    事件定时器声明为struct etimer类型,所有访问事件定时器都需要通过指针来指向被声明的etimer时间。

        Contiki etimer库的API 如下所示。如同前面的那些定时器,事件定时器总是调用etimer_set()初始化,设置定时器从当前时间开始到指定时间的延时。etimer_reset() 可以从之前的到期时间启动定时器。Etimer_restart()从当前时间重启定时器,他们都使用相同的时间间隔,且最初都是由etimer_set()设置。etimer_reset()和etimer_restart()的区别在于:前者的时间从以前的到期时间,而后者的时间从当前时间开始,从而允许时间推移。一个事件定时器可以被etimer_stop()停止,这意味着etimer立即过期,而不会发布一个定时器事件。Etimer_expired()用来检查一个etimer时间是否过期。

    注意:定时器事件被发送到contiki进程用来调度事件定时器。(太绕了,暂时这么理解吧)如果一个事件定时器在回调函数或者其他的contiki进程被设置, PROCESS_CONTEXT_BEGIN() 和PROCESS_CONTEXT_END()可以被用来临时改变进程上下文。在processes中有更多关于进程管理的信息。

    下面是一个简单的例子:如何用etimer每秒安排process运行一次。

         Etimer库不能从中断中安全使用。

Etimer库的API:

void etimer_set(struct etimer *t, clock_time_t interval) :启动定时器。

void etimer_reset(struct etimer *t) :从以前到期时间重启定时器。

void etimer_restart(struct etimer *t) :从当前时间重启定时器。

void etimer_stop(struct etimer *t):停止定时器。

int etimer_expired(struct etimer *t):检查时间是否到期。

int etimer_pending() :检查是否有非过期的事件计时器。

clock_time_t etimer_next_expiration_time():得到下一个事件定时器过期时间。

void etimer_request_poll() :通知etimer库,系统时间已经改变。

     设置一个事件定时器,让process每秒执行一次。

PROCESS_THREAD(example_process, ev, data)

 {

   static struct etimer et;

   PROCESS_BEGIN();

   /* Delay 1 second */

   etimer_set(&et, CLOCK_SECOND);

   while(1) {

     PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

     /* Reset the etimer to trig again in 1 second */

     etimer_reset(&et);

     /* ... */

   }

   PROCESS_END();

 }

Porting the Etimer Library

        Etimer库实现的核心是/sys/etimer.c,与平台无关,但需要回调etimer_request_poll()来处理事件定时器。这允许事件定时器到期时,从低功耗模式唤醒。Etimer库提供三种功能:

       etimer_pending() 检查是否有任何非过期事件定时器。

       etimer_next_expiration_time()得到下一个事件定时器过期时间。

       etimer_request_poll() 通知etimer库,系统时间已经改变,一个etimer已经过期。这个函数从中断调用是安全的。

    时钟模块处理系统时间之后,通常还要回调etimer库。(这句也不太懂,原文The implementation of the clock module usually also handles the callbacks to the etimer library since the module already handles the system time)可以通过定期调用etimer_request_poll()简单地实现,或者利用etime_next_expiration_time(),或者在需要时通知etimer库。

The Ctimer Library

        Contiki ctimer库提供了一个定时器机制,当回调时间过期时,调用指定的函数。在时钟模块中Ctimer库使用clock_timer()获得当前的系统时间。

        Contiki ctimer库的API如下所示,他和etimer的库很像。区别在于ctimer_set()需要一个回调函数指针和数据指针作为参数。当ctimer到期时,他将数据指针作为参数调用回调函数。下面的代码展示了ctimer如何安排回调函数每秒调用一次。

    注意:尽管这个回调定时器指定回调函数,但是ctimer安排进程上下文的回调。除非你确定回调定时器如何工作,否则不采取任何特定的进程上下文回调。

        Ctimer库从中断中使用不是安全的。

Ctimer库的API:

void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr):启动定时器。

void ctimer_reset(struct ctimer *t) :从以前到期的时间重启定时器。

void ctimer_restart(struct ctimer *t) :从当前时间重启定时器。

void ctimer_stop(struct ctimer *t) :停止定时器。

int ctimer_expired(struct ctimer *t) :检查定时器是否过期。

    设置一个ctimer,每秒调用一次函数。

static void

 callback(void *ptr)

 {

   ctimer_reset(&timer);

   /* ... */

 }

 void

 init(void)

 {

   ctimer_set(&timer, CLOCK_SECOND, callback, NULL);

 }

Porting the Ctimer Library

         Ctimer库的实现使用etimer库,不需要近一步移植。

The Rtimer Library

        Contiki rtimer库提供了实时任务调度和执行(可预测执行时间)。Rtimer使用自己的时钟模块调度,允许更高的时钟分辨率。RTIMER_SECOND()函数以嘀嗒的形式获取当前系统时间,RTIMER_SECOND指定每秒的时钟节拍数。

    不像其他的contiki定时器库,实时任务抢占正常执行的进程,立即执行任务。在实时任务中能做什么是有约束的,因为大多数函数不处理具有优先权的任务。中断安全函数例如asprocess_poll()在实时任务中总是安全的,但是任何可能的冲突与正常执行必须是同步的。

    实时任务可以使用函数RTIMER_TIME(struct rtimer *t)在任务被执行的最后一次检索所需的执行时间。

    这里没有例子,这里的文档解释的是从2007年以前的API,是误导。

Porting the Rtimer Library

        Rtimer库实现的核心是/sys/rtimer.c,与平台无关,取决于rtime-arch.c处理平台的相关功能,如调度等。下面三个功能在移植rtimer库是需要实现。

        rtimer_arch_init()被rtimer库调用,初始化rtimer代码。

        rtimer_arch_now()用来获取当前的系统实时时间。

        rtimer_arch_schedule()需要一个参数---唤醒时间,请求唤醒回调。

    除了这三个函数,rtimer架构代码需要定义RTIMER_ARCH_SECOND作为每秒的滴答数,rtimer_clock_t数据类型用于rtimer时间,这些都是在rtimer-arch.h文件中声明的。

Rtimer库与平台相关的函数:

RTIMER_ARCH_SECOND:每秒的滴答数。

void rtimer_arch_init(void):初始化rtimer。

rtimer_clock_t rtimer_arch_now():获取当前时间。

int rtimer_arch_schedule(rtimer_clock_t wakeup_time):安排一个rtimer_run_next()调用。

Conclusions

        Contiki包含一组定时器库,应用于contiki核心模块和应用程序。定时器库用来检测超时、安排处理事件和函数回调来让系统处理一些其他事情,或者进入低功耗模式一段时间,在这之后恢复执行。


    
[2] 数据结构(五)之单链表的操作(补充)
    来源: 互联网  发布时间: 2014-02-18
数据结构(5)之单链表的操作(补充)
1 前言

    上次我们讲到单链表的存储和一些简单的算法,今天我们来学习一下单链表的初始化和销毁操作。

2 详述 2.1 单链表的整表创建

思路:

·声明一结点p和计数器变量i;

·初始化一空链表L;

·让L的头结点的指针指向NULL,即建立一个带头结点的单链表;

·循环:

    生成一新结点赋值给p;

    随机生成一数字赋值给p的数据域p->data;

   将p插入到头结点与前一新结点之间。

如图:

实现代码如下:

/*随机产生n个元素的值,建立带头结点的单链线性表L(头插法)*/
void CreateListHead(LinkList *L,int n)
{
    LinkList p;
    int i;
    srand(time(0));       /*初始化随机数种子*/
    *L = (LinkList) malloc (sizeof(Node));
    (*L)->next = NULL;     /*先建立一个带头结点的单链表*/
    for(i = 0;i<n;i++)
    {
        p = (LinkList) malloc (sizeof(Node));     /*生成新结点*/
        p->data = rand()%100+1;      /*随机生成100以内的数字*/
        p->next = (*L)->next;
        (*L)->next = p;        /*插入到表头*/
    }
}

还有一种尾插法,比较符合我们的思路,代码实现:

/*随机产生n个元素的值,建立带头结点的单链表L(尾插法)*/
void CreateListTail(LinkList *L,int n)
{
    LinkList p,r;
    int i;
    srand(time(0));        
    *L = (LinkList) malloc(sizeof(Node));
    r = *L;      /*r指向尾部的结点*/
    for (i = 0;i<n;i++)
    {
        p = (Node *) malloc(sizeof(Node));     /*生成新结点*/
        p->data = rand()%100+1;      /*随机生成100以内的数字*/
        r->next = p;       /*将尾端结点的指针指向新结点*/
        r = p;      /*将当前的新节点指向传给r结点*/
    }
    r->next = NULL;    /*表示当前链表结束*/
}

解释:

r->next = p图解:

r = p图解:

2.2 单链表的整表删除

思路:

·声明一结点p和q;

·将第一个结点赋值给p;

·循环

    将下一个结点赋值给q;

    释放p;

    将q赋值给p。

实现算法:

/*初始条件:顺序线性表L已存在,操作结果:将L重置为空表*/
Status ClearList(LinkList *L)
{
    LinkList p,q;
    p = (*L)->next;        /*p指向第一个结点*/
    while(p)        /*没到表尾*/
    {
        q = p->next;
        free(p);
        p = q;
    }
    (*L)->next = NULL;     /*头结点指针域为空*/
    return OK;
}

2.3 单链表结构与顺序结构存储结构优缺点

2.4 其它类型的链表 2.4.1 静态链表

有些高级语言没有指针,这时候我们要让数组的元素由两个数据域组成,data和cur,数据域data用来存放数据元素;游标cur相当于存放单链表的next指针,存放该元素的后继在数组中的下标。我们把这种数组描述的链表叫做静态链表。

2.4.2 循环链表

将单链表中终端结点的指针由空指针改为指向头结点,就使得整个单链表形成一个环。这种头尾相接的单链表成为单循环链表,简称循环链表(cirular linked list)。

2.4.3 双向链表

双向链表(double linked list)是在单链表中的每个结点中,再设置一个指向其前驱结点的指针域。

2.5 总结

用下图简单的来介绍一下线性表部分的内容:

3 结语

    以上是所有内容,希望对大家有所帮助。


    
[3] IT English Collection(九) of Objective-C
    来源: 互联网  发布时间: 2014-02-18
IT English Collection(9) of Objective-C
1 前言

    今天我们来解除一篇有关Objective-C的介绍文章,详情如下。

2 详述 2.1 原文

    Objective-C defines a small but powerful set of extensions to the ANSI C programming language that enables sophisticated object-oriented programming. Objective-C is the native language for Cocoa programming—it’s the language that the frameworks are written in, and the language that most applications are written in. You can also use some other languages—such as Python and Ruby—to develop programs using the Cocoa frameworks. It’s useful, though, to have at least a basic understanding of Objective-C because Apple’s documentation and code samples are typically written in terms of this language.

    Because Objective-C rests on a foundation of ANSI C, you can freely intermix straight C code with Objective-C code. Moreover, your code can call functions defined in non-Cocoa programmatic interfaces, such as the BSD library interfaces in /usr/include. You can even mix C++ code with your Cocoa code and link them into the same executable.

2.2 生词

extension [ɪk'stenʃ(ə)n; ek-]  n. 延长;扩大

sophisticate [sə'fɪstɪkeɪt] vt. 弄复杂

in terms of  依据;按照

rest on 停留在;依靠

intermix [ɪntə'mɪks] vt. 使…混杂;使…混合

Moreover [mɔːr'əʊvə] adv. 而且;此外

programmatic [prəʊɡrə'mætɪk] 纲领性

executable [ɪg'zekjʊtəb(ə)l; eg-] n. 可执行的;可实行的

3 结语

    以上是所有内容,希望对大家有所帮助。


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3