This repository has been archived on 2023-07-17. You can view files and clone it, but cannot push or open issues or pull requests.
bl_mcu_sdk/components/shell/shell_freertos.c
2023-02-24 21:33:36 +08:00

163 lines
4.5 KiB
C

#include "shell.h"
#include <FreeRTOS.h>
#include "semphr.h"
#include "ring_buffer.h"
#include "bflb_uart.h"
static int shell_exec_argc;
static char *shell_exec_argv[SHELL_ARG_NUM];
static char shell_exec_line[SHELL_CMD_SIZE];
static ptrdiff_t shell_exec_line_diff;
TaskHandle_t shell_exec_handle;
static ATTR_NOCACHE_RAM_SECTION volatile bool shell_exec_end = true;
static void shell_exec_task(void *pvParameters)
{
shell_exec_end = false;
__ASM volatile("fence");
((cmd_function_t)(pvParameters))(shell_exec_argc, shell_exec_argv);
shell_exec_end = true;
__ASM volatile("fence");
vTaskDelete(shell_exec_handle);
shell_exec_handle = NULL;
}
void shell_dup_line(char *cmd, uint32_t length)
{
memcpy(shell_exec_line, cmd, length);
shell_exec_line_diff = shell_exec_line - cmd;
}
void shell_abort_exec(int sig)
{
(void)sig;
if (shell_exec_end == false) {
shell_exec_end = true;
__ASM volatile("fence");
vTaskDelete(shell_exec_handle);
shell_exec_handle = NULL;
}
}
int shell_start_exec(cmd_function_t func, int argc, char *argv[])
{
BaseType_t xReturned;
shell_abort_exec(SHELL_SIGINT);
shell_exec_argc = argc;
for (uint8_t i = 0; i < argc; i++) {
shell_exec_argv[i] = argv[i] + shell_exec_line_diff;
}
__ASM volatile("fence");
xReturned = xTaskCreate(shell_exec_task, (char *)"shell_exec_task", SHELL_EXEC_THREAD_STACK_SIZE, func, SHELL_EXEC_THREAD_PRIO, &shell_exec_handle);
if (xReturned == pdPASS) {
return 0;
} else {
shell_exec_end = true;
return -1;
}
}
static TaskHandle_t shell_handle;
SemaphoreHandle_t sem_shell = NULL;
Ring_Buffer_Type shell_rb;
uint8_t shell_buffer[512];
void shell_release_sem(void)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
int ret = xSemaphoreGiveFromISR(sem_shell, &xHigherPriorityTaskWoken);
if (ret == pdPASS) {
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
static struct bflb_device_s *uart_shell;
void uart_shell_isr(int irq, void *arg)
{
uint32_t intstatus = bflb_uart_get_intstatus(uart_shell);
if (intstatus & UART_INTSTS_RX_FIFO) {
while (bflb_uart_rxavailable(uart_shell)) {
Ring_Buffer_Write_Byte(&shell_rb, bflb_uart_getchar(uart_shell));
}
shell_release_sem();
}
if (intstatus & UART_INTSTS_RTO) {
while (bflb_uart_rxavailable(uart_shell)) {
Ring_Buffer_Write_Byte(&shell_rb, bflb_uart_getchar(uart_shell));
}
shell_release_sem();
bflb_uart_int_clear(uart_shell, UART_INTCLR_RTO);
}
}
static void shell_task(void *pvParameters)
{
uint8_t data;
uint32_t len;
while (1) {
if (xSemaphoreTake(sem_shell, portMAX_DELAY) == pdTRUE) {
len = Ring_Buffer_Get_Length(&shell_rb);
for (uint32_t i = 0; i < len; i++) {
Ring_Buffer_Read_Byte(&shell_rb, &data);
shell_handler(data);
}
}
}
}
void shell_init_with_task(struct bflb_device_s *shell)
{
uart_shell = shell;
vSemaphoreCreateBinary(sem_shell);
bflb_uart_rxint_mask(uart_shell, false);
bflb_irq_attach(uart_shell->irq_num, uart_shell_isr, NULL);
bflb_irq_enable(uart_shell->irq_num);
Ring_Buffer_Init(&shell_rb, shell_buffer, sizeof(shell_buffer), NULL, NULL);
shell_init();
xTaskCreate(shell_task, (char *)"shell_task", SHELL_THREAD_STACK_SIZE, NULL, SHELL_THREAD_PRIO, &shell_handle);
}
static void ps_cmd(int argc, char **argv)
{
char *pcWriteBuffer, *info;
const char *const pcHeader = "State Priority Stack # Base\r\n********************************************************\r\n";
BaseType_t xSpacePadding;
info = malloc(1536);
if (NULL == info) {
return;
}
pcWriteBuffer = info;
/* Generate a table of task stats. */
strcpy(pcWriteBuffer, "Task");
pcWriteBuffer += strlen(pcWriteBuffer);
/* Minus three for the null terminator and half the number of characters in
"Task" so the column lines up with the centre of the heading. */
for (xSpacePadding = strlen("Task"); xSpacePadding < (configMAX_TASK_NAME_LEN - 3); xSpacePadding++) {
/* Add a space to align columns after the task's name. */
*pcWriteBuffer = ' ';
pcWriteBuffer++;
/* Ensure always terminated. */
*pcWriteBuffer = 0x00;
}
strcpy(pcWriteBuffer, pcHeader);
vTaskList(pcWriteBuffer + strlen(pcHeader));
printf(info);
free(info);
}
SHELL_CMD_EXPORT_ALIAS(ps_cmd, ps, shell ps);