linux 内核3.8,[Beaglebone] BBB迁移到linux 3.8实时内核
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
總結
以上是生活随笔為你收集整理的linux 内核3.8,[Beaglebone] BBB迁移到linux 3.8实时内核的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云RPA(机器人流程自动化)干货系列
- 下一篇: 简单弄一个-个人主页