Thread: Help with C question

  1. #1
    Registered User
    Join Date
    Oct 2018
    Posts
    3

    Help with C question

    Hi all,

    I'd appreciate some help with this piece of code -

    Code:
    unsigned char buffer[64];
    unsigned char volatile in;
    unsigned char volatile out;
     
    void SERIAL_PORT_INTERRUPT(void)
    {
         if (SERIAL_PORT_TRANSMIT_IDLE) {
               if (in != out) {
                    SERIAL_PORT_WRITE(buffer[out % sizeof(buffer)]);
                    ++out;
               } else
                    SERIAL_PORT_INTERRUPT_DISABLE();
         }
    }
     
    void serial_send(unsigned char data)
    {
         while (in - out == sizeof(buffer))
               ;
     
         buffer[in % sizeof(buffer)] = data;
         ++in;
     
         /* will interrupt immediately if transmitter is idle ... */
     
         SERIAL_PORT_INTERRUPT_ENABLE();
    }
    The code above is for a simple interrupt driven serial port transmitter.

    1. Is there any issue with increasing the size of buffer to 192 bytes ?


    Here is what I do know...

    There is no issue with increasing the size of the buffer to 191 bytes however 192 doesn't work.

    Can anyone confirm why?

    Thanks in advance!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    36,629
    What device are you running this on?

    What toolchain are you using to build this with?

    Do you get at least 192 chars transmitted before it blows up?
    more?
    less?

    Does it halt, or corrupt data?

    TBH, I would prefer to see the likes of
    in = ( in + 1 ) % sizeof(buffer)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2018
    Posts
    3
    Quote Originally Posted by Salem View Post
    What device are you running this on?

    What toolchain are you using to build this with?

    Do you get at least 192 chars transmitted before it blows up?
    more?
    less?

    Does it halt, or corrupt data?

    TBH, I would prefer to see the likes of
    in = ( in + 1 ) % sizeof(buffer)
    I have no bloody clue on any of the above, sorry!

  4. #4
    Registered User john.c's Avatar
    Join Date
    Dec 2017
    Posts
    356
    Are you saying that sizes of 1 to 191 all "work"?
    Are you saying that sizes of 192 to 255 all "don't work"?

    Try to answer Salem's questions:
    1. What machine are you running this on? Are you running it at all?
    2. What compiler/etc. do you use to build the executable?
    3. What exactly happens? "It doesn't work" says very little. How may chars are transmitted before the problem? Does it halt (crash)? Does it start overwriting data, outputting garbage, what?

    The tricky points in the code have to do with unsigned char having a range of 0 to 255. So in and out will wrap around from 255 to 0 when they hit the end of that range. At some points, in will be less than out, so in - out will be negative. That would seem to be a problem with any buffer size.

    Also, the "modded index" will jump when the value wraps if the buffer size doesn't divide 256 evenly. E.g., buffer size = 191: 255 % 191 = 64, 0 % 191 = 0. So the buffer index jumps from 64 to 0.

    Like Salem said, the answer seems to be to keep in and out within the buffer bounds at all times. E.g., instead of ++in, use in = ( in + 1 ) % sizeof(buffer)
    Simplicity is the ultimate sophistication.

  5. #5
    Registered User
    Join Date
    Oct 2018
    Posts
    3
    Quote Originally Posted by john.c View Post
    Are you saying that sizes of 1 to 191 all "work"?
    Are you saying that sizes of 192 to 255 all "don't work"?

    Try to answer Salem's questions:
    1. What machine are you running this on? Are you running it at all?
    2. What compiler/etc. do you use to build the executable?
    3. What exactly happens? "It doesn't work" says very little. How may chars are transmitted before the problem? Does it halt (crash)? Does it start overwriting data, outputting garbage, what?

    The tricky points in the code have to do with unsigned char having a range of 0 to 255. So in and out will wrap around from 255 to 0 when they hit the end of that range. At some points, in will be less than out, so in - out will be negative. That would seem to be a problem with any buffer size.

    Also, the "modded index" will jump when the value wraps if the buffer size doesn't divide 256 evenly. E.g., buffer size = 191: 255 % 191 = 64, 0 % 191 = 0. So the buffer index jumps from 64 to 0.

    Like Salem said, the answer seems to be to keep in and out within the buffer bounds at all times. E.g., instead of ++in, use in = ( in + 1 ) % sizeof(buffer)
    Apologies let me clear some points up!

    No 1 to 191 don't necessarily work and same with 192 to 255. (the numbers that do work is any number to the power of 2).

    This code is used within an embedded system, although am unsure of the exact system, probably ARM based.

    I have tested this on a Windows 10 machine using Visual Studio which confirms the above.

    IIRC, it goes into an infinite loop, although I'm not 100% on that.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    36,629
    > This code is used within an embedded system, although am unsure of the exact system, probably ARM based.
    So you're not the person responsible for maintaining this code (given by your "I have no bloody clue" response).

    TBH, you need to get the person responsible for the code to ask the questions and report test results.
    Playing "Chinese whispers" where the person in the middle has no idea what the people on either side are taking about just isn't going to work.

    Do you know what a "race condition" is?
    I can see at least 4 places where there could be an issue.


    You first said
    > There is no issue with increasing the size of the buffer to 191 bytes
    Which you then retract with
    > No 1 to 191 don't necessarily work and same with 192 to 255.

    > (the numbers that do work is any number to the power of 2).
    See john.c's "modded index" comment.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 08-25-2014, 05:41 PM
  2. Replies: 1
    Last Post: 03-23-2011, 09:00 AM
  3. *szString = things question/memory question
    By Jang in forum C Programming
    Replies: 3
    Last Post: 01-20-2011, 04:59 AM
  4. Newbish Question file reading question....
    By kas2002 in forum C Programming
    Replies: 23
    Last Post: 05-17-2007, 12:06 PM
  5. Self regiserting DLLs question and libraries question.
    By ApocalypticTime in forum Windows Programming
    Replies: 2
    Last Post: 03-22-2003, 02:02 PM

Tags for this Thread