serial errOverRun

ChibiOS public support forum for topics related to the STMicroelectronics SPC56x family of automotive micro-controllers.
plamen
Posts: 11
Joined: Thu Feb 02, 2017 9:47 am
Has thanked: 1 time
Been thanked: 2 times

serial errOverRun

Postby plamen » Thu Feb 02, 2017 10:21 am

Hello,
I'm working with Chibios 16.1.6 on MPC5748g EVB with powerpc-eabivle-gcc from Freescale S32 Design Studio 1.1
My MPC5 port is almost identical with the SPC5 that is in chibios - I just took startup.s code from Freescale templates and had to make some fixes for freescale gcc version.

My application is reading data from serial port LIN2 with the following code:
uint8_t nextByte;
while(true) {
sdRead(sd, (uint8_t*)&nextByte, 1);
if (sd->errOverRun || sd->errFraming || sd->errBreak) {
while (1) ; <- block to check it in the debugger
}
if (!updateInput(nextByte)) {

At speed of 115200 it works fine. However, at speed of 1Mb/s it starts dropping bytes and the errOverRun counter goes up - BOI interrupt is triggered. I have tried all versions of read - sdRead, chnRead, sdReadTimeout, chnReadTimeout - it always drops data at higher speeds. Can you please advice how to solve the problem?

Sorry if my second question is stupid. Why do we have to disable the interrupts in iqReadTimeout(...) before putting the caller thread to sleep with osalThreadEnqueueTimeoutS(...). Don't we miss the UART interrupt that way?

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: serial errOverRun

Postby Giovanni » Thu Feb 02, 2017 10:34 am

Hi,

Functions with name postfixed by S must be called from within a critical zone, it is meant to make some operations atomic. This does not cause any lost interrupt, interrupts are simply delayed to after the call to osalSysUnlock(). Note that the code could suggest that the caller is blocked and interrupts stay disabled, this is not the case, osalThreadEnqueueTimeoutS() switches to another thread which immediately enables interrupts again, the critical zone is very short.

About your issue, the read function used is not the issue here, at those speeds the LinFlex generates interrupts at such a rate that the system is unable to serve interrupts fast enough. LinFlex does not have FIFO buffers that could mitigate the problem.

Is your system configured for maximum performance? it is just matter of speed, the ISR itself is not that complex. Another option would be to use the LinFlex with DMA but that would require a custom driver or an implementation of the ChibiOS UART driver which is meant to use DMA, currently the UART driver is not available for SPC/MPC devices.

Giovanni

plamen
Posts: 11
Joined: Thu Feb 02, 2017 9:47 am
Has thanked: 1 time
Been thanked: 2 times

Re: serial errOverRun

Postby plamen » Thu Feb 02, 2017 11:13 am

It is configured at 160MHz, which should be maximum performance. I took that code from what S32 design studio generates -I don't suspect errors there but I'll dobule check it.
Another project is communicating with the MCU at 1Mb/s without any overflow problems - but it doesn't use any OS and is compiled with greenhills compiler (if that matters). Its ISR is very much the same. I was just thinking if I'm not misusing the OS and make it delay the interrupt processing, which may cause the overflow at higher speeds.

I see in the doc that the rx buffer can be configured to be 1-4 bytes, defaults to 1 - DATA4. Probably it will be worth checking to send always multiples of 4 bytes and receive interrupt when DATA4 - DATA7 are full. If it doesn't work I'll try the DMA option.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: serial errOverRun

Postby Giovanni » Thu Feb 02, 2017 12:50 pm

Using DATA1..4 would require a change in the driver but could reduce the IRQ load.

Giovanni

plamen
Posts: 11
Joined: Thu Feb 02, 2017 9:47 am
Has thanked: 1 time
Been thanked: 2 times

Re: serial errOverRun

Postby plamen » Thu Feb 02, 2017 3:24 pm

I added in the initial configuration of the driver for the Reception Data Field Length

linflexp->UARTCR.B.RDFL_RFC = 3; //receive 4 bytes

And in the RX ISR:
sdIncomingDataI(sdp, sdp->linflexp->BDRM.B.DATA4);
sdIncomingDataI(sdp, sdp->linflexp->BDRM.B.DATA5);
sdIncomingDataI(sdp, sdp->linflexp->BDRM.B.DATA6);
sdIncomingDataI(sdp, sdp->linflexp->BDRM.B.DATA7);

The result slightly improved. I found experimentally that I can transfer safely data up to 400 kbps. With IRQ on every input byte the max safe speed was 300kbps. Probably i have some issue with the port / initialization of the board as 1Mbit/s is perfectly good for it.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: serial errOverRun

Postby Giovanni » Thu Feb 02, 2017 3:29 pm

If you don't need driver events then you may try to simplify the ISR and remove all the events related code (put data directly in queue, do not use sdIncomingDataI()).

Giovanni


Return to “SPC56x Support”

Who is online

Users browsing this forum: No registered users and 6 guests