Using a colibri imx6 512Mb module, we tried sending (periodically) 127 byte packets over uart in 2ms time intervals.
|------2ms------|------2ms-----|-----2ms-----|
Baud rate is 1Mbit and as long as there is there is no overlap to the next 2ms interval, we are fine with data transmission starting anywhere in the 2ms time interval.
Below is the code snippet for sending data.
// https://stackoverflow.com/questions/24259640/writing-a-full-buffer-using-write-system-call
int writen(const int sd, guint8 * b, const size_t s, const int retry_on_interrupt) {
size_t n = s;
while (0 < n) {
ssize_t result = write(sd, b, n);
if (-1 == result) {
if ((retry_on_interrupt && (errno == EINTR)) || (errno == EWOULDBLOCK) || (errno == EAGAIN)) { continue; }
else { break; }
}
n -= result;
b += result;
}
return (0 < n) ?-1 :0;
}
void * appsink_thread(void *tdata_void)
{
ThreadData * tdata = (ThreadData*) tdata_void;
struct timeval tv0, tv1;
guint32 tv0_residue, tv1_residue;
int tty = open(tdata->tty.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
if (!tty) {
return NULL;
}
while(1){
if(packets_to_send[pcks_start] > 0){
gettimeofday (&tv0, NULL);
tv0_residue = tv0.tv_usec % 2000;
if (tv0_residue > 1900) {
guint8 *data = serialize_pack(pck, (guint16*)&tx_size);
do {
gettimeofday (&tv1, NULL);
tv1_residue = tv1.tv_usec % 2000;
} while (tv1_residue > tv0_residue);
int rc = writen(tty, data, tx_size, false);
// ... cleanup resources etc
}
}
// ... receive more packs here
usleep(50);
}
close(tty);
}
Could you provide the version of the hardware and software of your module?
As you already suspected, Linux is not a real-time Operating System. During the run of thread and tasks, there will be a jitter depending on caching and load of the CPU and other things. Applying the Real Time patch will make Linux more deterministic.
Please read the following developer site for further Information.
console-tdx-image derived custom image at LinuxImage2.8. Cloned a few days ago. Commit of .repo/manifests.git is 60d5600163bf31057efb0d7656f7356a75f236f4.
Tried both linux-toradex and linux-toradex-rt. Applied pthread priority attributes at this example for RT tests. RT enhanced waking up times. I am only getting a few >3 with this debug output:
It depends on your requirements. Which jitter is allowed for your application?
To reduce jitter you can write your own kernel module for your application.
If you want to have a very low jitter, you should run your code on m4 which is included in VF61 and iMX6.
Side note: Could you try to rewrite your C-code and check every 2ms, if there are data to send and send them? This will give you a more regular and deterministic code?
You could code like this:
t1 = initial time;
while (1)
{
t2 = actual time;
dt = actual time - initial time;
if dt > 2ms
{
initial time = actual time;
send data;
}
usleep(100);
}