linux 内核3.8,[Beaglebone] BBB迁移到linux 3.8实时内核

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

动机

之前使用TI SDK提供的3.2标准内核,在和fpga进行高速通信时出现CPU 100%中断响应延迟严重(偶尔>50ms)造成数据丢包。为达到严格的中断响应速度(<10ms),亟需实时操作系统内核支持。方案有两个:Standard Linux -> RTOS Linux

Standard Linux -> other RTOS( RT-Thread, freeRTOS,uc/os-ii等)

当前在不牺牲功能性的情况下直接打上内核补丁是最好的方案。

关于RT-Preempt内核

The standard Linux kernel only meets soft real-time requirements: it provides basic POSIX operations for userspace time handling but has no guarantees for hard timing deadlines. With Ingo Molnar’s Realtime Preemption patch (referenced to as RT-Preempt in this document) and Thomas Gleixner’s generic clock event layer with high resolution support, the kernel gains hard realtime capabilities.

The RT-Preempt patch has raised quite some interest throughout the industry. Its clean design and consequent aim towards mainline integration makes it an interesting option for hard and firm realtime applications, reaching from professional audio to industrial control.

The RT-Preempt patch converts Linux into a fully preemptible kernel. The magic is done with:Making in-kernel locking-primitives (using spinlocks) preemptible though reimplementation with rtmutexes

Critical sections protected by i.e. spinlock_t and rwlock_t are now preemptible. The creation of non-preemptible sections (in kernel) is still possible with raw_spinlock_t (same APIs like spinlock_t)

Implementing priority inheritance for in-kernel mutexes, spinlocks and rw_semaphores. For more information on priority inversion and priority inheritance please consult Introduction to Priority Inversion

Converting interrupt handlers into preemptible kernel threads: The RT-Preempt patch treats soft interrupt handlers in kernel thread context, which is represented by a task_struct like a common userspace process. However it is also possible to register an IRQ in kernel context.

Converting the old Linux timer API into separate infrastructures for high resolution kernel timers plus one for timeouts, leading to userspace POSIX timers with high resolution.

git:https://github.com/beagleboard/kernel/tree/3.8-rt,beagleboard官方维护内核库

Device Tree

Device Tree在ARM社区的推行来源于Linus对长期以来内核代码里ARM架构上充斥的相关板级驱动代码、平台相关的垃圾代码无情谩骂,长久以来arch/arm/目录下的诸多platform级描述对内核来说就是一堆×××,因此ARM社区借鉴了PowerPC社区Device Tree概念。

“The Device Tree is a data structure for describing hardware. Rather than hard coding every detail of a device into an operating system, many aspect of the hardware can be described in a data structure that is passed to the operating system at boot time.”

Device Tree代替了以前的硬件platform上的写法,而是用树形节点描述硬件,对硬件的管教分配、时序、资源(中断、DMA通道、物理和虚拟空间等)进行描述,然后自动probe在对应各自模块的驱动下进行探测,解析硬件描述信息,完成platform或者其上的device驱动的注册。

原platform驱动模型下的实现

/* In the foo_platform_data.h file:*/

struct foo_platform_data {

u32 bar;

};

/* In the board file:*/

struct foo_platform_data foo_pdata {

.bar = 5,

};

struct platform_device foo_dev {

.name = "foo",

.id = -1,

.dev.platform_data = &foo_pdata,

};

/* And in the board setup function*/

platform_device_register(&foo_dev);

/* The driver gets access to the platform data in the probe function.*/

static int foo_probe(struct platform_device *pdev)

{

struct foo_platform_data *pdata;

pdata = pdev->dev.platform_data;

if (pdata == NULL) /* ERROR */

...

/* access pdata->bar for configuration */

...

}

static struct platform_driver foo_driver = {

.probe = foo_probe,

....

.driver = {

.name = "foo",

},

...

};

module_platform_driver(&foo_driver);

设备树下的实现

This method no longer works; in a DT based system what you have to do come up with device driver bindings, which contain the configuration the driver requires.

You must add a device node in board.dts under the on-chip-peripherals(OCP) device node:

foo {

compatible = "corp,foo";

bar = <5>;

};

No change in the board file (generic anyway) needs to be made, but the device driver must be updated to support the DT method, with something similar to the following:

static struct foo_platform_data *

foo_parse_dt(struct platform_device *pdev)

{

struct device_node *node = pdev->dev.of_node;

struct foo_platform_data *pdata;

pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);

if (pdata == NULL)

return NULL; /* out of memory */

/* no such property */

if (of_property_read_u32(node, "bar", &pdata->bar) != 0)

return NULL;

/* pdata->bar is filled in with 5 */

return pdata;

}

static int foo_probe(struct platform_device *pdev)

{

struct foo_platform_data *pdata;

pdata = pdev->dev.platform_data;

if (pdata == NULL) /* ERROR */

...

/* access pdata->bar for configuration */

...

}

static struct platform_driver foo_driver = {

.probe = foo_probe,

....

.driver = {

.name = "foo",

},

...

};

module_platform_driver(&foo_driver);

其他

3.2-Standard迁移到3.8-RT内核需要变化的驱动包括LCD7和GPMC驱动(包括DMA),两块驱动都以Device Tree Overlay的方法加载。此外,配套Device tree的U-Boot需要升级,老版本U-boot不支持Device Tree & Overlay。

3.8内核实时性的检验

因为正好有FPGA端需要处理的中断源,因此使用示波器跑一下脉宽就可以检验。

参考https://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO

https://github.com/beagleboard/kernel/tree/3.8-rt

http://elinux.org/BeagleBone_and_the_3.8_Kernel

http://devicetree.org/mediawiki/index.php?title=Device_Tree_Usage

http://valentfx.com/wiki/index.php?title=LOGI_-_BBB_GPMC_Bus-_HW

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值