Microcontroller networking

Discussion in 'Programmer's Corner' started by kuch128, Feb 25, 2013.

  1. kuch128

    Thread Starter Member

    Mar 7, 2011
    So I am completely defeated with the assignment I am currently working on. I am taking a networking with micro controllers class and basically the goal of the class is to make our micro controller dev boards (STK600 w/ ATMega2560) in a network card. We are going to be using the USART to talk with a PC script in Python and eventually we will hopefully have a network between computers using our dev boards as the interface. Anyway I think that is enough background for now.

    Where I am stuck at is the creation of a buffer in order to store the received packets from the computer. Right now we are only sending simple char arrays and can make use of the \0 character which C terminates each string with. The packets we have to create must have a header which for fight now must only contain the length of the payload and a last field which indicates that the incoming packet will complete the transmission. The payload can range anywhere from 1 - 255 bytes.

    So to start off I have defined two structures, header (which contains the last and length fields) and pkt (which will include the payload and the header) both members of the pkt structure are pointers one to the header structure one to the hardcoded payload. Right now I just created a char array of 255 characters including the null character.

    We are only allowed to used the transmit and receive complete interrupts so the micro is not wasting time sitting in an ISR or function polling the UDREn flag to determine when the UDR is ready.

    So what I am having a hard time with is creating a buffer which I can set up to let the interrupts take care of the rest as well as how to transfer that information in its appropriate structure so the higher level functions and analyze what was received.

    I'm not looking for code just maybe some suggestions to look into I am willing to do the research but I am completely overwhelmed and don't know where to begin.
  2. Papabravo


    Feb 24, 2006
    What you need is called a circular buffer. You can statically allocate such a buffer as an array of characters with any convenient length. Let us say 300 unsigned characters for example. This is more than enough to hold an entire maximum payload. Associated with this circular buffer is a "count" of the number of characters in the buffer. There is also a "get" index and a "put" index. Now I 'm going to explain what happens for receive and the logic is similar for transmit.

    In the Receive Interrupt Service Routine:
    1. Check the "count" to see if there is room in the buffer
    2. If there is no room you throw the character away and set an "error" indication
    3. If there is room in the buffer("count" < Buffer Size), you read the character out of the hardware register and stuff it in the circular buffer at the "put" index
    4. You then increment the "put" index MODULO the buffer size of 300 bytes, and increment the "count". So an index pointing to the end of the buffer will wrap around to the beginning.

    In the Receiver Processing Routine which runs continuously in a "do forever" loop at a non-interrupt level.
    1. Check the "count" to see if it is greater than zero. If it zero then you go do other tasks and come back later.
    2. If the "count" is non-zero then one or more characters are in the circular buffer, and you fetch the one that is at the "get" pointer.
    3. You then increment the "get" index MODULO the buffer size and decrement the "count"

    There is only one other thing to be careful about. In the non-interrupt Receiver Processing Routine you must not modify "count" without disabling interrupts. The "get" and "put" indexes are safe because they are not modified in both places.

    Transmit works the same way except for one thing. Receive interrupts should be left on all the time. Transmit interrupts should only be on when there are characters in the circular buffer. When the circular buffer is empty the Transmit Interrupt should be off.

    Hope this helps
    JMac3108 likes this.
  3. kuch128

    Thread Starter Member

    Mar 7, 2011
    Papabravo thank you very much. I am going to try and recite what you just said in my words (helps me understand).

    -The one circular buffer will be used for both transmit and receive.

    -Given my scenario and your hypothetical array size of 300 I would be able to store a little over 1 packets worth of data before it would give me an "error" as being full

    -The count variable could be declared static in the ISR to keep track on where in the array to stuff the data from the UDR register? And the upper level function handling the received data will check if count is non-zero if it is it will know that there is data which is ready to be pulled and put into my packet structures. My only question with this is regarding your use MODULO, are you implying the use of the modulus operator?

    I apologize for my ignorance but I am truly trying to learn, I appreciate the time you took in your response and I feel like I have a new avenue of attack with this. I will keep you updated with my progress if you are interested.

    Also there are still a few things I am unclear with regarding your post but I am going to do a little more research with the direction you provided so I can pose an intelligent question.
  4. tgil

    New Member

    May 18, 2011
  5. Papabravo


    Feb 24, 2006
    There are actually two circular buffers, one for the UART transmitter and one for the UART receiver. They don't need to be the same size but they can be.