[yocto] Yocto Realtime tests on beaglebone black
Stephen Flowers
sflowers1 at gmail.com
Tue Feb 10 06:43:53 PST 2015
Sorry, no I have not run cyclictest yet. The results are latencies
measured via gpio toggles from running the code posted previously.
Steve
On 10/02/2015 14:40, Bruce Ashfield wrote:
> On 15-02-10 09:39 AM, Stephen Flowers wrote:
>>
>> Thanks for your input. Here are results of 1000 samples over a 10
>> second period:
>
> To be clear ? Is that the cyclictest run that I was asking
> about ?
>
> If it is, what parameters did you use for the run ? It makes a
> huge difference in the results from the test.
>
> Bruce
>
>>
>> Interrupt response (microseconds)
>> standard: min: 81, max:118, average: 84
>> rt: min: 224, max: 289, average: 231
>>
>> Will share the .config later once I get on that machine.
>>
>> Steve
>>
>>
>> On 10/02/2015 14:16, Bruce Ashfield wrote:
>>> On 15-02-10 08:06 AM, Stephen Flowers wrote:
>>>> Hi All,
>>>>
>>>> I have built the realtime kernel using Yocto and deployed on the
>>>> beaglebone black (specifically core-image-rt-sdk). I have written a
>>>> program to test the timer latency and interrupt latency of userspace
>>>> applications. For this I'm using a simple timerfd to generate a
>>>> periodic 10ms gpio toggle which itself acts as a gpio interrupt on
>>>> another gpio pin.
>>>> I find the latency is much worse on the preempt_rt kernel than the
>>>> standard one. RT kernel gives around 220us average with the standard
>>>> kernel about 80us. Testing with Xenomai gives about 60us. The
>>>> response
>>>> times are measured with an external logic analyser, and taken with no
>>>> other load on the system. Kernel version is 3.14.
>>>>
>>>> The difference between standard and RT kernel configs:
>>>> Preemption model: desktop vs. realtime kernel
>>>> Timer: 100Hz vs 1000Hz
>>>> High resolution timers disabled
>>>
>>> Can you share the full .config for both configurations ? That should
>>> shed a bit more light on what might be misconfigured.
>>>
>>> I haven't run tests on the beaglebone black myself, but on similar
>>> ARM boards, performance has been as expected.
>>>
>>> You are talking about average latency above, what about the max
>>> latency ? We expect that the preempt-rt kernel will have a higher
>>> minimum, and often average latency .. but will be significantly
>>> better in maximum latency.
>>>
>>> It would also be useful to grab cyclictest results for the standard
>>> and preempt-rt kernel as a baseline performance measure.
>>>
>>> Bruce
>>>
>>>>
>>>> I'm having a hard time figuring out why the RT kernel gives worse
>>>> latency. Anyone have any insight into this?
>>>> Included the source code below.
>>>>
>>>> Thanks & Regards,
>>>> Steve
>>>>
>>>> #include<sys/time.h>
>>>> #include<time.h>
>>>> #include<sys/types.h>
>>>> #include <signal.h>
>>>> #include <stdlib.h>
>>>> #include <stdio.h>
>>>> #include <sched.h>
>>>> #include <sys/mman.h>
>>>> #include "poll.h"
>>>> #include "fcntl.h"
>>>> #include "string.h"
>>>> #include "errno.h"
>>>> #include <sys/timerfd.h>
>>>>
>>>> #define TIMER_OUT_PATH "/sys/class/gpio/gpio47"
>>>> #define LED_OUT_PATH "/sys/class/gpio/gpio26"
>>>> #define IRQ_IN_PATH "/sys/class/gpio/gpio46"
>>>>
>>>> static int timer_toggle = 0;
>>>> static int output_toggle = 0;
>>>>
>>>> void stack_prefault(void)
>>>> {
>>>> unsigned char dummy[8192];
>>>> memset(dummy, 0, 8192);
>>>> }
>>>>
>>>>
>>>> int main(int argc, char* argv[])
>>>> {
>>>> struct itimerspec itv;
>>>> unsigned long long timer_increment = 0;
>>>>
>>>> clock_t prevClock;
>>>> int sigCnt = 0;
>>>> struct sigaction sa;
>>>> struct sched_param sp;
>>>>
>>>> struct pollfd fdset[2];
>>>> int fd_in;
>>>> int action;
>>>> int fd_led;
>>>> int fd_timer_out;
>>>> int fd_timer_in;
>>>>
>>>> char buf[2];
>>>> int len;
>>>>
>>>> // setup gpio
>>>> if(system("echo 46 > /sys/class/gpio/export") == -1)
>>>> perror("unable to export gpio 46");
>>>>
>>>> if(system("echo 47 > /sys/class/gpio/export") == -1)
>>>> perror("unable to export gpio 47");
>>>>
>>>> if(system("echo 26 > /sys/class/gpio/export") == -1)
>>>> perror("unable to export gpio 26");
>>>>
>>>> // timer out
>>>> if(system("echo out > /sys/class/gpio/gpio47/direction") == -1)
>>>> perror("unable to set 47 to output");
>>>>
>>>> // led out
>>>> if(system("echo out > /sys/class/gpio/gpio26/direction") == -1)
>>>> perror("unable to set 26 to output");
>>>>
>>>> // irq in
>>>> if(system("echo in > /sys/class/gpio/gpio46/direction") == -1)
>>>> perror("unable to set 46 to input");
>>>>
>>>> if(system("echo both > /sys/class/gpio/gpio46/edge") == -1)
>>>> perror("unable to set 46 edge");
>>>>
>>>> // set scheduling parameters
>>>> sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
>>>> if(sched_setscheduler(0, SCHED_FIFO, &sp) == -1)
>>>> {
>>>> perror("setscheduler");
>>>> exit(-1);
>>>> }
>>>>
>>>> // lock memory
>>>> if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1)
>>>> perror("mlockall");
>>>>
>>>> stack_prefault();
>>>>
>>>> // Set up timer
>>>> fd_timer_in = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
>>>> printf("fd_timer:%d\n",fd_timer_in);
>>>>
>>>> if(fd_timer_in < 0)
>>>> {
>>>> perror("timerfd_create()");
>>>> }
>>>>
>>>> itv.it_value.tv_sec = 0;
>>>> itv.it_value.tv_nsec = 10000000;
>>>> itv.it_interval.tv_sec = 0;
>>>> itv.it_interval.tv_nsec = 10000000;
>>>> if(-1 == timerfd_settime(fd_timer_in, 0, &itv, NULL))
>>>> {
>>>> perror("settime()");
>>>> }
>>>>
>>>> // setup file descriptor for poll()
>>>> fd_in = open(IRQ_IN_PATH "/value", O_RDONLY | O_NONBLOCK);
>>>> printf("fd irq input:%d\n",fd_in);
>>>>
>>>> if(fd_in < 0)
>>>> {
>>>> perror("file open problem");
>>>> exit(0);
>>>> }
>>>>
>>>> while(1)
>>>> {
>>>> memset((void*)fdset, 0, sizeof(fdset));
>>>> fdset[0].fd = fd_in;
>>>> fdset[0].events = POLLPRI | POLLERR;
>>>> fdset[0].revents = 0;
>>>>
>>>> fdset[1].fd = fd_timer_in;
>>>> fdset[1].events = POLLIN | POLLERR;
>>>> fdset[1].revents = 0;
>>>> action = poll(fdset, 2, -1);
>>>>
>>>> if(action < 0)
>>>> {
>>>> if(errno == EINTR)
>>>> {
>>>> // when signal interrupts poll, we poll again
>>>> continue;
>>>> }
>>>> else
>>>> {
>>>> perror("poll failed");
>>>> exit(0);
>>>> }
>>>> }
>>>>
>>>> if(fdset[1].revents & POLLIN)
>>>> {
>>>> //len = read(fdset[1].fd, 0, SEEK_SET);
>>>> len = read(fdset[1].fd, &timer_increment,
>>>> sizeof(timer_increment));
>>>>
>>>> fd_timer_out = open( TIMER_OUT_PATH "/value", O_WRONLY);
>>>>
>>>> if(timer_toggle ^= 1)
>>>> {
>>>> write(fd_timer_out, "1", 2);
>>>> }
>>>> elseonse (microseconds)
> standard: min: 81, max:118, average: 84
> rt: min: 224, max: 289, average: 231
>
>>>> {
>>>> write(fd_timer_out, "0", 2);
>>>> }
>>>>
>>>> close(fd_timer_out);
>>>> }
>>>>
>>>> if(fdset[0].revents & POLLPRI)
>>>> {
>>>> lseek(fdset[0].fd, 0, SEEK_SET); // read from start
>>>> of file
>>>> len = read(fdset[0].fd, buf, sizeof(buf));
>>>>
>>>> fd_led = open( LED_OUT_PATH "/value", O_WRONLY |
>>>> O_NONBLOCK);
>>>>
>>>> if(buf[0] == '1')
>>>> {
>>>> write(fd_led, "1", 2);
>>>> }
>>>> else
>>>> {
>>>> write(fd_led, "0", 2);
>>>> }
>>>>
>>>> close(fd_led);
>>>> }
>>>> }
>>>>
>>>> close(fd_in);
>>>> close(fd_timer_in);
>>>> close(fd_led);
>>>> printf("finished\n");
>>>> return 0;
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>
>
More information about the yocto
mailing list