我使用的是 Toradex 的 Colibri iMX6 DualLite SoM。它基于多核 ARM Cortex™A9 处理器。我正在其中运行 toradex 提供的嵌入式 Linux 发行版。我们正在使用它开发精密模拟 DAQ 产品。
我们使用 TI ADC IC - ADS8684 16 位 500kSPS(每通道 125kSPS),通过 SPI/SSI 通信进行连接。
为了测试目的,我们在 while 循环中连续获取数据 5 秒,然后中断循环。我们使用动态内存分配为每次迭代重新分配一个数组来存储获取的数据,如下面的代码所示。
time_t start, end;
double *arr; int n=1;
arr=(double*)malloc(n*sizeof(double));
start=time(NULL); //get the present time stamp as start time
end=start+5; //to acquire data for 5 sec
while(start<=end)
{
for(int i=0;i<4;i++) //to take data from 4 ch of adc
{
libsoc_gpio_set_level(cs, LOW); // For acquiring data from the IC
libsoc_spi_read(spi_dev,rdata,4); // For acquiring data from the IC
libsoc_gpio_set_level(cs, HIGH); // For acquiring data from the IC
arr[n-1]=(10.24/65536)*((rdata[2]<<8) | rdata[3]);
n=n+1; // Once a data is acquired increment the size of the array
arr=(double*)realloc(arr,n*sizeof(double)); // Re-Allocate the array for the new size
}
start=time(NULL); }
// 数据获取结束后,我们打印数组和元素的大小。
printf("The size of arr for 5 sec is %d\n",n);
for(int i=0;i<n;i++)
{
printf("arr[%d] is %f\n",i,arr[i]);
}
我们面临的问题是循环迭代不是以恒定速度运行。因此数组中的元素数量变化很大,如 8000,15000,11000,6000 等。由于循环内的所有语句都以恒定速度执行,并且迭代之间没有延迟,唯一可能的原因可能是循环时间发生变化每次迭代。
有没有办法以恒定速度运行DAQ while循环?即每次迭代之间的时间间隔应该相同。
感谢您的时间。
答案1
虽然这些语句可能会以恒定数量运行时钟周期对于每个循环,不能保证它们有一个常数时钟时间以便执行。
内核必须使用循环不可用的时钟周期来解决许多其他问题。更新系统时钟,检查其他要运行的进程,包括可能的cron
作业,以及无数其他内务任务。这些事情可能超出您的控制范围,因此您的代码可用的周期是不可预测的,并且收集的样本数量将不断变化。
我可以提出的唯一解决方案是评估真正重要的参数是什么,并确定如何尽可能最好地控制它们,同时接受所有其他参数的可变性。
答案2
代码中的一个主要失败之处是使用了time()
.这会返回一个以秒为单位的值,因此循环可能会持续 4 到 5 秒。相反,您应该使用gettimeofday()
它提供微秒字段(尽管分辨率可能比这更差)。
您还可以通过使流程成为实时流程来减少可变性。用于chrt -f
运行命令,或使用sched_setscheduler()
进行调用SCHED_FIFO
。