Skip to content

Commit cbb84d8

Browse files
committed
Asynchronous Serial API fixes and refactoring, part 2
Aborting of asynchronous operation is necessarily hazardous, as operation can end in interrupt anywhere from the point of decision until it is actually aborted down the abort_...() method. Proper deep sleep unlocking requires then use of the critical section and should be contained completely within API implementation.
1 parent 6d64809 commit cbb84d8

File tree

1 file changed

+40
-16
lines changed

1 file changed

+40
-16
lines changed

drivers/SerialBase.cpp

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -201,20 +201,28 @@ void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2)
201201

202202
int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t &callback, int event)
203203
{
204-
if (serial_tx_active(&_serial)) {
205-
return -1; // transaction ongoing
204+
int result = 0;
205+
lock();
206+
if (!serial_tx_active(&_serial) && !_tx_asynch_set) {
207+
start_write((void *)buffer, length, 8, callback, event);
208+
} else {
209+
result = -1; // transaction ongoing
206210
}
207-
start_write((void *)buffer, length, 8, callback, event);
208-
return 0;
211+
unlock();
212+
return result;
209213
}
210214

211215
int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t &callback, int event)
212216
{
213-
if (serial_tx_active(&_serial)) {
214-
return -1; // transaction ongoing
217+
int result = 0;
218+
lock();
219+
if (!serial_tx_active(&_serial) && !_tx_asynch_set) {
220+
start_write((void *)buffer, length, 16, callback, event);
221+
} else {
222+
result = -1; // transaction ongoing
215223
}
216-
start_write((void *)buffer, length, 16, callback, event);
217-
return 0;
224+
unlock();
225+
return result;
218226
}
219227

220228
void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t &callback, int event)
@@ -229,22 +237,30 @@ void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_wi
229237

230238
void SerialBase::abort_write(void)
231239
{
240+
lock();
241+
core_util_critical_section_enter();
232242
if (_tx_asynch_set) {
233243
_tx_callback = NULL;
234244
_tx_asynch_set = false;
235245
serial_tx_abort_asynch(&_serial);
236246
sleep_manager_unlock_deep_sleep();
237247
}
248+
core_util_critical_section_exit();
249+
unlock();
238250
}
239251

240252
void SerialBase::abort_read(void)
241253
{
254+
lock();
255+
core_util_critical_section_enter();
242256
if (_rx_asynch_set) {
243257
_rx_callback = NULL;
244258
_rx_asynch_set = false;
245259
serial_rx_abort_asynch(&_serial);
246260
sleep_manager_unlock_deep_sleep();
247261
}
262+
core_util_critical_section_exit();
263+
unlock();
248264
}
249265

250266
int SerialBase::set_dma_usage_tx(DMAUsage usage)
@@ -267,21 +283,29 @@ int SerialBase::set_dma_usage_rx(DMAUsage usage)
267283

268284
int SerialBase::read(uint8_t *buffer, int length, const event_callback_t &callback, int event, unsigned char char_match)
269285
{
270-
if (serial_rx_active(&_serial)) {
271-
return -1; // transaction ongoing
286+
int result = 0;
287+
lock();
288+
if (!serial_rx_active(&_serial) && !_rx_asynch_set) {
289+
start_read((void *)buffer, length, 8, callback, event, char_match);
290+
} else {
291+
result = -1; // transaction ongoing
272292
}
273-
start_read((void *)buffer, length, 8, callback, event, char_match);
274-
return 0;
293+
unlock();
294+
return result;
275295
}
276296

277297

278298
int SerialBase::read(uint16_t *buffer, int length, const event_callback_t &callback, int event, unsigned char char_match)
279299
{
280-
if (serial_rx_active(&_serial)) {
281-
return -1; // transaction ongoing
300+
int result = 0;
301+
lock();
302+
if (!serial_rx_active(&_serial) && !_rx_asynch_set) {
303+
start_read((void *)buffer, length, 16, callback, event, char_match);
304+
} else {
305+
result = -1; // transaction ongoing
282306
}
283-
start_read((void *)buffer, length, 16, callback, event, char_match);
284-
return 0;
307+
unlock();
308+
return result;
285309
}
286310

287311

0 commit comments

Comments
 (0)