• 易迪拓培训,专注于微波、射频、天线设计工程师的培养
首页 > 无线通信 > 技术文章 > 嵌入式Linux下的实时性增强方案

嵌入式Linux下的实时性增强方案

录入:edatop.com     点击:

2.2 内核可抢占性设计

在Linux标准内核中,因不具有可抢占性和导致较大的延迟,增加内核的可抢占性能,可提高系统的实时任务处理能力。当前修改Linux内核提高实时性的方法主要有增加抢占点和改造成抢占式内核两种方法。增加抢占点方法是在内核中插入抢占点,通过检测抢占点调度标志来决定是否进行实时任务的调度。采用这种方法,在检测抢占点标志时大大增加了系统开销,因此本方案采用直接改造Linux内核的方法,通过修改自旋锁为互斥锁来提高内核的可抢占性[5]。即借鉴Ingo Molnar的实时补丁的实时化方法,使用mutex互斥锁来替换spinlock自旋锁。使用mutex替换spinlock,可以让spinlock可抢占。起初spinlock不可抢占性设计目的是避免死锁,可抢占性设计可能导致竞争者与保持者的死锁局面。中断处理函数中也可以使用spinlock,如果spinlock已经被某一进程保持,则中断处理函数无法进行,从而形成死锁。中断线程化以后,中断线程将挂在等待队列上并放弃CPU让别的线程或进程来运行,让每个spinlock都有一个等待队列,该等待队列按进程或线程优先级排队,如果一个进程或线程竞争的spinlock已经被另一个线程保持,它将把自己挂在该spinlock的优先级化的等待队列上,然后发生调度把CPU让给别的进程或线程。mutex替换spinlock后,spinlock结构定义如下代码:

typedef struct {

struct rt_mutex lock; //新的实时互斥锁

unsigned int break_lock;

} spinlock_t;

其中struct rt_mutex结构如下:

struct rt_mutex {

raw_spinlock_t wait_lock;

struct plist wait_list; //优先级等待队列

struct task_struct *owner; //拥有该锁进程的信息

int owner_prio;

… …

};

在如上代码中,类型raw_spinlock_t就是原来的spinlock_t。即代码中的spinlock_t就是新设计的自旋锁。rt_mutex结构中,wait_list字段为优先级等待队列。在mutex使用中,当遇到锁住的临界资源时,任务被挂起到wait_list中,临界资源解锁时等待任务被激活。临界资源被保护的同时可以抢占。

由于Linux内核底层的临界资源是不可抢占的,使用mutex替换spinlock的过程中,这部分可以保留,仍由不可抢占的spinlock保护,如:保护硬件寄存器的锁、调度器的运行队列锁等。不可抢占的spinlock被重新命名为raw_spinlock_t。spin_lock被宏定义为:

#define spin_lock(lock) PICK_OP(raw_spinlock_t,spin,_lock,lock)

函数PICK_OP支持两种锁共存机制,PICK_OP在编译阶段将锁操作转化为mutex或者spinlock:

#define PICK_OP(type, optype, op, lock)

do {

if (TYPE_EQUAL((lock), type))

_raw_##optype##op((type *)(lock));

else if (TYPE_EQUAL(lock, spinlock_t))

//调用gcc的内嵌函数__builtin_types_compatible_p()

_spin##op((spinlock_t *)(lock));

else __bad_spinlock_type();

} while (0)

#define TYPE_EQUAL(lock, type)

__builtin_types_compatible_p(typeof(lock), type *)

gcc的内嵌函数__builtin_types_compatible_p用于判断一个变量的类型是否为某指定的类型,如果类型为spinlock_t,将运行函数_spin_lock;类型为raw_spinlock_t,将运行函数_raw_spin_lock。

实时rt_mutex在具体应用中,一个高优先级任务抢占该锁的同时,把先前的锁拥有者添加到互斥锁等待队列中,并在当前拥有该锁的任务task_struct中标记等待该锁的所有任务;反之,不能得到该锁就把当前任务添加到锁的优先级等待队列中,直到唤醒执行。为了防止优先级逆转,可以改变锁的当前拥有者的优先级为锁的等待队列中任务的最高优先级。

rt_mutex可以使高优先级任务利用抢占锁进入临界区,这样内核不可抢占区的数量和范围大大缩小,内核可抢占性有了很大的提高,且降低了实时高优先级任务的抢占延迟,改善了系统的实时性能。

2.3 可抢占大内核锁设计

大内核锁BKL(Big Kernel Lock)实质上也是spinlock,它用于保护整个内核,该锁保持时间较长,对系统的实时性能影响很大[6]。采用Ingo Molnar的实时化方法,BKL使用semaphore实现,结构定义如下代码:

struct semaphore {

atomic_t count;

struct rt_mutex lock; //实时互斥锁的使用

};

由结构体发现,在BKL实现中利用了实时互斥锁rt_mutex,在改进后的spinlock结构体spinlock_t中也利用了实时互斥锁rt_mutex,因此可抢占大内核锁和新的spinlock共用了低层的处理代码。使用semaphore之后,大内核锁就可抢占了。

3 内核实时性测试

针对Linux2.6内核,本文并没有作出对内核调度算法的修正,只是探讨了中断运行机制、自旋锁及大内核锁技术在系统实时性能上的局限性,所以实验测试主要测试中断延迟时间和任务响应时间。实验环境: Intel 2 GHz CPU,256 DDR内存,Kernel 2.6.22版本。测试结果如表1所示。

由表可知,在中断服务程序中写入标记,测试中断触发至中断服务程序执行平均响应时间,标准Linux2.6内核平均中断响应时间为182 μs,改进后Linux2.6内核为14 μs。采用开源软件LMbench3.0 测试系统任务调度延迟时间,标准Linux2.6内核平均任务响应时间为1 260 μs,改进后Linux2.6内核为162μs。由此可见,改进策略在一定程度上大大减小了中断延迟和任务调度时间,有利于改善移动机器人任务处理的实时性能。

本文基于Linux2.6内核的关中断、中断优先级、内核的不可抢占性以及大内核锁保持时间过长等问题进行了实时性分析,提出了相应的改进方法。利用中断线程化、互斥锁的应用及大内核锁的改进等技术提高了系统的实时性能,降低了内核中断延迟和调度延迟。改进后的内核在移动机器人控制器平台中有很好的应用价值,提高了机器人控制的实时性能。

来源:维库开发网

上一篇:基于AD9957的多波形雷达信号产生器
下一篇:基于MPC828O的网络通信平台的实现

手机天线设计培训教程详情>>

手机天线设计培训教程 国内最全面、系统、专业的手机天线设计培训课程,没有之一;是您学习手机天线设计的最佳选择...【More..

射频和天线工程师培训课程详情>>

  网站地图