News for hackers. Stuff that matters.
Re:UART Receive Buffering by kabdib on Thursday June 11, 2015 @09:49PM (#9703557)
The mix of global buffer and passed-in struct defining the buffer made me sad. So did the lack of atomic increments and decrements (volatile ain't sufficient). Don't get me started on the getchar routine.

This stuff just isn't hard. Sigh.

Re:UART Receive Buffering by vardump on Friday June 12, 2015 @05:20AM (#9704790)
> The mix of global buffer and passed-in struct defining the buffer made me sad. So did the lack of atomic increments and decrements (volatile ain't sufficient). Don't get me started on the getchar routine.

It's for MSP430, and seems to be oriented in single core embedded microcontrollers. Those things have no atomic operations, other than disabling interrupts.

You'd be right for multicore chips or if data type is larger than word size or if data is not aligned.

But in this case, this code is correct for this architecture. All of those things you mentioned are perfectly normal and acceptable when programming microcontrollers.

http://www.simplyembedded.org/tutorials/msp430-architecture/

http://en.wikipedia.org/wiki/TI_MSP430

Re:UART Receive Buffering by kabdib on Friday June 12, 2015 @10:28AM (#9706065)
I guess you're assuming the compiler will issue an "increment" instruction for the ++, and that instruction is atomic.

It's not a great coding practice. Move to a different processor (this happens!) and your code turns into a load-add-store, gets interrupted halfway through, and you scratch your head for a while about the mysterious and flaky FIFO failures.

Been there. At least a gesture towards an atomic operation would be nice, when you have data shared between interrupt and non-interrupt code.

Re:UART Receive Buffering by onnoonno on Saturday June 13, 2015 @03:28PM (#9712280)
How about putting

#if !defined(__AVR__) && !defined(__MSP430__)

#warning "Fix this FIFO - ++/-- possibly not atomic!"

#endif

into the header of that thingy then. Save work on small uCs, and be warned when moving it somewhere else.

Re:UART Receive Buffering by shabble on Friday June 12, 2015 @01:51AM (#9704278)
Why isn't volatile sufficient here? If they were both modifying the same variable, I can see how

A:read Ax; (Interrupt: B:read Bx; B:write Bx+1; return); A: write Ax+1 # (wrong!)

could occur. But the only error I can see here is that sometimes put() might fail thinking there is overflow when there's maybe one space left.

Am I missing something?

(Further investigation: This[1] thread suggests you can run into problems if your counter type is larger than the native ALU size, because the interrupt could occur midway through your increment operation. But here the size_t is 16 bits, so that should 't be a problem?)

[1] http://www.embeddedrelated.com/showthread/msp430/20400-1.php

Re:UART Receive Buffering by cnvogel on Friday June 12, 2015 @05:12AM (#9704766)
Also the update of the write pointer could be reordered to occur before storage of the actual data flushed to the buffer.

      e.g.
      buf[volatile_write_ptr] = c
      volatile_write_ptr++;
might occur the other way 'round for the code that is reading from buf[].

For typical "simple" single processor controllers this will not be an issue, though, and "volatile"+spinlocks/disenable-enable-interrupts will work just fine.

Re:UART Receive Buffering by unwind on Friday June 12, 2015 @02:38AM (#9704371)
Yes, the ceremony to set up a ring buffer was confusing.

But isn't getchar() at least doing the same as before?

If the ring buffer is empty, ring_buffer_get() won't write to its data argument, and since getchar() passes in -1, that's what it's going to be returning if the buffer was empty. Just like it says it did before using a ring buffer.