Tôi cần phải thực hiện thời gian chính xác đến mức 1 của chúng tôi để thay đổi chu kỳ nhiệm vụ của sóng pwm.Thời gian chính xác của Linux - Điều gì xác định độ phân giải của clock_gettime()?
nền
Tôi đang sử dụng một Gumstix trên mặt nước COM (https://www.gumstix.com/store/app.php/products/265/) mà có một bộ xử lý Cortex-A8 lõi ARM đơn chạy ở 499,92 bogomips (trang Gumstix tuyên bố lên đến 1Ghz với 800Mhz đề nghị) theo/proc/cpuinfo. Hệ điều hành là một phiên bản Angstrom Image của Linux dựa trên phiên bản hạt nhân 2.6.34 và nó là cổ phiếu trên Gumstix Water COM.
Vấn đề
tôi đã làm được một số tiền hợp lý của việc đọc về thời gian chính xác trong Linux (và đã cố gắng nhất của nó) và sự đồng thuận có vẻ là rằng việc sử dụng clock_gettime() và tham khảo CLOCK_MONOTONIC là tốt nhất cách để làm điều đó. (Tôi đã có thể sử dụng đăng ký RDTSC cho thời gian kể từ khi tôi có một lõi với khả năng tiết kiệm điện tối thiểu nhưng đây không phải là một bộ xử lý Intel.) Vì vậy, đây là phần lẻ, trong khi clock_getres() trả về 1, cho thấy độ phân giải 1 ns , các thử nghiệm tính thời gian thực tế cho thấy độ phân giải tối thiểu 30517ns hoặc (không thể trùng hợp) chính xác thời gian giữa các dấu tick đồng hồ 32.768KHz. Đây là những gì tôi muốn nói:
// Stackoverflow example
#include <stdio.h>
#include <time.h>
#define SEC2NANOSEC 1000000000
int main(int argc, const char* argv[])
{
// //////////////// Min resolution test //////////////////////
struct timespec resStart, resEnd, ts;
ts.tv_sec = 0; // s
ts.tv_nsec = 1; // ns
int iters = 100;
double resTime,sum = 0;
int i;
for (i = 0; i<iters; i++)
{
clock_gettime(CLOCK_MONOTONIC, &resStart); // start timer
// clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
clock_gettime(CLOCK_MONOTONIC, &resEnd); // end timer
resTime = ((double)resEnd.tv_sec*SEC2NANOSEC + (double)resEnd.tv_nsec
- ((double)resStart.tv_sec*SEC2NANOSEC + (double)resStart.tv_nsec);
sum = sum + resTime;
printf("resTime = %f\n",resTime);
}
printf("Average = %f\n",sum/(double)iters);
}
(Đừng băn khoăn về việc chọn diễn viên đôi, tv_sec trong một time_t và tv_nsec là một chặng đường dài.)
Compile với:
gcc soExample.c -o runSOExample -lrt
Run với:
./runSOExample
Với nanosleep nhận xét như được hiển thị, kết quả là 0ns hoặc 30517ns với đa số là 0ns. Điều này khiến tôi tin rằng CLOCK_MONOTONIC được cập nhật ở mức 32.768kHz và hầu hết thời gian đồng hồ chưa được cập nhật trước khi cuộc gọi clock_gettime thứ hai() được thực hiện và trong trường hợp kết quả là 30517ns đồng hồ đã được cập nhật giữa các cuộc gọi.
Khi tôi làm điều tương tự trên máy tính phát triển của mình (AMD FX (tm) -6100 Bộ vi xử lý sáu lõi chạy ở tần số 1,4 GHz), độ trễ tối thiểu là 149-151ns liên tục không có số không.
Vì vậy, hãy so sánh các kết quả đó với tốc độ CPU. Đối với Gumstix, 30517ns (32.768kHz) tương đương với 15298 chu kỳ của CPU 499.93MHz. Đối với máy tính dev của tôi, 150ns tương đương với 210 chu kỳ của CPU 1,4Ghz.
Với clock_nanosleep() gọi uncomment kết quả trung bình là những: Gumstix: Giá trị trung bình = 213.623 và kết quả khác nhau, lên xuống, bởi bội số của độ phân giải tối thiểu của 30517ns máy tính Dev: 57.710-68.065 ns với không có xu hướng rõ ràng. Trong trường hợp của máy tính dev tôi mong đợi độ phân giải thực sự ở mức 1 ns và đo ~ 150ns thực sự là thời gian trôi qua giữa hai cuộc gọi clock_gettime().
Vì vậy, câu hỏi của tôi là: Điều gì xác định độ phân giải tối thiểu đó? Tại sao độ phân giải của máy tính dev 30000X tốt hơn so với Gumstix khi bộ xử lý chỉ chạy ~ 2.6X nhanh hơn? Có cách nào để thay đổi tần suất CLOCK_MONOTONIC được cập nhật và ở đâu không? Trong hạt nhân?
Cảm ơn! Nếu bạn cần thêm thông tin hoặc làm rõ chỉ cần hỏi.
Chỉ cần tự hỏi. Sẽ không phải loại phần cứng nào cần thiết để lấy chu trình từ đồng hồ CPU? Ít nhất ở mức độ chính xác đó. Có lẽ Gumstix không có? (Tôi chỉ nói về một thanh ghi có thể đếm ve và giữ chúng trước khi lăn qua.) – Jiminion
Với tất cả các bài đọc bạn nói bạn đã làm, bạn có thể đã thấy *** [liên kết này] (http: // gallinazo.flightgear.org/technology/gumstix-overo-rc-servos-and-pwm-signal-generation/)*** nhưng vẫn đăng bài trong trường hợp. Một số tài liệu có liên quan. – ryyker
Có cùng một vấn đề chính xác. Số lượng 30517ns. Im sử dụng một thủy triều Overo. Bạn đã từng giải quyết vấn đề này chưa? – Ryan