Skip to content

Commit ff62371

Browse files
committed
Re-write the greentea_send_kv() functions to replace the use of printf,
with a set of underlying functions to write the preamble, postamble, strings and integer values, directly to the serial port (for target to host comms) using the mbed-os Rawserial class. Raw serial can be used safely from within and interrupt context, whereas printf cannot. Thus this change allows key/values to be written to the host from within interrupt context. Added instantiation of the Rawserial class, greentea_serial Added new functions: greentea_write_preamble() greentea_write_postamble() greentea_write_string() greentea_write_int() This is an internal change only within greentea_client and does not affect the user use of greentea_send_kv().
1 parent 571cfef commit ff62371

File tree

1 file changed

+146
-34
lines changed

1 file changed

+146
-34
lines changed

source/test_env.cpp

Lines changed: 146 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <ctype.h>
1919
#include <cstdio>
2020
#include <string.h>
21+
#include "mbed.h"
2122
#include "greentea-client/test_env.h"
2223

2324

@@ -55,6 +56,12 @@ static void greentea_notify_hosttest(const char *);
5556
static void greentea_notify_completion(const int);
5657
static void greentea_notify_version();
5758

59+
/**
60+
* Rawserial object used to provide direct, raw serial communications
61+
* between the target and the host.
62+
*/
63+
RawSerial greentea_serial(USBTX, USBRX);
64+
5865

5966
/** \brief Handshake with host and send setup data (timeout and host test name)
6067
* \details This function will send preamble to master.
@@ -172,52 +179,138 @@ void greentea_notify_coverage_end() {
172179
*/
173180

174181
/**
175-
* \brief Encapsulate and send key-value message from DUT to host
182+
* \brief Write the preamble characters to the serial port
183+
*
184+
* This function writes the preamble "{{" which is required
185+
* for key-value comunication between the target and the host.
186+
* This uses a Rawserial object, greentea_serial, which provides
187+
* a direct interface to the USBTX and USBRX serial pins and allows
188+
* the direct writing of characters using the putc() method.
189+
* This suite of functions are provided to allow for serial communication
190+
* to the host from within a thread/ISR.
191+
*
192+
*/
193+
inline void greentea_write_preamble()
194+
{
195+
greentea_serial.putc('{');
196+
greentea_serial.putc('{');
197+
}
198+
199+
/**
200+
* \brief Write the postamble characters to the serial port
201+
*
202+
* This function writes the postamble "{{\n" which is required
203+
* for key-value comunication between the target and the host.
204+
* This uses a Rawserial object, greentea_serial, which provides
205+
* a direct interface to the USBTX and USBRX serial pins and allows
206+
* the direct writing of characters using the putc() method.
207+
* This suite of functions are provided to allow for serial communication
208+
* to the host from within a thread/ISR.
209+
*
210+
*/
211+
inline void greentea_write_postamble()
212+
{
213+
greentea_serial.putc('}');
214+
greentea_serial.putc('}');
215+
greentea_serial.putc('\n');
216+
}
217+
218+
/**
219+
* \brief Write a string to the serial port
176220
*
177-
* This function encapsulate key-value to a string
178-
* formatted message and sends it to host (master).
221+
* This function writes a '\0' terminated string from the target
222+
* to the host. It writes directly to the serial port using the
223+
* greentea_serial, Rawserial object.
179224
*
180-
* Note: printf is hooked to stdout (serial port TX).
225+
* \param str - string value
226+
*
227+
*/
228+
inline void greentea_write_string(const char *str)
229+
{
230+
while (*str != '\0') {
231+
greentea_serial.putc(*str);
232+
str ++;
233+
}
234+
}
235+
236+
237+
/**
238+
* \brief Write an int to the serial port
239+
*
240+
* This function writes an integer value from the target
241+
* to the host. The integer value is converted to a string and
242+
* and then written character by character directly to the serial
243+
* port using the greentea_serial, Rawserial object.
244+
* sprintf() is used to convert the int to a string. Sprintf if
245+
* inherently thread safe so can be used.
246+
*
247+
* \param val - integer value
248+
*
249+
*/
250+
#define MAX_INT_STRING_LEN 15
251+
inline void greentea_write_int(const int val)
252+
{
253+
char intval[MAX_INT_STRING_LEN];
254+
unsigned int i = 0;
255+
sprintf(intval, "%d", val);
256+
while (intval[i] != '\0') {
257+
greentea_serial.putc(intval[i]);
258+
i++;
259+
}
260+
}
261+
262+
/**
263+
* \brief Encapsulate and send key-value message from DUT to host
264+
*
265+
* This function uses underlying functions to write directly
266+
* to the serial port, (USBTX). This allows KVs to be used
267+
* from within interrupt context.
181268
*
182269
* \param key Message key (message/event name)
183270
* \param value Message payload, string value
184271
*
185272
*/
186273
void greentea_send_kv(const char *key, const char *val) {
187274
if (key && val) {
188-
printf("{{%s;%s}}" NL, key, val);
275+
greentea_write_preamble();
276+
greentea_write_string(key);
277+
greentea_serial.putc(';');
278+
greentea_write_string(val);
279+
greentea_write_postamble();
189280
}
190281
}
191282

192283
/**
193284
* \brief Encapsulate and send key-value message from DUT to host
194285
*
195-
* This function encapsulate key-value to a string
196-
* formatted message and sends it to host (master). Last value
197-
* is integer to avoid integer to string conversion made
198-
* by the user in runtime we use printf to format output.
199-
*
200-
* Note: printf is hooked to stdout (serial port TX).
286+
* This function uses underlying functions to write directly
287+
* to the serial port, (USBTX). This allows KVs to be used
288+
* from within interrupt context.
289+
* Last value is an integer to avoid integer to string conversion
290+
* made by the user.
201291
*
202292
* \param key Message key (message/event name)
203293
* \param value Message payload, integer value
204294
*
205295
*/
206296
void greentea_send_kv(const char *key, const int val) {
207297
if (key) {
208-
printf("{{%s;%d}}" NL, key, val);
298+
greentea_write_preamble();
299+
greentea_write_string(key);
300+
greentea_serial.putc(';');
301+
greentea_write_int(val);
302+
greentea_write_postamble();
209303
}
210304
}
211-
305+
212306
/**
213307
* \brief Encapsulate and send key-value-value message from DUT to host
214308
*
215-
* This function encapsulate key-value-value to a string
216-
* formatted message and sends it to host (master). Last value
217-
* is integer to avoid integer to string conversion made
218-
* by the user in runtime we use printf to format output.
219-
*
220-
* Note: printf is hooked to stdout (serial port TX).
309+
* This function uses underlying functions to write directly
310+
* to the serial port, (USBTX). This allows KVs to be used
311+
* from within interrupt context.
312+
* Last value is an integer to avoid integer to string conversion
313+
* made by the user.
221314
*
222315
* \param key Message key (message/event name)
223316
* \param value Message payload, string value
@@ -226,19 +319,25 @@ void greentea_send_kv(const char *key, const int val) {
226319
*/
227320
void greentea_send_kv(const char *key, const char *val, const int result) {
228321
if (key) {
229-
printf("{{%s;%s;%d}}" NL, key, val, result);
322+
greentea_write_preamble();
323+
greentea_write_string(key);
324+
greentea_serial.putc(';');
325+
greentea_write_string(val);
326+
greentea_serial.putc(';');
327+
greentea_write_int(result);
328+
greentea_write_postamble();
329+
230330
}
231331
}
232332

233333
/**
234334
* \brief Encapsulate and send key-value-value-value message from DUT to host
235335
*
236-
* This function encapsulate key-value-value-value to a string
237-
* formatted message and sends it to host (master). Last two values
238-
* are integers to avoid integer to string conversion made
239-
* by the user in runtime we use printf to format output.
240-
*
241-
* Note: printf is hooked to stdout (serial port TX).
336+
* This function uses underlying functions to write directly
337+
* to the serial port, (USBTX). This allows KVs to be used
338+
* from within interrupt context.
339+
* Last 2 values are integers to avoid integer to string conversion
340+
* made by the user.
242341
*
243342
* Names of the parameters: this function is used to send test case
244343
* name with number of passes and failures to host. But it can be used
@@ -253,19 +352,26 @@ void greentea_send_kv(const char *key, const char *val, const int result) {
253352
*/
254353
void greentea_send_kv(const char *key, const char *val, const int passes, const int failures) {
255354
if (key) {
256-
printf("{{%s;%s;%d;%d}}" NL, key, val, passes, failures);
355+
greentea_write_preamble();
356+
greentea_write_string(key);
357+
greentea_serial.putc(';');
358+
greentea_write_string(val);
359+
greentea_serial.putc(';');
360+
greentea_write_int(passes);
361+
greentea_serial.putc(';');
362+
greentea_write_int(failures);
363+
greentea_write_postamble();
257364
}
258365
}
259366

260367
/**
261368
* \brief Encapsulate and send key-value-value message from DUT to host
262369
*
263-
* This function encapsulate key-value-value to a string and
264-
* sends it to host (master). Both values are integers to
265-
* avoid integer to string conversion made by the user in runtime
266-
* we use printf to format output.
267-
*
268-
* Note: printf is hooked to stdout (serial port TX).
370+
* This function uses underlying functions to write directly
371+
* to the serial port, (USBTX). This allows key-value-value to be used
372+
* from within interrupt context.
373+
* Both values are integers to avoid integer to string conversion
374+
* made by the user.
269375
*
270376
* Names of the parameters: this function is used to send number
271377
* of passes and failures to host. But it can be used to send any
@@ -279,7 +385,13 @@ void greentea_send_kv(const char *key, const char *val, const int passes, const
279385
*/
280386
void greentea_send_kv(const char *key, const int passes, const int failures) {
281387
if (key) {
282-
printf("{{%s;%d;%d}}" NL, key, passes, failures);
388+
greentea_write_preamble();
389+
greentea_write_string(key);
390+
greentea_serial.putc(';');
391+
greentea_write_int(passes);
392+
greentea_serial.putc(';');
393+
greentea_write_int(failures);
394+
greentea_write_postamble();
283395
}
284396
}
285397

0 commit comments

Comments
 (0)