定期线程在Xenomai中实时失败 [英] Periodic thread fails real-time in Xenomai

查看:304
本文介绍了定期线程在Xenomai中实时失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个周期线程,该线程在模拟输出上输出平方信号.我正在使用Xenomai API中的Posix Skin和Analogy.

I'm creating a periodic thread which outputs a square signal on an analogic output. I'm using Posix Skin and Analogy from the Xenomai API.

我使用示波器测试了我的代码的实时性能,并查看了方波信号(其频率为1kHz)的延迟.我应该达到< 100us延迟.但是,该信号会受到常见的中断信号(例如移动鼠标,启动新程序等)的强烈干扰(延迟超过250us).

I tested the real-time performance of my code using an oscilloscope and looking at the latency on the square signal (whose frequency is 1kHz). I am supposed to achieve <100us latency. However, the signal is strongly (>250us latency) perturbated by common interruption signals, like moving the mouse, starting a new program, etc.

我的makefile中的标志设置如下:

The flags in my makefile are set up as such:

gcc  -I/usr/xenomai/include -D_GNU_SOURCE -D_REENTRANT -D__XENO__ -I/usr/xenomai/include/posix    
main_posix.c -Xlinker -rpath -Xlinker /usr/xenomai/lib -Wl,@/usr/xenomai/lib/posix.wrappers 
-L/usr/xenomai/lib -lpthread_rt -lxenomai -lpthread -lrt  -lanalogy -lrtdm -o main_posix

这是代码:

#define PERIOD 1e6 
#define FILENAME "analogy0"
#define ANALOG_SUBD 1
#define CHANNEL 0
#define SCAN_SIZE 2
#define DELAI 5

static char *filename = FILENAME;
static int idx_subd = ANALOG_SUBD;
static int idx_chan = CHANNEL;
static int valueUp = 450000;
static int valueDown = 98500;

void *TaskCode(void *arg)
{
   unsigned char sgnl = 0;
   unsigned long overruns_r = 0;

   a4l_desc_t dsc = { .sbdata = NULL };
   a4l_chinfo_t *chinfo;
   int err = 0;
   unsigned int scan_size = SCAN_SIZE;

   err = a4l_open(&dsc, filename);
   if (err < 0) {
        fprintf(stderr,
            "insn_write: a4l_open %s failed (err=%d)\n",
            filename, err);
        return NULL;
   }    

   while(1) {
        pthread_wait_np( &overruns_r );
    if(sgnl)
        err = a4l_sync_write(&dsc,
                 idx_subd, CHAN(idx_chan), 0, &valueUp, scan_size);
    else
        err = a4l_sync_write(&dsc,
                 idx_subd, CHAN(idx_chan), 0, &valueDown, scan_size);
    if (err < 0) {
        fprintf(stderr,
            "insn_write: a4l_sync_write failed (err=%d)\n", err);
        goto out_insn_write;
    }

    sgnl = (sgnl + 1) % 2;
   }

   out_insn_write:

    if (dsc.sbdata != NULL)
        free(dsc.sbdata);

    a4l_close(&dsc);

    return NULL;

}

int main(void)
{
   mlockall( MCL_CURRENT | MCL_FUTURE );

   pthread_t thread;
   int rc, i;
   int prio = 99;
   struct timespec rqtp, rmtp;
   rqtp.tv_sec = 0;
   rqtp.tv_nsec = PERIOD;

   struct sched_param sparam;
   sparam.sched_priority = 99;

   rc = pthread_create(&thread, NULL, TaskCode, NULL);
   assert(0 == rc);

   rc = pthread_setschedparam(&thread, SCHED_FIFO, &sparam);
   assert(0 == rc);

   rc = clock_gettime( CLOCK_REALTIME, &rmtp );
   assert(0 == rc);
   rmtp.tv_sec = rmtp.tv_sec + DELAI;   

   rc = pthread_make_periodic_np(thread, &rmtp, &rqtp);
   if(rc == ETIMEDOUT) printf("Début dépassé \n");
   else if(rc == ESRCH) printf("Thread invalide \n");
   assert(0 == rc);

   rc = pthread_join(thread, NULL);

   exit(EXIT_SUCCESS);
}

我强烈怀疑(通过查看Xenomai调度程序)我的程序以某种方式进入了辅助模式.我试图删除"assert"语句以及相关的printf语句,但这并不成功.知道如何解决吗?

I am strongly suspecting (by looking at the Xenomai scheduler) that my program somehow enters secondary mode. I tried to remove the "assert" statements as well as the relevant printf's, but this was not successful. Any idea how to fix it?

推荐答案

一如既往,魔鬼在细节中.

As always, the devil is in the details.

我在gcc中启用了-Wall选项,该选项显示了所有警告.原来pthread_ *的标头未正确加载,这使我无法看到pthread_setschedparam的第一个参数是错误的,并且应该是线程而不是& thread.

I enabled the -Wall option in gcc, which shows all the warnings. It turned out the headers for pthread_* were not properly loaded, which prevented me from seeing that the first argument of pthread_setschedparam was wrong, and was supposed to be thread and not &thread.

这篇关于定期线程在Xenomai中实时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆