2013-05-22 88 views
2

我正在創建一個週期線程,它在模擬輸出上輸出一個方形信號。我使用Xenomai API的Posix Skin和Analogy。定期線程在Xenomai實時失敗

我使用示波器測試了我的代碼的實時性能,並查看了方波信號(頻率爲1kHz)上的延遲。我應該實現100us的延遲。然而,該信號是強(> 250US延遲)由常見的中斷信號的擾動,如移動鼠標,開始一個新的程序等

在我的生成文件的標誌被設置爲這樣:

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,但這並不成功。任何想法如何解決它?

回答

2

一如既往,魔鬼在細節中。

我啓用了gcc中的-Wall選項,它顯示了所有的警告。原來pthread_ *的頭文件沒有正確加載,這使我無法看到pthread_setschedparam的第一個參數是錯誤的,並且應該是線程而不是&線程。

+0

您是否能夠成功完成此項工作?我有一個類似的程序,它始終以次要模式執行。我嘗試刪除所有的'pthreads',然後運行一個'while'循環,我可以看到它在Linux中顯示爲一個進程。 – am3