Am 27.05.2011 08:40, schrieb Gilles Chanteperdrix:
On 05/26/2011 07:28 PM, Jonas Witt wrote:
Hi all,
i am having a problem concerning the clock drift under load:
# /usr/xenomai/bin/clocktest
== Tested clock: 0 (CLOCK_REALTIME)
CPU ToD offset [us] ToD drift [us/s] warps max delta [us]
--- -------------------- ---------------- ---------- --------------
0 775571614.0 166776.858 0 0.0
It remains in the hundreds of MILLIseconds, changing constantly. My
setup consists of an embedded Intel Atom board (1.6GHz Z530 processor)
with a 2.6.32.7 kernel and Xenomai 2.5.2.
Hi Jonas,
Could you try and see if 2.5.6 with latest I-pipe patches has the same
behaviour?
Latencies under load are
reasonable. Mean latency< 10us. Maximum latency< 40us.
Without load the ToD offset is approximately constant over time with a
ToD drift in the range of 10 microseconds (strangely after a while this
settles in a range of 2 microseconds). Does anyone have an idea how this
can be caused?
First, I am not sure clocktest is meant to be use under load. Second,
does your system uses ntp?
As a workaround I currently use rt_timer_read() in all
relevant programs (also the non-realtime ones), since I need consistent
timestamps between realtime and non-realtime tasks.
In order to solve this particular issue, we have a solution, but not yet
in stable released versions.
One other (maybe unrelated) strange behavior is occasional secondary
mode switches when calling rt_queue_read(...).
For this error, we need more details, such as a simple test case
allowing to reproduce the issue, and again, you need to be sure to
reproduce the issue on latest stable release with latest I-pipe patches.
Regards.
Hi Gilles,
thanks for your input. I will try Xenomai 2.5.6 soon. In the meantime I
wrote a simple load simulator to reproduce the issue with my more
complex program. The clock drift only occurs with a load of more than
30%. Below that the clock is fine. So you may have to adjust the
attached code (e.g. change the 2000 value in the for-loop to something
larger) to stress your system to that level where the processing time is
more than 2000 microseconds.
Cheers,
Jonas
cmake_minimum_required(VERSION 2.6)
project(XenoLoadSimulator)
link_directories(/usr/xenomai/lib)
include_directories(/usr/xenomai/include)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} xenomai rtdm native)
#include <sys/mman.h>
#include <csignal>
#include <native/queue.h>
#include <native/timer.h>
#include <native/task.h>
#include <cmath>
bool running = true;
RT_QUEUE queue;
void exitSignal (int param)
{
printf ("Exiting program...\n");
running = false;
}
void mainLoop(void* dummy)
{
int status;
printf("Main loop...\n");
RTIME currentTime, lastTime;
double result = 7.0;
double a = 1000.;
double b = 333.;
unsigned int counter = 0;
float periodTime = 500.0f;
float processingTime = 0.0f;
double position[3];
while(running)
{
rt_task_wait_period(NULL);
RTIME startTime = rt_timer_read();
for(unsigned long long int i=0; i < ((unsigned long)result) % 5
+ 3000; ++i)
{
a += sin((double)i / 500.);
b = sqrt(a);
result += ((double)i / 3.0 + 3.1423) * (double) i - a *
b;
}
currentTime = rt_timer_read();
processingTime = 0.9f * processingTime + 0.1f *
(float)(currentTime - startTime) / 1000.f;
periodTime = 0.9f * periodTime + 0.1f * (float)(currentTime -
lastTime) / 1000.f;
lastTime = currentTime;
/*if(rt_queue_read(&queue, (void*)position, 3*sizeof(double),
TM_NONBLOCK) > 0)
{
printf("X: %.1f Y: %.1f Z: %.1f\n", position[0],
position[1], position[2]);
}*/
if(counter++ > 100)
{
counter = 0;
printf("Period Time: %.1fus Result: %.1f\n",
periodTime, result);
printf("Processing Time: %.1fus\n", processingTime);
}
}
}
int main (int argc , char * argv [])
{
mlockall(MCL_CURRENT | MCL_FUTURE);
signal (SIGINT, exitSignal);
printf("Initialization...");
int status;
/*if(rt_queue_bind(&queue, "camPosQueue", TM_NONBLOCK) != 0)
{
return 0;
}*/
rt_timer_set_mode(TM_ONESHOT);
RT_TASK task;
if(rt_task_create(&task, NULL, 0, 80, T_JOINABLE) != 0)
{
printf("Creation of Xenomai Task failed!\n");
return 0;
}
rt_task_set_periodic (&task, TM_NOW, 4000000);
printf("done!\n");
rt_task_start(&task, &mainLoop, (void*)NULL);
rt_task_join(&task);
mainLoop(NULL);
printf("CleanUp...");
//rt_queue_unbind(&queue);
printf("done!\n");
return 0;
}
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help