Forum Discussion

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

uC/OS-II friendly UART communication

Hi,

I'm trying to set up a few communication links using UART. One is at 115.2kbps and the others are at 9600bps. One is obviously going to be used quite a bit and the others not so much.

My problem is setting up the tx and rx routines without taking up all the time during the relatively slow sending (compared to the processor). I want to be able to wait for a packet to come in and to be able to send out while allowing the processor to do other things.

Right now I'm testing an interrupt-based solution which looks promising but I'm not entirely sure it's the way to go. I have also tried to poll the RRDY status bit but I kept missing all the data due to buffer overruns (I was pausing the task so uC/OS could do other things while waiting). I could poll successfully only if I didn't allow uC/OS to do anything else. A thought was to have Nios send the data directly into memory (using DMA) as it was received and then have my routine read the memory but I haven't seen any documentation on this.

What would be the best way to perform UART transmissions (over multiple lines, not necessarily at the same time though) while still allowing the processor to do time-critical tasks (the UART transmissions are not time-critical but they must be recieved/sent within a reasonable amount of time)?

Thanks,

Philip

6 Replies

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

    I understand you do not like the blocking nature of read() calls.

    I am sure there should be some non-blocking call to check UART buffer if there is any character ready to be received. I am still a beginner in NiosII and uC/OS-II so I cannot tell what is its name, but I believe it is...

    Also, when I was checking UART registers in Nios II I have noticed and EOP (End Of Packet) register where you put your character ending communication protocol packet (ETX?) This way your task could be awaken only after the complete packet has been collected in the UART buffer.

    I am not sure if I am interpreting this correctly, maybe somebody with more experience will chime in...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by pszemol@Apr 4 2006, 02:53 AM

    i understand you do not like the blocking nature of read() calls.

    i am sure there should be some non-blocking call to check uart buffer if there is any character ready to be received. i am still a beginner in niosii and uc/os-ii so i cannot tell what is its name, but i believe it is...

    also, when i was checking uart registers in nios ii i have noticed and eop (end of packet) register where you put your character ending communication protocol packet (etx?) this way your task could be awaken only after the complete packet has been collected in the uart buffer.

    i am not sure if i am interpreting this correctly, maybe somebody with more experience will chime in...

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=13994)

    --- quote end ---

    --- Quote End ---

    &#21487;&#20197;&#25171;&#20013;&#25991;&#30340;&#21527;?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by panger123+apr 4 2006, 05:14 am--><div class='quotetop'>quote (panger123 @ apr 4 2006, 05:14 am)</div>

    --- quote start ---

    <!--quotebegin-pszemol@Apr 4 2006, 02:53 AM

    i understand you do not like the blocking nature of read() calls.

    i am sure there should be some non-blocking call to check uart buffer if there is any character ready to be received. i am still a beginner in niosii and uc/os-ii so i cannot tell what is its name, but i believe it is...

    also, when i was checking uart registers in nios ii i have noticed and eop (end of packet) register where you put your character ending communication protocol packet (etx?) this way your task could be awaken only after the complete packet has been collected in the uart buffer.

    i am not sure if i am interpreting this correctly, maybe somebody with more experience will chime in...

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=13994)

    --- quote end ---

    --- Quote End ---

    &#21487;&#20197;&#25171;&#20013;&#25991;&#30340;&#21527;?

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=13995)</div>

    [/b]

    --- Quote End ---

    Sure!

    I am a Chinese

    &#21487;&#20197;&#29992;&#20013;&#25991;&#30340;&#65292;

    &#25105;&#26377;&#20107;&#35201;&#35831;&#25945;&#20320;&#65281;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Using interrupts will work well. Just use your ISR to populate a buffer with the characters as they are received and move a head pointer. Then poll the head and tail pointers of your buffer in your main loop. If the head and tail don&#39;t match then write the character to memory(or whatever you need to do with it) and move your tail pointer. Use as many buffers as you have UARTs. You can also populate a buffer and send characters from it by polling in your main loop as well.

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

    Using interrupts will work well. Just use your ISR to populate a buffer with the characters as they are received and move a head pointer. Then poll the head and tail pointers of your buffer in your main loop. If the head and tail don&#39;t match then write the character to memory(or whatever you need to do with it) and move your tail pointer. Use as many buffers as you have UARTs. You can also populate a buffer and send characters from it by polling in your main loop as well.

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

    Hello all,

    Thanks for responding.

    DMA transfers would have worked but our protocol requires two bytes for the end-of-packet so this wasn&#39;t viable as the EOP register only allows for one byte.

    The solution that I settled on was using open() with O_NONBLOCK for non-blocking mode. The UART is being polled one character at a time and stored in a buffer. When the end bytes are found or a timeout occurs then the packet is dealt with.

    I&#39;ve started to re-write the UART drivers so I can completely toss the one&#39;s supplied by Altera. I&#39;ve found some problems with it and small tests so far show I can shave 30K off the final executable by getting rid of the included drivers and a couple of other things that aren&#39;t being used.

    Thanks,

    Philip