Skip to content

Commit c4da1b5

Browse files
fangpeinaxiaoxiang781216
authored andcommitted
system/cu: Optimize I/O performance with batch read/write
Due to DMA-based transfers, the rx buffer can receive a large amount of data at once. The previous character-by-character processing approach was inefficient. Modify character-by-character read to block read of the entire buffer. This improves throughput and reduces CPU overhead, especially for high-speed serial communication or other DMA-based transfers. Signed-off-by: fangpeina <[email protected]>
1 parent 8cb7dd0 commit c4da1b5

File tree

1 file changed

+55
-29
lines changed

1 file changed

+55
-29
lines changed

system/cu/cu_main.c

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,16 @@ static FAR void *cu_listener(FAR void *parameter)
103103

104104
for (; ; )
105105
{
106+
char buf[CONFIG_LINE_MAX];
106107
int rc;
107-
char ch;
108108

109-
rc = read(cu->devfd, &ch, 1);
109+
rc = read(cu->devfd, buf, sizeof(buf));
110110
if (rc <= 0)
111111
{
112112
break;
113113
}
114114

115-
rc = write(STDOUT_FILENO, &ch, 1);
115+
rc = write(STDOUT_FILENO, buf, rc);
116116
if (rc <= 0)
117117
{
118118
break;
@@ -289,6 +289,7 @@ int main(int argc, FAR char *argv[])
289289
int start_of_line = 1;
290290
int exitval = EXIT_FAILURE;
291291
bool badarg = false;
292+
bool escaping = false;
292293

293294
/* Initialize global data */
294295

@@ -436,55 +437,80 @@ int main(int argc, FAR char *argv[])
436437

437438
while (!cu->force_exit)
438439
{
439-
char ch;
440+
char buf[CONFIG_LINE_MAX];
441+
ssize_t nwrite = 0;
442+
ssize_t nread;
443+
ssize_t i;
440444

441-
if (read(STDIN_FILENO, &ch, 1) <= 0)
445+
/* Read multiple characters at once (blocking) */
446+
447+
nread = read(STDIN_FILENO, buf, sizeof(buf));
448+
if (nread <= 0)
442449
{
443450
continue;
444451
}
445452

446-
if (start_of_line == 1 && ch == cu->escape)
453+
/* Process each character */
454+
455+
for (i = 0; i < nread; i++)
447456
{
448-
/* We've seen and escape (~) character, echo it to local
449-
* terminal and read the next char from serial
450-
*/
457+
char ch = buf[i];
451458

452-
write(STDOUT_FILENO, &ch, 1);
459+
/* Check if we're waiting for an escape command character */
453460

454-
if (read(STDIN_FILENO, &ch, 1) <= 0)
461+
if (escaping)
455462
{
456-
continue;
463+
/* We got the escape character in previous read,
464+
* now process the command character
465+
*/
466+
467+
escaping = false;
468+
if (cu_cmd(cu, ch) == 1)
469+
{
470+
cu->force_exit = true;
471+
nread = i;
472+
break;
473+
}
457474
}
458475

459-
if (ch == cu->escape)
476+
if (start_of_line == 1 && ch == cu->escape)
460477
{
461-
/* Escaping a tilde: handle like normal char */
478+
/* Normal character */
479+
480+
if (i > nwrite)
481+
{
482+
write(cu->devfd, &buf[nwrite], i - nwrite);
483+
}
484+
485+
nwrite = i + 1;
486+
487+
/* We've seen and escape (~) character, echo it to local
488+
* terminal and read the next char from serial
489+
*/
462490

463-
write(cu->devfd, &ch, 1);
491+
write(STDOUT_FILENO, &ch, 1);
492+
start_of_line = 0;
493+
escaping = true;
464494
continue;
465495
}
496+
497+
/* Determine if we are now at the start of a new line or not */
498+
499+
if (ch == '\n' || ch == '\r')
500+
{
501+
start_of_line = 1;
502+
}
466503
else
467504
{
468-
if (cu_cmd(cu, ch) == 1)
469-
{
470-
break;
471-
}
505+
start_of_line = 0;
472506
}
473507
}
474508

475509
/* Normal character */
476510

477-
write(cu->devfd, &ch, 1);
478-
479-
/* Determine if we are now at the start of a new line or not */
480-
481-
if (ch == '\n' || ch == '\r')
482-
{
483-
start_of_line = 1;
484-
}
485-
else
511+
if (nread > nwrite)
486512
{
487-
start_of_line = 0;
513+
write(cu->devfd, &buf[nwrite], nread - nwrite);
488514
}
489515
}
490516

0 commit comments

Comments
 (0)