xenomai 编程要点:

  1. 不要在xenomai线程中调用影响实时性的API:
    xenomai实时任务中不建议调用系统调用( sleep open close read write ioctl socket printf new malloc 等等),这些系统调用会让 xenomai switching to secondary mode (because of the plain linux syscalls) and then handeled by the linux scheduler(另外,系统调用会产生CPU软中断并陷入内核态,内核中可能会因等待外部设备响应或是DMA等操作破坏实时性). 如图所示:

xenomai 编程要点:_第1张图片

如果在程序确实需要动态分配内存(new),则可以考虑使用memory poll 即使用自定义的 allocator,例如使用 TLSF allocator。

2 . 在 xenomai 中调用 boost::is_service::poll & boost::is_service::run 会影响实时性。
3 . cat /proc/xenomai/stat
如果 MSW 值一直在增加说明你在实时任务中调用了非实时函数破坏了实时性(xenomai会在两个核之间切换)。

解决方式,在 xenomai 线程中创建一个 std::thread(非实时线程),将 io_service.run & poll 等调用放在该线程中 (然后引出了第四个点…)。

4 . 不要在 xenomai 实时线程和 std::thread 线程中公用一个 mutex 锁!!!(在xenomai dual kernel 配置中,mutex 锁不能跨 kernel,所以共享资源可能会有问题!)

The Cobalt co-kernel does not share any lock with the regular Linux kernel when dealing with real-time activities. see link: https://xenomai.org/start-here/#Single_or_dual_kernel_configuration

xenomai 配置为 dual kernel 时,由于存在两个调度核,而这两个调度核不能共享一个mutex,在分布在两个核上的多线程操作对象的时候,会出现 lock 失效,导致多线程资源操作问题。

例如,将共享的资源挪到非实时线程(std::thread)中出现另外一个问题,在创建 std::string 的时候出现的:

terminate called after throwing an instance of 'std::length_error'
    what():  basic_string::_S-create
Aborted (core dumped)

5 . 实时线程和非实时线程可以通过 rtipc 发送和接受数据,避免出现 switch to secondary mode.

6 . 所以最好的办法就是,使用 PREEMPT_RT 和 xenomai3 的单核模式,只不过实时性稍微差一点点而异。

关于 dual kernel xenomai 和 PREEMPT_RT 的性能说明,可以看这里: http://linuxgizmos.com/real-time-linux-explained

更多注意点,see here:

  • http://blog.bbv.ch/2012/07/16/usage-of-dynamic-memory-in-a-real-time-system/
  • https://rt.wiki.kernel.org/index.php/HOWTO:_Build_an_RT-application
  • http://www.xenomai.org/pipermail/xenomai/2017-January/037081.html
  • http://retis.sssup.it/~lipari/courses/str07/xenomai-handout.pdf
  • http://git.net/ml/linux.real-time.xenomai.users/2005-12/msg00024.html
  • https://moodle-arquivo.ciencias.ulisboa.pt/1415/pluginfile.php/105637/mod_resource/content/2/SETR_xenomai.pdf

你可能感兴趣的:(xenomai)