У меня есть небольшой код ниже. Я использую этот код для вывода некоторых 1s и 0s (unsigned output[38]
) из GPIO встроенной платы.
Мой вопрос: время между двумя выходными значениями (1, 0 или 0, 1) должно быть 416 микросекунд, как я определяю на clock_nanosleep
ниже кода, я также использовал sched_priority()
для лучшее временное разрешение. Однако измерение осциллографа (pic ниже) показывает, что время между двумя выходными значениями 770 usec. Интересно, почему у меня такая большая неточность между сигналами?
PS. на доске (beagleboard) есть Linux 3.2.0-23-omap # 36-Ubuntu Tue Apr 10 20:24:21 UTC 2012 armv7l armv7l armv7l Ядро GNU/Linux, и оно имеет процессор 750 МГц, top
показывает почти никакой CPU (~ 1%), а память (~ 0,5%) потребляется до запуска моего кода. Я использую электронный осциллограф, который не имеет проблемы с калибровкой.
#include <stdio.h>
#include <stdlib.h> //exit();
#include <sched.h>
#include <time.h>
void msg_send();
struct sched_param sp;
int main(void){
sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(0, SCHED_FIFO, &sp);
msg_send();
return 0;
}
void msg_send(){
unsigned output[38] = {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1};
FILE *fp8;
if ((fp8 = fopen("/sys/class/gpio/export", "w")) == NULL){ //echo 139 > export
fprintf(stderr,"Cannot open export file: line844.\n"); fclose(fp8);exit(1);
}
fprintf(fp8, "%d", 139); //pin 3
fclose(fp8);
if ((fp8 = fopen("/sys/class/gpio/gpio139/direction", "rb+")) == NULL){
fprintf(stderr,"Cannot open direction file - GPIO139 - line851.\n");fclose(fp8); exit(1);
}
fprintf(fp8, "out");
fclose(fp8);
if((fp8 = fopen("/sys/class/gpio/gpio139/value", "w")) == NULL) {
fprintf(stderr,"error in openning value\n"); fclose(fp8); exit(1);
}
struct timespec req = { .tv_sec=0, .tv_nsec = 416000 }; //416 usec
/* here is the part that my question focus*/
while(1){
for(i=0;i<38;i++){
rewind(fp8);
fprintf(fp8, "%d", output[i]);
clock_nanosleep(CLOCK_MONOTONIC ,0, &req, NULL);
}
}
}
РЕДАКТИРОВАТЬ: Я читал в течение нескольких дней, что clock_nanosleep() или другой наномет, usleep и т.д. не гарантирует пробуждения вовремя. они обычно обеспечивают спящий код в течение определенного времени, но пробуждение процесса зависит от процессора. я обнаружил, что абсолютное время обеспечивает лучшее разрешение (флаг TIMER_ABSTIME
). Я нашел то же самое решение, что и Maxime. однако у меня есть сбой в моем сигнале, когда цикл завершен. На мой взгляд, нехорошо выполнять какие-либо функции сна для создания ШИМ или вывода данных на встроенной платформе. Хорошо потратить некоторое время на изучение таймеров CPU, которые предоставляют платформы для генерации PWM или данных, которые имеют хорошую точность.