Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

RS232C Packet Loss

Hello,

I am working with my custom board,

and having problem communicating via RS232C.

In very rare occasion,

commands seems to be ignored,

lost, or thrown away.

My C code is somewhat like below:===int main()

{

char cmd[100];

alt_ic_isr_register(CUSTOM_FPGA_CONTROLLER_ID,CUSTOM_FPGA_IRQ, func, NULL, NULL);

while(1)

{

scanf(%s, cmd);

printf("packet received\n");

}

}

alt_isr_func func()

{

// disable irq here,

// do something here,

// enable irq here.

return 0;

}

=====

packet loss I mean here is that chararcters "packet received"

won't be returned when I send characters to the board.

I inserted debug codes and found out that

the packet loss occurs when interrupt from

custom FPGA and packet receiving

(probably rs232c interrupt) happens simultaneously.

Is there any way to avoid this problem,

or am I missing something important?

Evironment :

Quartus:11.0sp1 Web Edition

NIOS II: 11.0sp1 for Eclipse

FPGA: CycloneIII

Any advice appreciated, Thanks.

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    At a guess it is an interrupt latency issue - too much code in the interrupt handlers for the length of the hardware fifos.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks dsl,

    You were right. I have deleted all codes in my isr, and it's working fine so far.

    Do you think increasing the fifo depths of Clock Crossing Bridge would help?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    No!

    You need to increase any fifo that allow for a longer interrupt latency - eg the rs232 rx data fifo.

    Alternatively just make the software fast enough!

    In many embedded systems you don't actually need to use interrupts - provided the sofware 'idle' loop polls all the hardware often enough.

    It does mean that you may need to optimise for the worst case path, rather than the common one.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you dsl,

    I do continuesly throw commands,

    but always wait until the board returns "packet received" before throwing the next.

    And the command length is only 32bytes.

    Is this really a rx fifo matter?..sorry if i'm asking something dum..

    ..And I can't find fifo length setting in altera_avalon_uart from SOPC..

    What I do in my isr is, transferring data

    from internal to external RAM

    using double buffering without a DMA.

    I guess this is taking too much time(?)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    I had used altera_avalon_uart and I got lost characters.

    I use fifoed avalon_uart from opencores or nioswiki (I don't remember). I think, for this, it is a hardware FIFO (no cpu time consuming). And I treat UART as a file descriptor.

    But I use a RTOS (FreeRTOS) which allow my sytem to continue running even if a (bad designed) task wants to block.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've always kept as far away as possible from commercial (or free!) RTOS for board products. Usually just write a simple scheduler (only one stack), probably written half a dozen (maybe more) over the years. My nios code is just a single C function with a for (;;) {...} in it (after the compiler has inlined things).

    Most embedded code isn't ever going to be run in any other environment, and certainly doesn't need to constrain itself to POSIX (aka unixlike) interfaces. If you have a UART, you want a function read_bytes_from_uart(uart_control_data_t *, void *buf, int len); that directly calls the function that reads the hardware registers, not some long convoluted code path invoded by scanf().
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks, mmTsuchi & dsl

    I will check the fifoed one, and read_bytes_from_uart.

    RTOS sounds attractive.

    (..and I do have a plan to try it on the next engineering)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi, I modified my codes as below,

    and it's working fine so far.

    Just simply replaced scanf() to file descriptor.

    ===

    n=0;

    while(1)

    {

    ////////scanf(%s, cmd);

    fread(&cmd[n], 1, 1, fs);

    if(cmd[n] == 0x0a){//LF

    cmd[n] = 0;

    break;

    }

    n++;

    printf("packet received\n");

    }

    ===

    I guess scanf() is doing something bad in my case..

    mmTsuchi & dsl, Thanks for your support!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi, one last thing.

    I found out that even using file descripter

    as I metioned in above, it still loses some charactors.

    (well, better than losing the whole command)

    Then I realized that the default rs232c ip

    doesn't have any kind of hardware fifo.

    Am I getting this right?

    So, I downloaded FIFOed avalon_UART,

    as mmTsuchi said, and now it's working completely fine.

    scanf() is also working fine.