通信系统离不开通信协议,而定时器是保证通信协议正常运行的基本要素之一。在目前的通信系统中, 通常硬件只提供几个定时器, 大量的定时器必须由软件提供,而软件提供方法只有两种: 由操作系统提供或由应用程序提供[1]。其中,操作系统提供的定时器具有定时精度高、实时性好等优点。
LTE(Long Term Evolution)项目是3G的演进,它改进并增强了3G的空中接口技术,在20 MHz带宽上能够提供下行100 Mb/s、上行50 Mb/s的峰值速率,同时对数据传输的可靠性提出了更高的要求[2]。无线链路控制RLC(Radio Link Control)层作为协议栈层次结构中的L2层之一,主要是提供可靠的数据传输链路。LTE系统是一个对实时性要求较高的系统,因此TD-LTE 射频一致性测试仪表的开发采用Nucleus Plus操作系统。该操作系统具有实时响应、抢先式、多任务等开放特性,在通信设备、航空航天、医疗器械、工业控制系统等实时性要求高的领域得到了广泛应用。
1 Nucleus Plus和定时器
1.1 Nucleus Plus简介
Nucleus Plus 是美国著名RTOS 厂商ATI 公司(Accelerated Technology Inc)在嵌入式实时多任务操作系统Nucleus 基础上,为嵌入式应用而设计的一个实时、任务抢先式、多任务操作系统内核。大约95%的Nucleus Plus 内核代码是用ANSIC编写的,非常便于移植且可以很容易地应用到大多数的处理器中[3]。该内核提供任务间通信、任务调度、同步、内存管理、定时器和中断等操作系统最基本服务,将任务组织起来构成完整的系统的则是其中的任务间通信功能[4]。Nucleus Plus操作系统在系统初始化过程中为LTE系统协议栈每个子层创建了一个对应的任务和队列,且不同的任务有不同的优先级,队列则作为消息的载体提供了传输消息的机制。
1.2 RLC层定时器介绍
LTE系统中的RLC层位于协议栈接入层的媒体介入控制MAC(Media Access Control)层和分组数据汇聚协议PDCP(Packet Data Convergence Protocol)层之间,主要执行组装PDU、重组SDU、重传PDU等功能。它支持3种数据传输模式:透明模式(TM)、非确认模式(UM)和确认模式(AM)。为保证无线链路的正常运行以及链路传输的高速性,RLC层作为LTE系统核心通路的重要组成部分,定义了3种定时器,即重排序定时器(t-Reordering)、状态禁止定时器(t-StatusProhibit)和轮询重传定时器(t-PollRetransmit)。第一种定时器在UM和AM模式下都存在,后两种定时器只在AM模式下存在。这三种定时器在RLC层的作用都至关重要,是不可缺少的。其中,t-Reordering可以保证数据按序递交给高层;t-StatusProhibit控制发送状态 PDU的时间间隔,该定时器运行期间不能发送状态 PDU;t-PollRetransmit可以避免过分频繁地要求对等层发送状态 PDU,以保证其他数据的正常接收、发送以及数据传输速率。根据3GPP通信协议,各模式下的定时器都有各自的开启条件、关闭条件以及溢出处理方式。
2 定时器设计
在单实例模式下,为方便起见,RLC层的定时器和协议栈其他层一样,都是在Nucleus Plus操作系统初始化时创建的。但实际存在SRB和一个或多个DRB共存的情况。为保证同时建立多个承载,LTE系统的RLC层必须支持多实例功能,且每个实例下的RLC实体必须拥有自己独立的一套参数。如果某实例下RLC层被配置为UM模式,则其只拥有一个重排序定时器;如果某实例下RLC层被配置为AM模式,则其包含一个重排序定时器、一个状态禁止定时器和一个轮询重传定时器。在多实例模式下,由于最初并不知道要建立哪些无线承载及数量,如果在系统初始化时就创建多个实例下的定时器,定会导致资源的浪费。为防止多实例模式中RLC层各实例下的定时器出现混乱,在建立RLC实体时创建属于本实例的定时器,而不是在系统初始化时创建定时器。例如在建立数据传输模式为AM模式,实例号为v_rlc_rbId 的承载时,创建重排序定时器,且表示为s_rlc_amInst[v_rlc_rbId].t_rlc_t_reordering。这样既不会浪费资源,也能很清晰明了地表示各实例下的定时器。
在处理定时器超时函数时,由于在MAC层设置了软中断,如果在定时器超时后直接调用定时器超时函数,超时函数、数据搬移完成后,操作系统可能直接跳转到MAC层执行相关操作,而不会立即返回RLC层断点处继续未完的操作。这样就会导致RLC层的数据堆积,不利于系统快速有效地运行。为避免这种情况,先调用协议栈一个整体的超时函数rtos01_09timerExpirationRoutine,该函数运用switch语句,通过判断分支,将超时的任务发到RLC层的队列中。例如,如果此时是AM传输模式下的重排序定时器超时,根据信令ID OP_T_rlc_t_am_reordering(为每种定时器分配了一个信令标示)找到相应的case语句,并执行此语句后的操作,即将处理重排序定时器超时的任务发到Nucleus Plus 操作系统,为RLC层创建的队列中,并将任务放在队列的最前面,保证该消息能尽快地被处理。发送的消息要携带当前状态(所举例中应该是AM传输状态)和RBID(无线承载标示),RBID用以说明是哪一个无线承载下的定时器超时。
多实例模式下,要进行消息的处理,首先必须知道该消息属于哪个实例以及该实例所处的状态,然后执行该状态下对应的这条消息的处理函数,处理结束后便跃迁到相应的状态[5]。针对存在多实例模式的情况, RLC层引入了一个多实例管理模块,它负责将发到RLC层的任务转到相应的进程实例下,多实例结构如图1所示。
协议栈的开发是基于有限状态机的思想,收到消息后,就会对消息进行相应的处理。当操作系统检测到RLC层任务被激活后便跳转至RLC状态机,具体过程是:从RLC队列最前面开始读取定时器超时的消息,多实例管理模块会解析出当前消息的RBID,将其赋给instanceID,用其作为各实例的区分,然后通过有效的processID获得当前的进程状态机入口函数,有效的instanceID获得此实例当前的状态(本例中为AM传输状态)之后,状态机进入相应的状态分支,通过信令ID处理重排序定时器超时的函数。该消息处理完后,RLC状态机会继续从RLC队列中读取消息进行处理,直至队列为空。队列为空时,RLC层任务会被挂起,并跳出本层状态机,控制权限交还给操作系统。当操作系统检测到其他层任务被激活后,便会跳转至其他层状态机进行消息处理。操作系统处理定时器超时的消息流程如图2所示。
3 定时器模块的改善
协议中涉及的对定时器的操作有创建、开启、停止、重启、重设和删除功能。Nucleus Plus 提供的功能函数只可以实现对定时器的创建、开启、停止和删除等基本操作,如果重启定时器时需改变一个定时器的长度,运用这些功能函数实现的方法为:先关闭该定时器,再删除该定时器, 最后重新创建一个新长度的定时器,并将启动的新定时器加入Nucleus Plus系统中启动定时器链表。很明显,整个实现过程比较繁琐, 而且容易出错。在LTE系统协议栈的开发中,为了方便定时器的使用,设计了一个新的功能函数(RTOS02_01RestartTimerChangeable)。即将重启定时器长度改变和未改变合并在一个函数中,即在使用时通过该函数的形参的不同分别实现定时器长度未改变和改变了两种情况。首先定义如下两个宏定义:
#define RTOS_RESTART_TIMER(timer)
osi_start_timer_change
(timer,0,0)#define RTOS_RESTART_TIMER_CHANGEABLE
(timer,init_time,loop_time)
osi_start_timer_change(timer,init_time,loop_time)
当需重启定时器的长度未改变时, 调用RTOS_REST-
ART_TIMER(timer);当重启定时器长度改变时,调用RTOS_
RESTART_TIMER_CH-ANGEABLE(timer,init_time,loop_
time)。
定时器重启的函数如下:
T_osi_STATUS osi_start_timer_change(T_osi_HANDLE handle,
u32 init_time,u32 loop_time)
{
T_osi_STATUS v_status = NU_Control_Timer((VOID*)
(handle),NU_DISABLE_TIMER);
return rtos02_01RestartTimerChangeable((VOID *)handle,
((init_time)/RTOS_TIEMBASE),((loop_time)/RTOS_
TIEMBASE));
}
其中,设计的新的功能函数如下:
STATUS rtos02_01RestartTimerChangeable(NU_TIMER *app_
timer,UNSIGNED init_time, UNSIGNED loop_time)
{
R1 TM_APP_TCB *timer;
UNSIGNED time;
time=loop_time;
timer = (TM_APP_TCB *) app_timer;
TCT_System_Protect();
/* Determine what type of request is present. */
if (!timer -> tm_enabled)
{
if (init_time>0) /* Use new timer length */
time = init_time;
else /*Use the old timer length*/
time = timer -> tm_initial_time;
timer -> tm_enabled = NU_TRUE;
TMC_Start_Timer(&(timer -> tm_actual_ti-mer),
time);
}
TCT_Unprotect();
return(NU_SUCCESS);
}
从上述函数可看出,必须在定时器未运行时,才能对其进行操作。在调用定时器重启的函数时,如果形参init_time>0,则说明定时器的长度需要修改,需重启定时器时要用新的长度;否则,重启定时器时还是用原来的定时器长度。当重启的定时器的长度确定好后,便调用函数TMC_Start_Timer重启该定时器。该函数的实现过程如下:整个函数大体分为两部分,第一部分是已启动的定时器链表为空的情况,另一部分则是已有定时器启动的情况。第一种情况只需将已启动的定时器链表的指针指向该定时器的(任务控制块)TCB结构体,此时该定时器处于链表头,将根据定时器的定时长度设置实际的计数定时器结构,并开启定时器。第二种情况,首先需确定系统没有执行要重启定时器的超时任务。若正在执行超时任务,为保证系统正常运行,不可试图调整定时器链表。在确定没有运行超时任务时,则可以从链表头开始搜索,通过比较要加入的定时器的长度和链表中每个定时器剩余时间,将该定时器加入链表中合适的位置。当定时器超时后,操作系统便根据章节2中的超时过程进行处理。
文中结合Nucleus Plus操作系统主要给出了项目TD-LTE射频一致性测试仪表中,协议栈RLC层多实例模式下定时器的实现机制。操作系统为协议栈每个层创建了一个对应的任务和队列,并将队列作为消息载体实现各任务间的通信。本文将定时器超时也作为一个消息发到队列中,系统处理完超时函数后会返回断点继续之前未完的操作,避免了数据堆积,有利于系统快速正常地运行。同时,通过改善操作系统中定时器的模块可以更方便地实现对定时器的控制。
参考文献
[1] 邹仕祥.通信系统中大量定时器的设计与分析[J].计算机应用,2005,25(11):2715-2719.
[2] 沈嘉.LTE的技术创新与挑战[J].电子技术应用,2009,35(6):7-13.
[3] Wu Liming, Li Dongdong, Wang Guitang. Design of realtime image acquisition system of IC wafer[C]. International Conference on Convergence Information Technology,2007.
[4] 0001026-001 Rev. 102-2000. Nucleus PLUS Reference Manual[S]. 2000.
[5] 宋茂强.通信软件设计基础(第2版)[M].北京:北京邮电大学出版社,2008.