Serial::writeable method doesn't work as documented!

30 Nov 2013

Beware that the docs for the Serial::writeable method claims that when there is space in the buffer, it will return a 1.

So, accordingly I wrote:

writeable doesn't work this way

if (Base_serial.writeable() == 1)
{
    ...
}

but I found that the condition never got hit. I printed the return value and discovered a surprising 32 result. I'm guessing that it is returning the current number of bytes available for write buffering. When I changed the code to:

writeable seems to work this way

if (Base_serial.writeable() > 0)
{
    ...
}

then it worked as I expected and data now flows. If you use ancient C coding techniques, it is common to treat an integer return as a boolean expression, and then this approach would make more sense. However, the more contemporary practice is to avoid these unexpected/sneaky conversions which hide information and sometimes cause problems.

MBED folks, please update the docs to reflect both what is actually happening and your intended usage of the interface. I think a better approach would be to deprecate the writeable method, and replace it with 2 new methods along these lines:

alternate suggestion

bool is_writeable(void);

int buffer_bytes_available(void);

Question: Does Serial::readable() do the same thing?

-Dan

02 Dec 2013

Thank you for posting this information, I agree with the suggestion at the end. Have you/maybe you should post this in the bugs and suggestion forum as well?

02 Dec 2013

Personally I don't think it is needed to split them in two functions, it would actually be a nice feature, if of course properly documented.

I can't test it right now myself, but from the LPC1768s code (which you have according to your profile):

int serial_writable(serial_t *obj) {
    int isWritable = 1;
    if (obj->uart->LSR & 0x20)
        obj->count = 0;
    else if (obj->count >= 16)
        isWritable = 0;
        
    return isWritable;
}

That can never return anything other than 0 or 1.