Olimex Support Forum

OLinuXino Android / Linux boards and System On Modules => A20 => Topic started by: margadon on November 20, 2015, 04:06:56 PM

Title: RT Kernel on Olinuxino A20
Post by: margadon on November 20, 2015, 04:06:56 PM
Hi, who tried t install RT-kernel on debian-linux for A20?
I couldn't get small jitter in UART using generic kernel..
Title: Re: RT Kernel on Olinuxino A20
Post by: MBR on November 21, 2015, 09:52:50 PM
Using a realtime kernel for a slow device like UART is an overkill, so unless you board is very heavy loaded and is doing a lot of I/O at the same time, you'll probably never run into problems with UART (unless the program is very badly designed). If you want a soft-realtime program, try a normal kernel and use realtime sheduling (using sched_setscheduler(), see http://linux.die.net/man/2/sched_setscheduler (http://linux.die.net/man/2/sched_setscheduler)) for your program, and to avoid paging out, you may add the locking of all pages of process in the memory (using mlock(), see http://linux.die.net/man/2/mlock (http://linux.die.net/man/2/mlock)).
Title: Re: RT Kernel on Olinuxino A20
Post by: margadon on December 01, 2015, 04:47:40 PM
Thanks a lot for your explanation! May I clarify something?
I use USART5: PI10, PI11 pins, asynchronous mode. Permanently sending some data packets on speed 115200, I get unexpected delays between packets from 10 up to 20 ms long. I see It on logic analyser. I send different packets of 1-40 bytes long. And after 10-15 packets I get those delays. Here are the pictures from analyser
https://yadi.sk/i/vsKBa1UokQHAp
https://yadi.sk/i/lIzgcR5ekQHFD
In normal state the distance between packets is less than 1 ms - (approx.0.6~0.7ms). Is It because the USART Driver, or Linux, or what is the reason of those unexpected delays?
Do i have to send data from kernel space? Or Is it not such important?
The other processes run in my system also - GUI and so onБ at that
the common usage of CPU is not more then 30-50%, memory not more then 70%. 
I send data from python application using pyserial
here is the code snippet which sends and recieves:
def read(self, size=1):
        """Read size bytes from the serial port. If a timeout is set it may
           return less characters as requested. With no timeout it will block
           until the requested number of bytes is read."""
        if not self._isOpen: raise portNotOpenError
        read = bytearray()
        while len(read) < size:
            try:
                ready,_,_ = select.select([self.fd],[],[], self._timeout)
                # If select was used with a timeout, and the timeout occurs, it
                # returns with empty lists -> thus abort read operation.
                # For timeout == 0 (non-blocking operation) also abort when there
                # is nothing to read.
                if not ready:
                    break   # timeout
                buf = os.read(self.fd, size-len(read))
                # read should always return some data as select reported it was
                # ready to read when we get to this point.
                if not buf:
                    # Disconnected devices, at least on Linux, show the
                    # behavior that they are always ready to read immediately
                    # but reading returns nothing.
                    raise SerialException('device reports readiness to read but returned no data (device disconnected or multiple access on port?)')
                read.extend(buf)
            except select.error, e:
                # ignore EAGAIN errors. all other errors are shown
                # see also http://www.python.org/dev/peps/pep-3151/#select
                if e[0] != errno.EAGAIN:
                    raise SerialException('read failed: %s' % (e,))
            except OSError, e:
                # ignore EAGAIN errors. all other errors are shown
                if e.errno != errno.EAGAIN:
                    raise SerialException('read failed: %s' % (e,))
        return bytes(read)

    def write(self, data):
        """Output the given string over the serial port."""
        if not self._isOpen: raise portNotOpenError
        d = to_bytes(data)
        tx_len = len(d)
        if self._writeTimeout is not None and self._writeTimeout > 0:
            timeout = time.time() + self._writeTimeout
        else:
            timeout = None
        while tx_len > 0:
            try:
                n = os.write(self.fd, d)
                if timeout:
                    # when timeout is set, use select to wait for being ready
                    # with the time left as timeout
                    timeleft = timeout - time.time()
                    if timeleft < 0:
                        raise writeTimeoutError
                    _, ready, _ = select.select([], [self.fd], [], timeleft)
                    if not ready:
                        raise writeTimeoutError
                else:
                    # wait for write operation
                    _, ready, _ = select.select([], [self.fd], [], None)
                    if not ready:
                        raise SerialException('write failed (select)')
                d = d[n:]
                tx_len -= n
            except OSError, v:
                if v.errno != errno.EAGAIN:
                    raise SerialException('write failed: %s' % (v,))
        return len(data)


The same situation I get, when i tried to use GPIO to control TX/RT mode for RS 485 Driver chip (like st485). The moment of switching It to 1 was delays sometimes on the same 10-20 ms, what destroys the transmission session.
Title: Re: RT Kernel on Olinuxino A20
Post by: JohnS on December 01, 2015, 06:13:37 PM
A normal process already sends from the kernel because the process asks the kernel to do the I/O.

I expect your process also does that but if not then do!

The kernel has buffers - again normally.

I would use C in case you are suffering something like a GC in a slow language.

If you get the same problem and have made the changes already suggested by others then something is wrong and needs finding, especially on a 2-cpu chip like the A20.

I take it you have already used tools like ps and top to find out what else your system is doing...

John
Title: Re: RT Kernel on Olinuxino A20
Post by: soenke on December 01, 2015, 09:46:04 PM
Try to start your process with priority -50 and check if that helps.
Title: Re: RT Kernel on Olinuxino A20
Post by: JohnS on December 02, 2015, 09:35:02 AM
You've not left the cpu governor unchanged I hope...

Various settings are utterly useless.  (google...)

John
Title: Re: RT Kernel on Olinuxino A20
Post by: margadon on December 02, 2015, 10:55:20 AM
QuoteYou've not left the cpu governor unchanged I hope...

Various settings are utterly useless.  (google...)
what mode i have to set from that list?

powersave userspace conservative interactive ondemand fantasy performance
Title: Re: RT Kernel on Olinuxino A20
Post by: JohnS on December 02, 2015, 02:52:35 PM
Only you have your hardware and needs so this is your chance to decide.

John
Title: Re: RT Kernel on Olinuxino A20
Post by: soenke on December 02, 2015, 11:51:27 PM
if you want minimal response times, use the performance governor, it will keep the CPU on maximum clock speed.
Title: Re: RT Kernel on Olinuxino A20
Post by: margadon on December 03, 2015, 11:39:05 AM
Quoteif you want minimal response times, use the performance governor, it will keep the CPU on maximum clock speed.
I checked. It was performance by default.