@@ -4,7 +4,7 @@ pub struct Stdin;
44pub struct Stdout ;
55pub type Stderr = Stdout ;
66
7- const STDIO_CHANNEL : u32 = 1 ;
7+ pub const STDIO_CHANNEL : u32 = 1 ;
88
99impl Stdin {
1010 pub const fn new ( ) -> Stdin {
@@ -40,17 +40,29 @@ impl Stdout {
4040
4141impl io:: Write for Stdout {
4242 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
43- let written =
44- unsafe { vex_sdk:: vexSerialWriteBuffer ( STDIO_CHANNEL , buf. as_ptr ( ) , buf. len ( ) as u32 ) } ;
45-
46- if written < 0 {
47- return Err ( io:: Error :: new (
48- io:: ErrorKind :: Uncategorized ,
49- "Internal write error occurred." ,
50- ) ) ;
43+ let mut count = 0 ;
44+
45+ // HACK: VEXos holds an internal write buffer for serial that is flushed to USB1 roughly every
46+ // millisecond by `vexTasksRun`. For writes larger than 2048 bytes, we must block until that buffer
47+ // is flushed to USB1 before writing the rest of `buf`. In practice, this is fairly nonstandard for
48+ // a `write` implementation but it avoids an guaranteed recursive panic when using macros such as
49+ // `print!` to write large amounts of data to stdout at once.
50+ for chunk in buf. chunks ( STDOUT_BUF_SIZE ) {
51+ if unsafe { vex_sdk:: vexSerialWriteFree ( STDIO_CHANNEL ) as usize } < chunk. len ( ) {
52+ self . flush ( ) . unwrap ( ) ;
53+ }
54+
55+ count += unsafe { vex_sdk:: vexSerialWriteBuffer ( STDIO_CHANNEL , chunk. as_ptr ( ) , chunk. len ( ) as u32 ) } ;
56+
57+ if count < 0 {
58+ return Err ( io:: Error :: new (
59+ io:: ErrorKind :: Uncategorized ,
60+ "Internal write error occurred." ,
61+ ) ) ;
62+ }
5163 }
5264
53- Ok ( written as usize )
65+ Ok ( count as usize )
5466 }
5567
5668 fn flush ( & mut self ) -> io:: Result < ( ) > {
0 commit comments