Skip to content

Commit 242bca9

Browse files
committed
Implement thread-safe uart
1 parent 17c8ceb commit 242bca9

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

cores/esp32/esp32-hal-uart.c

+40-4
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,21 @@ static int s_uart_debug_nr = 0;
4040

4141
struct uart_struct_t {
4242
uart_dev_t * dev;
43+
xSemaphoreHandle lock;
4344
uint8_t num;
4445
xQueueHandle queue;
4546
};
4647

48+
#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS)
49+
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
50+
51+
#define UART_MUTEX_LOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) do {} while (xSemaphoreTake(_uart_bus_array[i].lock, portMAX_DELAY) != pdPASS)
52+
#define UART_MUTEX_UNLOCK_NUM(i) if(_uart_bus_array[i].lock != NULL) xSemaphoreGive(_uart_bus_array[i].lock)
53+
4754
static uart_t _uart_bus_array[3] = {
48-
{(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL},
49-
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL},
50-
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL}
55+
{(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL},
56+
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL},
57+
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL}
5158
};
5259

5360
static void IRAM_ATTR _uart_isr(void *arg)
@@ -88,6 +95,7 @@ void uartDisableGlobalInterrupt()
8895

8996
void uartEnableInterrupt(uart_t* uart)
9097
{
98+
UART_MUTEX_LOCK();
9199
uart->dev->conf1.rxfifo_full_thrhd = 112;
92100
uart->dev->conf1.rx_tout_thrhd = 2;
93101
uart->dev->conf1.rx_tout_en = 1;
@@ -97,13 +105,16 @@ void uartEnableInterrupt(uart_t* uart)
97105
uart->dev->int_clr.val = 0xffffffff;
98106

99107
intr_matrix_set(xPortGetCoreID(), UART_INTR_SOURCE(uart->num), ETS_UART_INUM);
108+
UART_MUTEX_UNLOCK();
100109
}
101110

102111
void uartDisableInterrupt(uart_t* uart)
103112
{
113+
UART_MUTEX_LOCK();
104114
uart->dev->conf1.val = 0;
105115
uart->dev->int_ena.val = 0;
106116
uart->dev->int_clr.val = 0xffffffff;
117+
UART_MUTEX_UNLOCK();
107118
}
108119

109120
void uartDetachRx(uart_t* uart)
@@ -154,7 +165,14 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
154165
}
155166

156167
uart_t* uart = &_uart_bus_array[uart_nr];
157-
168+
169+
if(uart->lock == NULL) {
170+
uart->lock = xSemaphoreCreateMutex();
171+
if(uart->lock == NULL) {
172+
return NULL;
173+
}
174+
}
175+
158176
if(queueLen && uart->queue == NULL) {
159177
uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue
160178
if(uart->queue == NULL) {
@@ -164,7 +182,9 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
164182

165183
uartFlush(uart);
166184
uartSetBaudRate(uart, baudrate);
185+
UART_MUTEX_LOCK();
167186
uart->dev->conf0.val = config;
187+
UART_MUTEX_UNLOCK();
168188

169189
if(rxPin != -1) {
170190
uartAttachRx(uart, rxPin, inverted);
@@ -183,6 +203,7 @@ void uartEnd(uart_t* uart)
183203
return;
184204
}
185205

206+
UART_MUTEX_LOCK();
186207
if(uart->queue != NULL) {
187208
vQueueDelete(uart->queue);
188209
}
@@ -191,6 +212,7 @@ void uartEnd(uart_t* uart)
191212
uartDetachTx(uart);
192213

193214
uart->dev->conf0.val = 0;
215+
UART_MUTEX_UNLOCK();
194216
}
195217

196218
uint32_t uartAvailable(uart_t* uart)
@@ -230,21 +252,25 @@ void uartWrite(uart_t* uart, uint8_t c)
230252
if(uart == NULL) {
231253
return;
232254
}
255+
UART_MUTEX_LOCK();
233256
while(uart->dev->status.rxfifo_cnt == 0x7F);
234257
uart->dev->fifo.rw_byte = c;
258+
UART_MUTEX_UNLOCK();
235259
}
236260

237261
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
238262
{
239263
if(uart == NULL) {
240264
return;
241265
}
266+
UART_MUTEX_LOCK();
242267
while(len) {
243268
while(len && uart->dev->status.rxfifo_cnt < 0x7F) {
244269
uart->dev->fifo.rw_byte = *data++;
245270
len--;
246271
}
247272
}
273+
UART_MUTEX_UNLOCK();
248274
}
249275

250276
void uartFlush(uart_t* uart)
@@ -253,23 +279,27 @@ void uartFlush(uart_t* uart)
253279
return;
254280
}
255281

282+
UART_MUTEX_LOCK();
256283
while(uart->dev->status.txfifo_cnt);
257284

258285
uart->dev->conf0.txfifo_rst = 1;
259286
uart->dev->conf0.txfifo_rst = 0;
260287

261288
uart->dev->conf0.rxfifo_rst = 1;
262289
uart->dev->conf0.rxfifo_rst = 0;
290+
UART_MUTEX_UNLOCK();
263291
}
264292

265293
void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
266294
{
267295
if(uart == NULL) {
268296
return;
269297
}
298+
UART_MUTEX_LOCK();
270299
uint32_t clk_div = ((UART_CLK_FREQ<<4)/baud_rate);
271300
uart->dev->clk_div.div_int = clk_div>>4 ;
272301
uart->dev->clk_div.div_frag = clk_div & 0xf;
302+
UART_MUTEX_UNLOCK();
273303
}
274304

275305
uint32_t uartGetBaudRate(uart_t* uart)
@@ -283,20 +313,26 @@ uint32_t uartGetBaudRate(uart_t* uart)
283313

284314
static void IRAM_ATTR uart0_write_char(char c)
285315
{
316+
UART_MUTEX_LOCK_NUM(0);
286317
while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
287318
ESP_REG(DR_REG_UART_BASE) = c;
319+
UART_MUTEX_UNLOCK_NUM(0);
288320
}
289321

290322
static void IRAM_ATTR uart1_write_char(char c)
291323
{
324+
UART_MUTEX_LOCK_NUM(1);
292325
while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
293326
ESP_REG(DR_REG_UART1_BASE) = c;
327+
UART_MUTEX_UNLOCK_NUM(1);
294328
}
295329

296330
static void IRAM_ATTR uart2_write_char(char c)
297331
{
332+
UART_MUTEX_LOCK_NUM(2);
298333
while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
299334
ESP_REG(DR_REG_UART2_BASE) = c;
335+
UART_MUTEX_UNLOCK_NUM(2);
300336
}
301337

302338
void uartSetDebug(uart_t* uart)

0 commit comments

Comments
 (0)