Skip to content

Commit a7e98f1

Browse files
committed
Implement output buffering to improve TCP performance
1 parent 7890d2a commit a7e98f1

File tree

4 files changed

+85
-16
lines changed

4 files changed

+85
-16
lines changed

Shell.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ char shellfmtbuf[CONFIG_SHELL_FMT_BUFFER];
4747

4848
shell_reader_t shell_reader = 0;
4949
shell_writer_t shell_writer = 0;
50+
struct shell_outbuffer_data * obhandle = 0;
5051
bool initialized = false;
5152

5253
/*-------------------------------------------------------------*
@@ -114,6 +115,17 @@ bool shell_init(shell_reader_t reader, shell_writer_t writer, char * msg)
114115
return true;
115116
}
116117

118+
void shell_use_buffered_output(shell_bwriter_t writer)
119+
{
120+
static struct shell_outbuffer_data obd;
121+
122+
obhandle = &obd;
123+
124+
obd.shell_bwriter = writer;
125+
obd.buffercount = 0;
126+
obd.buffertimer = millis();
127+
}
128+
117129
bool shell_register(shell_program_t program, const char * string)
118130
{
119131
uint8_t i;
@@ -142,6 +154,20 @@ void shell_putc(char c)
142154
{
143155
if (initialized != false && shell_writer != 0)
144156
shell_writer(c);
157+
if (initialized != false && obhandle != 0) {
158+
// Keep track of last byte
159+
obhandle->buffertimer = millis();
160+
// Empty buffer if it´s full before storing anything else
161+
if (obhandle->buffercount >= 30) {
162+
// Write output...
163+
if (obhandle->shell_bwriter != 0)
164+
obhandle->shell_bwriter(obhandle->outbuffer, obhandle->buffercount);
165+
// and clear counter
166+
obhandle->buffercount = 0;
167+
}
168+
// Write to buffer always
169+
obhandle->outbuffer[obhandle->buffercount++] = c;
170+
}
145171
}
146172

147173
void shell_print(const char * string)
@@ -268,6 +294,17 @@ void shell_task()
268294
if (!initialized)
269295
return;
270296

297+
// Process buffered output if enabled
298+
if (obhandle != 0) {
299+
if (obhandle->buffercount != 0 && millis() - obhandle->buffertimer >= 200) {
300+
obhandle->buffertimer = millis();
301+
if (obhandle->shell_bwriter != 0)
302+
obhandle->shell_bwriter(obhandle->outbuffer, obhandle->buffercount);
303+
// and clear counter
304+
obhandle->buffercount = 0;
305+
}
306+
}
307+
271308
// Process each one of the received characters
272309
if (shell_reader(&rxchar)) {
273310

@@ -480,6 +517,7 @@ static void shell_prompt()
480517
* Shell formatted print support *
481518
*-------------------------------------------------------------*/
482519
#ifdef SHELL_PRINTF_LONG_SUPPORT
520+
483521
static void uli2a(unsigned long int num, unsigned int base, int uc, char * bf)
484522
{
485523
int n = 0;

Shell.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373

7474
/**
7575
* End of user configurable parameters, do not touch anything below this line
76-
*/
76+
*/
7777

7878
/*-------------------------------------------------------------*
7979
* Macros & definitions *
@@ -120,6 +120,12 @@ typedef void (*shell_writer_t) (char);
120120
*/
121121
typedef int (*shell_reader_t) (char *);
122122

123+
/*
124+
* Type definition for a function that sends multiple chars to the remote
125+
* terminal (function pointer)
126+
*/
127+
typedef void (*shell_bwriter_t)(char *, uint8_t);
128+
123129
/**
124130
* This enumeration defines the errors printed by the programs called by the
125131
* shell.
@@ -151,6 +157,13 @@ struct shell_command_entry {
151157
const char * shell_command_string;
152158
};
153159

160+
struct shell_outbuffer_data {
161+
char outbuffer[30];
162+
shell_bwriter_t shell_bwriter;
163+
uint32_t buffertimer;
164+
uint8_t buffercount;
165+
};
166+
154167
/*-------------------------------------------------------------*
155168
* Function prototypes *
156169
*-------------------------------------------------------------*/
@@ -172,6 +185,23 @@ extern "C" {
172185
* otherwise.
173186
*/
174187
bool shell_init(shell_reader_t reader, shell_writer_t writer, char * msg);
188+
189+
/**
190+
* @brief Enables internal output buffer for output chars
191+
*
192+
* Call this function to enable the use of an internal buffer to temporary store
193+
* characters that will be sent to a remote device. This function is meant to be
194+
* used when the communication channel performs better when many characters are
195+
* written at the same time. For example TCP/IP sockets perform better if a group
196+
* of characters are sent on a single segment.
197+
*
198+
* The content of the internal buffer is written when the it is full or if
199+
* 200 milliseconds have elapsed since the last character write on the buffer.
200+
*
201+
* @param writer The callback function used to write a group of characters on the
202+
* stream.
203+
*/
204+
void shell_use_buffered_output(shell_bwriter_t writer);
175205

176206
/**
177207
* @brief Registers a command with the command line library
@@ -242,7 +272,7 @@ extern "C" {
242272
* @param ... Aditional arguments that are inserted on the string as text
243273
*/
244274
void shell_printf(const char * fmt, ...);
245-
275+
246276
/**
247277
* @brief Prints the list of registered commands
248278
*

keywords.txt

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@
99
#######################################
1010
# Methods and Functions (KEYWORD2)
1111
#######################################
12-
shell_init KEYWORD2
13-
shell_register KEYWORD2
14-
shell_unregister_all KEYWORD2
15-
shell_putc KEYWORD2
16-
shell_print KEYWORD2
17-
shell_println KEYWORD2
18-
shell_printf KEYWORD2
19-
shell_print_commands KEYWORD2
20-
shell_print_error KEYWORD2
21-
shell_task KEYWORD2
22-
shell_print_pm KEYWORD2
23-
shell_println_pm KEYWORD2
24-
shell_printf_pm KEYWORD2
12+
shell_init KEYWORD2
13+
shell_use_buffered_output KEYWORD2
14+
shell_register KEYWORD2
15+
shell_unregister_all KEYWORD2
16+
shell_putc KEYWORD2
17+
shell_print KEYWORD2
18+
shell_println KEYWORD2
19+
shell_printf KEYWORD2
20+
shell_print_commands KEYWORD2
21+
shell_print_error KEYWORD2
22+
shell_task KEYWORD2
23+
shell_print_pm KEYWORD2
24+
shell_println_pm KEYWORD2
25+
shell_printf_pm KEYWORD2
2526

2627
#######################################
2728
# Instances (KEYWORD2)

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=GeekFactory Shell Library
2-
version=1.1.0
2+
version=1.2.0
33
author=www.geekfactory.mx
44
maintainer=Jesus Ruben Santa Anna Zamudio
55
sentence=Library to create a simple Command Line Interface (CLI).

0 commit comments

Comments
 (0)