2014-06-12 51 views
1

我正在試驗一些抖動時序測試,方法是切換GPIO線並觀察示波器上的波形。我的內核編譯爲PREEMPT_RT。我希望將進程的調度程序更改爲SCHED_FIFO可以減少抖動,但似乎沒有太大區別。代碼如下。有沒有什麼我做錯了試圖從這個代碼獲得實時性能?使用SCHED_FIFO在Linux上看到糟糕的實時性能使用SCHED_FIFO

// Program to test Linux timing jitter by driving GPIO output via sysfs interface. 
// In this variant, the scheduler is changed to SCHED_FIFO. 

#include <sys/stat.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sched.h> 

#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) 

int main() { 
    char buf[128]; 
    struct sched_param schedp; 

    const int pin = GPIO_TO_PIN(1, 24); 

    int fd = open("/sys/class/gpio/export", O_WRONLY); 
    if (fd == -1) { 
     fprintf(stderr, "Failed to open export for writing!\n"); 
     return(-1); 
    } 

    int bytes_written = snprintf(buf, sizeof buf, "%d", pin); 
    write(fd, buf, bytes_written); 
    close(fd); 

    snprintf(buf, sizeof buf, "/sys/class/gpio/gpio%d/direction", pin); 
    fd = open(buf, O_WRONLY); 
    if (fd == -1) { 
     fprintf(stderr, "Failed to open gpio direction for writing!\n"); 
     return(-1); 
    } 

    if (write(fd, "out", 3) == -1) { 
     fprintf(stderr, "Failed to set direction!\n"); 
     return(-1); 
    } 

    snprintf(buf, sizeof buf, "/sys/class/gpio/gpio%d/value", pin); 
    fd = open(buf, O_WRONLY); 
    if (fd == -1) { 
     fprintf(stderr, "Failed to open gpio value for writing!\n"); 
     return(-1); 
    } 

    // Change scheduler to SCHED_FIFO. 
    schedp.sched_priority = 99; 
    if (sched_setscheduler(0, SCHED_FIFO, &schedp)) { 
     perror("sched_setscheduler"); 
    } 

    while (1) { 
     if (write(fd, "1", 1) != 1) { 
      fprintf(stderr, "Failed to write value!\n"); 
      return(-1); 
     } 
     usleep(500); 

     if (write(fd, "0", 1) != 1) { 
      fprintf(stderr, "Failed to write value!\n"); 
      return(-1); 
     } 
     usleep(500); 
    } 

    close(fd); 

    return 0; 
} 
+0

一般來說,是的,期望用戶模式代碼的RT性能是錯誤的。你期望有多少抖動,你看到了多少? –

+1

當系統空閒時,我發現方波中存在10%左右的抖動,但如果我運行命令,則有時會看到它不會在幾毫秒內切換。我認爲PREEMPT_RT新增點的目的是讓你可以在用戶空間中做實時代碼? – user43995

+0

@ user43995有點。 Linux不是一個實時操作系統,所以仍然沒有保證。另外,默認情況下,5%的秒數仍可以被優先級較低的任務使用,並搶佔您的「實時」任務(請參閱https://www.kernel.org/doc/Documentation/scheduler/sched-rt-group。文本)。你也會受內核標記速率的限制,儘管通常的1000Hz標記速率可能只有1ms。 – nos

回答

0

有很多原因可能導致您看不到體面的實時性能。首先,你應該檢查OSADL網站http://www.osadl.org。首先要評估的是如果你有一個實時系統。

查詢here瞭解如何測試實時性能。

另外我看到你正在寫一個GPIO。我並不完全熟悉這一點,但我想有一些內核驅動程序/線程負責設備。你需要確保這個線程也可以通過像chrt -f -p這樣的東西流出。99 < pid>

也考慮睡眠時的納秒睡眠。

雖然很晚,但這可能會給你一些啓示。

相關問題