Skip to content

Commit 969733a

Browse files
adamgreenbogdanm
authored andcommitted
serial_putc() to make better use of Tx FIFO
If don't know if this is an issue that anyone cares about. I am also not sure what the best way to solve it is either. I just thought I would issue a pull request with this commit to bring the issue to light and show a possible solution that I have tested on my mbed-1768 device. Previously the serial_putc() API didn't make any use of the Tx FIFO since the serial_writable() API it utilizes only returns true when the FIFO is completely empty. This is due to the fact that the THRE bit of the UART's LSR (Line Status Register) only goes high when the whole FIFO is empty. I noticed this when doing some performance testing with the network stack. I went from calling printf() to output 3 bytes every 10 seconds (with packet drop stats) to instead output 4 bytes every 10 seconds. I thought these should easily fit in the 16 byte FIFO but outputting one extra byte caused an additional three 550 byte UDP packets to be dropped. This should only happen if the additional character being sent to the UART was taking away extra CPU cycles from the network stack. My solution is to keep track of the number of bytes that have been placed in the Tx FIFO since it was last detected as being completely empty (via the THRE bit). Only once this count hits 16 does the code then block, waiting for the THRE bit to go high. Each time the THRE bit does go high, the count is reset to 0 again and it is incremented for each byte that is loaded into the THR.
1 parent 544ac9e commit 969733a

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct pwmout_s {
4747
struct serial_s {
4848
LPC_UART_TypeDef *uart;
4949
int index;
50+
uint8_t count;
5051
};
5152

5253
struct analogin_s {

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/serial_api.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
106106
case UART_2: obj->index = 2; break;
107107
case UART_3: obj->index = 3; break;
108108
}
109+
obj->count = 0;
109110

110111
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
111112

@@ -283,14 +284,21 @@ int serial_getc(serial_t *obj) {
283284
void serial_putc(serial_t *obj, int c) {
284285
while (!serial_writable(obj));
285286
obj->uart->THR = c;
287+
obj->count++;
286288
}
287289

288290
int serial_readable(serial_t *obj) {
289291
return obj->uart->LSR & 0x01;
290292
}
291293

292294
int serial_writable(serial_t *obj) {
293-
return obj->uart->LSR & 0x20;
295+
int isWritable = 1;
296+
if (obj->uart->LSR & 0x20)
297+
obj->count = 0;
298+
else if (obj->count >= 16)
299+
isWritable = 0;
300+
301+
return isWritable;
294302
}
295303

296304
void serial_clear(serial_t *obj) {

0 commit comments

Comments
 (0)