|
|
2 周之前 | |
|---|---|---|
| .. | ||
| CherryRL | 2 周之前 | |
| builtin | 2 周之前 | |
| doc | 2 周之前 | |
| port | 2 周之前 | |
| .clang-format | 2 周之前 | |
| .gitignore | 2 周之前 | |
| .gitmodules | 2 周之前 | |
| CHANGELOG.md | 2 周之前 | |
| CMakeLists.txt | 2 周之前 | |
| LICENSE | 2 周之前 | |
| README.md | 2 周之前 | |
| README_zh.md | 2 周之前 | |
| chry_shell.c | 2 周之前 | |
| chry_shell.h | 2 周之前 | |
| csh.h | 2 周之前 | |
| csh_config_template.h | 2 周之前 | |
CherryShell is a tiny shell specifically designed for embedded applications.
$ as a prefix, e.g., $PATH$PATH environment variableCtrl + <key>, Alt + <key>, F1-F12 to invoke commandsCtrl + <key>, Alt + <key>, F1-F12SIGINT and Ctrl+Z SIGTSTPTaking the example of the HPMicro hpm5301evklite board.
// Include header file
#include "csh.h"
// Create a shell instance
static chry_shell_t csh;
// Character output function, directly outputs characters to the serial port
static uint16_t csh_sput_cb(chry_readline_t *rl, const void *data, uint16_t size)
{
uint16_t i;
(void)rl;
for (i = 0; i < size; i++) {
if (status_success != uart_send_byte(HPM_UART0, ((uint8_t *)data)[i])) {
break;
}
}
// Return the number of successfully output characters
return i;
}
// Character input function, reads characters directly from the serial port
// If the baud rate is high, a FIFO input buffer can be added
static uint16_t csh_sget_cb(chry_readline_t *rl, void *data, uint16_t size)
{
uint16_t i;
(void)rl;
for (i = 0; i < size; i++) {
if (status_success != uart_receive_byte(HPM_UART0, (uint8_t *)data + i)) {
break;
}
}
// Return the number of successfully read characters
return i;
}
// Shell initialization
int shell_init(void)
{
// Structure for configuring initialization parameters
chry_shell_init_t csh_init;
// Set the character input and output functions (must be implemented)
csh_init.sput = csh_sput_cb;
csh_init.sget = csh_sget_cb;
// Symbols defined in the linkscript, used to store exported commands and variables
extern const int __fsymtab_start;
extern const int __fsymtab_end;
extern const int __vsymtab_start;
extern const int __vsymtab_end;
// Configure the start and end addresses of the function and variable tables (must be implemented)
csh_init.command_table_beg = &__fsymtab_start;
csh_init.command_table_end = &__fsymtab_end;
csh_init.variable_table_beg = &__vsymtab_start;
csh_init.variable_table_end = &__vsymtab_end;
// Define a prompt buffer
static char csh_prompt_buffer[128];
// Configure the prompt buffer (optional)
// Depends on whether the editable prompt feature is enabled (CONFIG_CSH_PROMPTEDIT)
csh_init.prompt_buffer = csh_prompt_buffer;
csh_init.prompt_buffer_size = sizeof(csh_prompt_buffer);
// Define a history buffer
static char csh_history_buffer[128];
// Configure the history buffer (optional)
// Depends on whether the history record feature is enabled (CONFIG_CSH_LNBUFF_STATIC)
csh_init.history_buffer = csh_history_buffer;
csh_init.history_buffer_size = sizeof(csh_history_buffer);
// Define a line input buffer
static char csh_line_buffer[128];
// Configure the line input buffer (optional)
// Depends on whether the static line buffer feature is enabled (CONFIG_CSH_LNBUFF_STATIC)
// If the static line buffer feature is not enabled, the line buffer will exist on the stack,
// and non-blocking mode (CONFIG_CSH_NOBLOCK) must be set to 0
csh_init.line_buffer = csh_line_buffer;
csh_init.line_buffer_size = sizeof(csh_line_buffer);
// Default user count is 1
csh_init.uid = 0; // Default user ID
csh_init.user[0] = "cherry"; // Username for user ID 0
csh_init.hash[0] = NULL; // Password hash value for user ID 0
csh_init.host = "hpm5301evklite"; // Host name
// Initialization
int ret = chry_shell_init(&csh, &csh_init);
if (ret) {
return -1;
}
return 0;
}
// Main function of the shell, needs to be called in a while(1) loop
int shell_main(void)
{
int ret;
restart:
ret = chry_shell_task_repl(&csh);
if (ret == -1) {
// Execution failed or encountered an issue
return -1;
} else if (ret == 1) {
// Non-blocking mode: Insufficient characters read during character input, return to perform other user tasks
return 0;
} else {
// Execution successful, restart
goto restart;
}
}
// Used to avoid competition between printf and shell for the same serial port, called before printf
void shell_uart_lock(void)
{
chry_readline_erase_line(&csh.rl);
}
// Used to avoid competition between printf and shell for the same serial port, called after printf
void shell_uart_unlock(void)
{
chry_readline_edit_refresh(&csh.rl);
}
int main(void)
{
board_init();
board_init_led_pins();
shell_init();
uint32_t freq = clock_get_frequency(clock_mchtmr0);
uint64_t time = mchtmr_get_count(HPM_MCHTMR) / (freq / 1000);
while (1) {
shell_main();
// Print every 5 seconds
uint64_t now = mchtmr_get_count(HPM_MCHTMR) / (freq / 1000);
if (now > time + 5000) {
time = now;
// Call the lock to avoid printf interfering with shell input
shell_uart_lock();
printf("other task interval 5S\r\n");
shell_uart_unlock();
}
}
return 0;
}
// Implement the export of a command
// write_led 1 - Turn on the LED
// write_led 0 - Turn off the LED
static int write_led(int argc, char **argv)
{
if (argc < 2) {
printf("usage: write_led <status>\r\n\r\n");
printf(" status 0 or 1\r\n\r\n");
return -1;
}
board_led_write(atoi(argv[1]) == 0);
return 0;
}
CSH_CMD_EXPORT(write_led, );