Open peopleskai opened 5 months ago
Hi! That's interesting, can you provide some more info? At what moment does it hard fault? After any input and pressing enter, or some specific input?
Sorry i see the original post the CLI command is cut off, it is led --id 1 set 3
. The crash happens when it process CR character.
Another interesting observation to point out is that when I remove value: u8
from the Led Set command. and call led --id set
the program doesn't crash anymore.
Can you also include base command (that has id flag) and how you provide bytes to cli instance? And what buffer sizes do you use?
This is the base command and how we provide the buffer for CLI.
/// Defines CLI Commands and reference to subcommands, args and options.
/// Triplle slash comments above command names are used to define command names
/// and help documentation for the command directly from the comments.
#[derive(Debug, Command)]
pub enum BaseCommand<'a> {
/// Control LEDs
Led {
/// LED id
#[arg(long)]
id: u8,
/// Subcommand for LED control
#[command(subcommand)]
command: LedCommand,
},
/// Control ADC
Adc {
/// ADC id
#[arg(long)]
id: u8,
/// Subcommand for ADC control
#[command(subcommand)]
command: AdcCommand<'a>,
},
/// Show some status
Status,
}
// --- main loop that feeds data to CLI ---
// Creating static buffers for command history to avoid using stack memory
let (command_buffer, history_buffer) = unsafe {
static mut COMMAND_BUFFER: [u8; CMD_BUFFER_SIZE] = [0; CMD_BUFFER_SIZE];
static mut HISTORY_BUFFER: [u8; HISTORY_BUFFER_SIZE] = [0; HISTORY_BUFFER_SIZE];
(COMMAND_BUFFER.as_mut(), HISTORY_BUFFER.as_mut())
};
// Setup CLI with command buffer, history buffer, and a writer for output
let mut cli = CliBuilder::default()
.writer(writer)
.command_buffer(command_buffer)
.history_buffer(history_buffer)
.build()
.ok()
.expect("Failed to build CLI");
// Setting the CLI prompt
let _ = cli.set_prompt("main$ ");
// Global state used throughout the application
// This is used for the status command and the led simulation command
let mut state = AppState {
led_brightness: [0; 4],
num_commands: 0,
};
let _ = cli.write(|writer| {
// storing big text in progmem
// for small text it's usually better to use normal &str literals
uwrite!(
writer,
"{}",
"Cli is running.
Type \"help\" for a list of commands.
Use backspace and tab to remove chars and autocomplete.
Use up and down for history navigation.
Use left and right to move inside input."
)?;
Ok(())
});
// Loop continuously processing incoming bytes from UART and executing corresponding CLI commands
loop {
freertos_rust::CurrentTask::delay(freertos_rust::Duration::ms(2));
// Single byte buffer to read one byte at a time
let mut buffer: [u8; 1] = [0; 1];
// Single byte buffer to read one byte at a time
let bytes_read = embedded_io::Read::read(uart_rx, &mut buffer).unwrap();
defmt::dbg!("cli bytes read: {}", bytes_read);
let result = cli.process_byte::<BaseCommand<'_>, _>(
// byte_read,
buffer[0],
&mut BaseCommand::processor(|cli, command| match command {
BaseCommand::Led { id, command } => on_led(cli, &mut state, id, command),
BaseCommand::Adc { id, command } => on_adc(cli, &mut state, id, command),
BaseCommand::Status => on_status(cli, &mut state),
}),
);
...
}
We've did some testing on which commit after the v0.2.1 fixed the hardfault and the we found the last "utf8 short support" a83b84efa0a6faa062f724e063d9f096974b9197 fixes the hardfault.
Would it be possible to cut a release with the latest commit?
Thanks for the sources, I want to investigate first what was the problem before publishing a release. Can you for now use main branch using patch directive in your Cargo.toml?
Look at the commit a83b84e, I think the chagne from use a [u8]
to &str
in ArgsIter
probably fixed the problem? I don't understand the code enough to understand the root cause yet.
I did do more debugging, and stepped through the code a bit. I tried to look through the logic but haven't determine the root cause for the crash yet. Wanted to share screenshots of the call stack.
CLI command tested: "led --id 1 set 1"
There are 9 calls to the suspect function ArgsIter.next()
. In the screenshots we can see the process buffer have the correct ASCII codes.
Thanks for the debug screenshots. From them it actually seems like it's not error in library but somewhere else. This is because self.tokens is 100% valid byte slice (on last screen we see that it is 1 byte long and starts at 15th position in COMMAND_BUFFER, which is expected. But somehow calling iter().position(..) on this slice causes a hard fault. Can you provide more details about environment?
Ideally - upload somewhere whole project that can be flashed to mcu.
Hi,
I'm did a prototype for a STM32 chip using the ardiuno example as a basis. I have the same LedCommend
But this causes a hardfault, look at the call stack i can this
if let Some(pos) = self.tokens.as_bytes().iter().position(|&b| b == 0) {
let raw = self.tokens.next()?;
let res = handler.process(&mut handle, command);
The CLI com
The interesting thing is, if we clone mainline locally and compile it this hardfault goes away. Want to see if you have any insight into this issue or its an issue fixed already and just need to make a new release.