@@ -138,36 +138,47 @@ ssize_t UARTSerial::write(const void* buffer, size_t length)
138
138
size_t data_written = 0 ;
139
139
const char *buf_ptr = static_cast <const char *>(buffer);
140
140
141
+ if (length == 0 ) {
142
+ return 0 ;
143
+ }
144
+
141
145
api_lock ();
142
146
143
- while (_txbuf.full ()) {
144
- if (!_blocking) {
145
- api_unlock ();
146
- return -EAGAIN;
147
+ // Unlike read, we should write the whole thing if blocking. POSIX only
148
+ // allows partial as a side-effect of signal handling; it normally tries to
149
+ // write everything if blocking. Without signals we can always write all.
150
+ while (data_written < length) {
151
+
152
+ if (_txbuf.full ()) {
153
+ if (!_blocking) {
154
+ break ;
155
+ }
156
+ do {
157
+ api_unlock ();
158
+ wait_ms (1 ); // XXX todo - proper wait, WFE for non-rtos ?
159
+ api_lock ();
160
+ } while (_txbuf.full ());
147
161
}
148
- api_unlock ();
149
- wait_ms (1 ); // XXX todo - proper wait, WFE for non-rtos ?
150
- api_lock ();
151
- }
152
162
153
- while (data_written < length && !_txbuf.full ()) {
154
- _txbuf.push (*buf_ptr++);
155
- data_written++;
156
- }
163
+ while (data_written < length && !_txbuf.full ()) {
164
+ _txbuf.push (*buf_ptr++);
165
+ data_written++;
166
+ }
157
167
158
- core_util_critical_section_enter ();
159
- if (!_tx_irq_enabled) {
160
- UARTSerial::tx_irq (); // only write to hardware in one place
161
- if (!_txbuf.empty ()) {
162
- SerialBase::attach (callback (this , &UARTSerial::tx_irq), TxIrq);
163
- _tx_irq_enabled = true ;
168
+ core_util_critical_section_enter ();
169
+ if (!_tx_irq_enabled) {
170
+ UARTSerial::tx_irq (); // only write to hardware in one place
171
+ if (!_txbuf.empty ()) {
172
+ SerialBase::attach (callback (this , &UARTSerial::tx_irq), TxIrq);
173
+ _tx_irq_enabled = true ;
174
+ }
164
175
}
176
+ core_util_critical_section_exit ();
165
177
}
166
- core_util_critical_section_exit ();
167
178
168
179
api_unlock ();
169
180
170
- return data_written;
181
+ return data_written != 0 ? ( ssize_t ) data_written : ( ssize_t ) -EAGAIN ;
171
182
}
172
183
173
184
ssize_t UARTSerial::read (void * buffer, size_t length)
@@ -176,6 +187,10 @@ ssize_t UARTSerial::read(void* buffer, size_t length)
176
187
177
188
char *ptr = static_cast <char *>(buffer);
178
189
190
+ if (length == 0 ) {
191
+ return 0 ;
192
+ }
193
+
179
194
api_lock ();
180
195
181
196
while (_rxbuf.empty ()) {
0 commit comments