From 30dc17b3a84885efea34be0082d3751f8839cdfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Fri, 9 Aug 2024 01:12:48 +0800 Subject: [PATCH 01/12] =?UTF-8?q?test:=20=E2=9C=85=20=E6=B7=BB=E5=8A=A0STM?= =?UTF-8?q?32=20HAL=E5=BA=93=E7=A7=BB=E6=A4=8Ddemo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/easy_for_keil/ringbuffer/ringbuffer.c | 227 +++++++++++++ demo/easy_for_keil/ringbuffer/ringbuffer.h | 64 ++++ demo/easy_for_keil/shell_all.c | 321 ++++++++++++++++++ demo/easy_for_keil/shell_all.h | 83 +++++ demo/easy_for_keil/shell_cfg_user.h | 113 ++++++ .../stm32_HAL_adapt/stm32_HAL_adapt.c | 161 +++++++++ .../stm32_HAL_adapt/stm32_HAL_adapt.h | 75 ++++ extensions/log/log.h | 30 +- extensions/shell_enhance/shell_cmd_group.h | 1 + 9 files changed, 1060 insertions(+), 15 deletions(-) create mode 100644 demo/easy_for_keil/ringbuffer/ringbuffer.c create mode 100644 demo/easy_for_keil/ringbuffer/ringbuffer.h create mode 100644 demo/easy_for_keil/shell_all.c create mode 100644 demo/easy_for_keil/shell_all.h create mode 100644 demo/easy_for_keil/shell_cfg_user.h create mode 100644 demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c create mode 100644 demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h diff --git a/demo/easy_for_keil/ringbuffer/ringbuffer.c b/demo/easy_for_keil/ringbuffer/ringbuffer.c new file mode 100644 index 0000000..02ba04f --- /dev/null +++ b/demo/easy_for_keil/ringbuffer/ringbuffer.c @@ -0,0 +1,227 @@ +#include "ringbuffer.h" +#include + +#undef USER_ASSERT +#define USER_ASSERT(exp) (void)0 // 开启此宏关闭此文件用户自定义断言 + +// clang-format off +#ifndef USER_ASSERT + #include + #define USER_ASSERT(exp) \ + if (!(exp)) \ + { \ + printf("\"" #exp "\" assert failed at file: %s, line: %d", __FILE__, __LINE__); \ + for (;;) \ + ; \ + } +#endif // ! USER_ASSERT +// clang-format on + +void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + rb->buffer = buffer; + rb->buffer_size = size; + rb->busy = false; + + ringbuffer_reset(rb); +} + +void ringbuffer_reset(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + rb->head = 0; + rb->tail = 0; + rb->data_count = 0; +} + +uint16_t ringbuffer_get_free(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->buffer_size - rb->data_count; +} + +uint16_t ringbuffer_get_used(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->data_count; +} + +uint16_t ringbuffer_get_size(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->buffer_size; +} + +uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->last_series_count; +} + +uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + uint16_t free_size = ringbuffer_get_free(rb); + + if (size > free_size) + { + size = free_size; // 多余的数据不写入(丢掉) + } + + // 判断超过尾部没有 + if (rb->tail + size > rb->buffer_size) + { + uint16_t first_size = rb->buffer_size - rb->tail; + memcpy((uint8_t *)(rb->buffer) + rb->tail, data, first_size); + memcpy(rb->buffer, data + first_size, size - first_size); + } + else + { + memcpy((uint8_t *)(rb->buffer) + rb->tail, data, size); + } + + // 限制尾部位置 + if (rb->tail + size >= rb->buffer_size) + { + rb->tail = size - (rb->buffer_size - rb->tail); + } + else + { + rb->tail += size; + } + + rb->data_count += size; + + return size; +} + +uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + uint16_t used_size = ringbuffer_get_used(rb); + + if (size > used_size) + { + size = used_size; // 读取的数据超过了已有数据量 + } + + // 判断超过尾部没有 + if (rb->head + size > rb->buffer_size) + { + uint16_t first_size = rb->buffer_size - rb->head; + memcpy(data, (uint8_t *)(rb->buffer) + rb->head, first_size); + memcpy(data + first_size, rb->buffer, size - first_size); + } + else + { + memcpy(data, (uint8_t *)(rb->buffer) + rb->head, size); + } + + // 限制头部位置 + if (rb->head + size >= rb->buffer_size) + { + rb->head = size - (rb->buffer_size - rb->head); + } + else + { + rb->head += size; + } + + rb->data_count -= size; + + return size; +} + +uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size) +{ + USER_ASSERT(rb != NULL); + USER_ASSERT(size != NULL); + uint16_t max_size = ringbuffer_get_free(rb); + + if (max_size + rb->tail > rb->buffer_size) + { + max_size = rb->buffer_size - rb->tail; + } + + *size = max_size; + rb->last_series_count = max_size; + + return (uint8_t *)(rb->buffer) + rb->tail; +} + +uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size) +{ + USER_ASSERT(rb != NULL); + USER_ASSERT(size != NULL); + uint16_t max_size = ringbuffer_get_used(rb); + + if (max_size + rb->head > rb->buffer_size) + { + max_size = rb->buffer_size - rb->head; + } + + *size = max_size; + rb->last_series_count = max_size; + + return (uint8_t *)(rb->buffer) + rb->head; +} + +uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + // 限制尾部位置 + if (rb->tail + size >= rb->buffer_size) + { + rb->tail = size - (rb->buffer_size - rb->tail); + } + else + { + rb->tail += size; + } + + rb->data_count += size; + + return size; +} + +uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + // 限制头部位置 + if (rb->head + size >= rb->buffer_size) + { + rb->head = size - (rb->buffer_size - rb->head); + } + else + { + rb->head += size; + } + + rb->data_count -= size; + + return size; +} + +void ringbuffer_mark_busy(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + rb->busy = true; +} + +void ringbuffer_mark_idle(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + rb->busy = false; +} + +bool ringbuffer_is_busy(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->busy; +} diff --git a/demo/easy_for_keil/ringbuffer/ringbuffer.h b/demo/easy_for_keil/ringbuffer/ringbuffer.h new file mode 100644 index 0000000..c79d2d2 --- /dev/null +++ b/demo/easy_for_keil/ringbuffer/ringbuffer.h @@ -0,0 +1,64 @@ +/** + * @file ringbuffer.h + * @author 独霸一方 (2696652257@qq.com) + * @brief //> 部分参考cherryRB实现的环形缓冲区,完整实现参考:https://github.com/cherry-embedded/CherryRB + * 源码直接加入shell_all.c中进行编译,无需再次添加此目录下.c文件进行编译 + * @version 1.0 + * @date 2024-08-05 + * + * @copyright Copyright (c) 2024 + * + */ + +// > 单次包含宏定义 +#ifndef __RINGBUFFER_H_ +#define __RINGBUFFER_H_ + +#include +#include +#include + +// > C/C++兼容性宏定义 +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct __ringbuffer_t ringbuffer_t; + struct __ringbuffer_t + { + bool busy; // 用于指示'慢速'外设是否正在操作缓冲区,比如DMA传输 + uint16_t head; + uint16_t tail; + uint16_t data_count; // 当前队列中的数据量 + uint16_t last_series_count; // 调用连续读或写时候实际设置的值 + uint16_t buffer_size; // 缓冲区大小 + uint8_t *buffer; + }; + + void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size); + void ringbuffer_reset(ringbuffer_t *rb); + + uint16_t ringbuffer_get_free(ringbuffer_t *rb); // 获取剩余空间 + uint16_t ringbuffer_get_used(ringbuffer_t *rb); // 获取已使用空间 + uint16_t ringbuffer_get_size(ringbuffer_t *rb); // 获取缓冲区大小 + uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb); // 获取上次调用线性读取或者写入时候的设置的大小 + + uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size); // 返回实际写入的数据量 + uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size); // 返回实际读取的数据量 + + // for linear read/write operation(such as DMA) + extern uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size); // 返回写入的地址并设置实际能写入的数据量 + extern uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size); // 返回读取的地址并设置实际能读取的数据量 + extern uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size); // 返回实际写入的数据量 + extern uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size); // 返回实际读取的数据量 + + void ringbuffer_mark_busy(ringbuffer_t *rb); + void ringbuffer_mark_idle(ringbuffer_t *rb); + bool ringbuffer_is_busy(ringbuffer_t *rb); + +#ifdef __cplusplus +} +#endif //\ __cplusplus + +#endif //\ __RINGBUFFER_H_ diff --git a/demo/easy_for_keil/shell_all.c b/demo/easy_for_keil/shell_all.c new file mode 100644 index 0000000..d61c2c6 --- /dev/null +++ b/demo/easy_for_keil/shell_all.c @@ -0,0 +1,321 @@ +#include "shell_all.h" + +#include +#include + +// 将所有的源码文件加入到这一个文件中,方便Keil工程的添加 + +#if 1 + +#include "./ringbuffer/ringbuffer.c" // 环形队列 + +// shell核心实现包含 +#include "../../src/shell.c" +#include "../../src/shell_ext.c" +#include "../../src/shell_cmd_list.c" +#include "../../src/shell_companion.c" + +// shell拓展组件 + +// shell增强组件 +#include "../../extensions/shell_enhance/shell_cmd_group.c" // 命令组 +#include "../../extensions/shell_enhance/shell_passthrough.c" // 透传 +#include "../../extensions/shell_enhance/shell_secure_user.c" // 安全用户 + +// shell log组件 +#include "../../extensions/log/log.c" // 日志 + +//// shell fs组件 +// #include "../../extensions/fs_support/shell_fs.c" // 文件命令 + +//// shell telnet组件 +// #include "../../extensions/telnet/telnetd.c" // telnet,需要命令组拓展(注意头文件路径包含) + +#endif + +//// shell game组件需要单独添加.c到工程中,不然会有一些同名函数的问题 +// #include "../../extensions/game/game.c" // 游戏,需要命令组拓展(注意头文件路径包含) +// #include "../../extensions/game/2048/2048.c" // 2048 +// #include "../../extensions/game/pushbox/pushbox.c" // 贪吃蛇 + +//+********************************* 环形队列中转 **********************************/ +#if SHELL_SHOW_INFO == 1 +#if SHELL_TX_BUFFER_SIZE < 400 +#warning "建议将环形队列的大小设置为大于400,否则打印初始化信息的时候可能会出现部分打印数据丢失" +#warning "shell tx buffer size is too small, please increase the buffer size" +#endif +#endif + +// 定义shell和log对象 +static Shell user_shell; +static Log user_log; + +// 发送和接收的中转环形缓冲队列 +static ringbuffer_t rb_rx; +static ringbuffer_t rb_tx; + +// 写入是否可以阻塞,默认不可以阻塞,一般判断是否在中断中就可以判断是否可以阻塞 +#ifndef SHELL_WRITE_CAN_BLOCK +#define SHELL_WRITE_CAN_BLOCK() (false) +#endif // !SHELL_WRITE_CAN_BLOCK + +//+********************************* shell读写对接 **********************************/ + +short write_to_ringbuffer(char *data, unsigned short len) +{ + short total_written = 0; + short ret = 0; + + while (len > 0) + { + SHELL_ATOMIC_ENTER(); + + ret = ringbuffer_write(&rb_tx, (uint8_t *)data, len); + + SHELL_ATOMIC_EXIT(); + + if (ret >= len) // 只可能小于等于 + { + return total_written; // 全部数据写入成功 + } + else + { + if (!SHELL_WRITE_CAN_BLOCK()) + { + total_written += ret; + break; // 如果在中断中,直接退出,未写入的数据直接丢弃,避免长时间占用中断 + } + + total_written += ret; + data += ret; + len -= ret; + port_tx_trigger(); // 主动尝试触发发送 + + WAIT_A_MOMENT(); // 等待一段时间,避免频繁触发发送 + } + } + + return total_written; +} + +short read_from_ringbuffer(char *data, unsigned short len) +{ + short ret = 0; + SHELL_ATOMIC_ENTER(); + + ret = ringbuffer_read(&rb_rx, (uint8_t *)data, len); + + SHELL_ATOMIC_EXIT(); + return ret; +} + +//+******************************** log组件对接 ***************************************/ + +void UserLogWrite(char *buffer, short len) +{ +#if SHELL_SUPPORT_END_LINE == 1 + USER_ASSERT(user_log.shell != NULL); + shellWriteEndLine(user_log.shell, buffer, len); +#else + USER_ASSERT(user_log.shell != NULL); + USER_ASSERT(user_log.shell->write != NULL); + user_log.shell->write(buffer, len); +#endif +} + +//+******************************** 对外调用接口 ***************************************/ +void port_tx_trigger(void) +{ + if (ringbuffer_is_busy(&rb_tx) || ringbuffer_get_used(&rb_tx) <= 0) + { + return; // 没有数据或者外设还在响应上一次的发送 + } + + // 这两个栈变量可能会在极端情况下破坏原子操作性,改成static然后提到函数开头效果可能会更好 + uint16_t size; + uint8_t *p; + + SHELL_ATOMIC_ENTER(); + + // 获取ringbuffer当前的读指针和最大线性可读数据大小 + ringbuffer_mark_busy(&rb_tx); // 标记为忙,调用port_tx_end函数后再标记为闲 + p = ringbuffer_linear_read_setup(&rb_tx, &size); + + SHELL_ATOMIC_EXIT(); + + // 发送数据,调用平台相关的发送函数 + PLATFORM_TX_WRAP(p, size); +} + +void port_rx_trigger(void) +{ + + if (ringbuffer_is_busy(&rb_rx) || ringbuffer_get_free(&rb_rx) <= 0) // 性能优化,对于接收,外设忙的情况更多先判断是否在忙 + { + return; // 没有空间接收或者正在接收数据 + } + + // 这两个栈变量可能会在极端情况下破坏原子操作性,改成static然后提到函数开头效果可能会更好 + uint16_t size; + uint8_t *p; + + SHELL_ATOMIC_ENTER(); + ringbuffer_mark_busy(&rb_rx); // 标记为忙,调用port_rx_end函数后再标记为闲 + // 获取ringbuffer当前的写指针和最大线性可写数据大小 + p = ringbuffer_linear_write_setup(&rb_rx, &size); + + SHELL_ATOMIC_EXIT(); + + // 接收数据,调用平台相关的接收函数 + PLATFORM_RX_WRAP(p, size); +} + +// 通常用于中断中调用 +void port_tx_end(short truely_tx_len) +{ + SHELL_ATOMIC_ENTER(); + if (truely_tx_len < 0) + { + truely_tx_len = ringbuffer_get_last_series_size(&rb_tx); + } + + ringbuffer_linear_read_done(&rb_tx, truely_tx_len); + ringbuffer_mark_idle(&rb_tx); + + SHELL_ATOMIC_EXIT(); + +#if SHELL_TX_CONTINUOUSLY + port_tx_trigger(); // 继续发送 +#endif +} + +void port_rx_end(short truely_rx_len) +{ + SHELL_ATOMIC_ENTER(); + if (truely_rx_len < 0) + { + truely_rx_len = ringbuffer_get_last_series_size(&rb_rx); + } + + ringbuffer_linear_write_done(&rb_rx, truely_rx_len); + ringbuffer_mark_idle(&rb_rx); + SHELL_ATOMIC_EXIT(); + +#if SHELL_RX_CONTINUOUSLY + //! 继续接收,如果这里由于队列满了导致没有触发接收,那么直到再次触发接收之前,都不会再接收数据了 + port_rx_trigger(); +#endif +} + +//+******************************** shell和log组件初始化,shell任务 ***************************************/ + +void letter_shell_init(void) +{ + PLATFORM_INIT(); + + // 初始化输入输出环形队列 + static char rb_rx_buffer[SHELL_RX_BUFFER_SIZE]; + static char rb_tx_buffer[SHELL_TX_BUFFER_SIZE]; + ringbuffer_init(&rb_rx, (uint8_t *)rb_rx_buffer, sizeof(rb_rx_buffer)); + ringbuffer_init(&rb_tx, (uint8_t *)rb_tx_buffer, sizeof(rb_tx_buffer)); + + // 用于存放命令之类的buffer + static char shell_buffer[512]; + + user_shell.write = write_to_ringbuffer; + user_shell.read = read_from_ringbuffer; +#if SHELL_USING_LOCK == 1 + +#if !defined(SHELL_LOCK_FUNC) || !defined(SHELL_UNLOCK_FUNC) +#error "请定义shell的加锁与解锁函数或者不使用log锁(设置SHELL_USING_LOCK为0)" +#error "please define SHELL_LOCK_FUNC and SHELL_UNLOCK_FUNC" +#endif + user_shell.lock = SHELL_LOCK_FUNC; + user_shell.unlock = SHELL_UNLOCK_FUNC; +#endif + shellInit(&user_shell, shell_buffer, sizeof(shell_buffer)); // 初始化shell + + user_log.active = 1; // 创建log对象,默认输出所有等级的log + user_log.level = LOG_ALL; + user_log.write = UserLogWrite, +#if LOG_USING_LOCK == 1 + +#if !defined(LOG_LOCK_FUNC) || !defined(LOG_UNLOCK_FUNC) +#error "请定义log的加锁与解锁函数或者不使用log锁(设置LOG_USING_LOCK为0)" +#error "please define LOG_LOCK_FUNC and LOG_UNLOCK_FUNC" +#endif + + user_log.lock = LOG_LOCK_FUNC; + user_log.unlock = LOG_UNLOCK_FUNC; +#endif + + logRegister(&user_log, &user_shell); // 注册log +} + +void shell_task() +{ +#if SHELL_TASK_WHILE == 1 + for (;;) + { +#endif + port_tx_trigger(); + port_rx_trigger(); + // 读取数据进行处理,这里可以多读几个字节,提高处理效率 + static char data; + // while (user_shell.read(&data, 1)) + if (user_shell.read(&data, 1)) + { + shellHandler(&user_shell, data); + } +#if SHELL_TASK_WHILE == 1 + } +#endif +} + +//+********************************* 导出一些可能用到的命令或快捷键 **********************************/ +static void logChangeLevel() +{ + Log *log = &user_log; + SHELL_ASSERT(log, return); + log->level = (LogLevel)(log->level >= LOG_ALL ? LOG_NONE : (log->level + 1)); + + char logLevel[40] = {0}; + switch (log->level) + { + case LOG_NONE: + sprintf(logLevel, "set log level : LOG_NONE\t(%d)", log->level); + break; + + case LOG_ERROR: + sprintf(logLevel, "set log level : LOG_ERROR\t(%d)", log->level); + break; + + case LOG_WRANING: + sprintf(logLevel, "set log level : LOG_WRANING\t(%d)", log->level); + break; + + case LOG_INFO: + sprintf(logLevel, "set log level : LOG_INFO\t(%d)", log->level); + break; + + case LOG_DEBUG: + sprintf(logLevel, "set log level : LOG_DEBUG\t(%d)", log->level); + break; + + case LOG_VERBOSE: + sprintf(logLevel, "set log level : LOG_VERBOSE\t(%d)", log->level); + break; + + case LOG_ALL: + sprintf(logLevel, "set log level : LOG_ALL\t\t(%d)", log->level); + break; + + default: + break; + } + + logPrintln("%s", logLevel); +} +//> 0x04000000对应的应该是鼠标中键,但是在Xshell中,按下鼠标中间会以字符串的形式发送04000000,导致无法触发,现在修改为 ~ 的按键值 +// SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x04000000, logChangeLevel, switch log level); +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x60000000, logChangeLevel, '~' switch log level); \ No newline at end of file diff --git a/demo/easy_for_keil/shell_all.h b/demo/easy_for_keil/shell_all.h new file mode 100644 index 0000000..5790039 --- /dev/null +++ b/demo/easy_for_keil/shell_all.h @@ -0,0 +1,83 @@ +/** + * @file shell_all.h + * @author 独霸一方 (2696652257@qq.com) + * @brief //> 这个文件将包含letter shell的所有头文件实现(相对路径),方便在Keil工程中使用 + * @version 1.0 + * @date 2024-08-05 + * + * @copyright Copyright (c) 2024 + * + */ + +// 此文件使用相对路径,保证在任何地方都可以使用 + +// > 单次包含宏定义 +#ifndef __SHELL_ALL_H_ +#define __SHELL_ALL_H_ + +// 包含对接的头文件,使用相对路径 +#include "./stm32_HAL_adapt/stm32_HAL_adapt.h" + +#include "shell_cfg_user.h" // 使用本文件目录下的自定义配置文件 + +//> 环形队列用来等待接收和发送的数据,这样就可以在中断中调用shell的读写函数 +#define SHELL_RX_BUFFER_SIZE 512 +#define SHELL_TX_BUFFER_SIZE 512 + +// 连续发送与接收宏定义,当使用阻塞式接收发送时必须关闭指定的宏定义 +#define SHELL_TX_CONTINUOUSLY 1 // 使能连续发送(end中继续检测是否还有数据需要发送) +#define SHELL_RX_CONTINUOUSLY 1 // 使能连续接收(end中继续检测是否还有空间可以接收) + +// > C/C++兼容性宏定义 +#ifdef __cplusplus +extern "C" +{ +#endif + + //+******************************** C scope ***************************************/ + +#include "../../src/shell.h" + +// shell核心头文件 +#include "../../src/shell_cfg.h" +#include "../../src/shell.h" +#include "../../src/shell_ext.h" + +// shell增强组件 +#include "../../extensions/shell_enhance/shell_cmd_group.h" // 命令组 +#include "../../extensions/shell_enhance/shell_passthrough.h" // 透传 +#include "../../extensions/shell_enhance/shell_secure_user.h" // 安全用户 + + // #undef LOG_ENABLE + // #define LOG_ENABLE 0 //>在对应的C文件中使用此定义即可关闭当前文件的日志输出,需要加在文件最前面,直接打开这里的注释是关闭所有文件的日志输出 + +// shell log组件 +#include "../../extensions/log/log.h" // 日志 + + //// shell fs组件 + // #include "../../extensions/fs_support/shell_fs.h" // 文件命令 + + //// shell telnet组件 + // #include "../../extensions/telnet/telnetd.h" // telnet + + void port_tx_trigger(void); // 触发发送,定期调用 + void port_tx_end(short truely_tx_len); // 实际发送完后一定要调用,发送中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 + + void port_rx_trigger(void); // 触发接收,定期调用 + void port_rx_end(short truely_rx_len); // 实际接收完后一定要调用,接收中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 + + // 初始化shell和log + void letter_shell_init(void); + + // shell任务 + void shell_task(); + +#ifdef __cplusplus +} +//+******************************** c++ scope ***************************************/ +// shell C++支持组件 +#include "../../extensions/cpp_support/shell_cpp.h" // C++命令 + +#endif //\ __cplusplus + +#endif //\ __SHELL_ALL_H_ diff --git a/demo/easy_for_keil/shell_cfg_user.h b/demo/easy_for_keil/shell_cfg_user.h new file mode 100644 index 0000000..7c98bc2 --- /dev/null +++ b/demo/easy_for_keil/shell_cfg_user.h @@ -0,0 +1,113 @@ +/** + * @file shell_cfg_user.h + * @author Letter (nevermindzzt@gmail.com) + * @brief shell config + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_CFG_USER_H__ +#define __SHELL_CFG_USER_H__ + +#include + +// clang-format off + +/** + * @brief shell默认用户 + */ +#define SHELL_DEFAULT_USER "letter_shell" + +// /** +// * @brief 是否使用shell伴生对象,开启后需要支持malloc和free接口 +// * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 +// */ +// #define SHELL_USING_COMPANION 0 + +// /** +// * @brief shell内存分配 +// * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 +// */ +// extern void *pvPortMalloc(size_t xSize); +// #define SHELL_MALLOC(size) pvPortMalloc(size) + +// /** +// * @brief shell内存释放 +// * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 +// */ +// extern void vPortFree(void *pv); +// #define SHELL_FREE(obj) vPortFree(obj) + +/** + * @brief 使用锁 + * @note 使用shell锁时,需要对加锁和解锁进行实现 + */ +#define SHELL_USING_LOCK 0 + +#ifndef SHELL_TASK_WHILE +/** + * @brief 是否使用默认shell任务while循环 + * 使能此宏,则`shell_task()`函数会一直循环读取输入,一般使用操作系统建立shell + * 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shell_task()` + */ +#define SHELL_TASK_WHILE 0 +#endif /** SHELL_TASK_WHILE */ + +/** + * @brief 是否显示shell信息 + */ +#define SHELL_SHOW_INFO 1 + +/** + * @brief 支持shell尾行模式 + */ +#define SHELL_SUPPORT_END_LINE 1 + + +/** + * @brief 使用LF作为命令行回车触发 + * 可以和SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_LF 0 + +/** + * @brief 使用CR作为命令行回车触发 + * 可以和SHELL_ENTER_LF同时开启 + */ +#define SHELL_ENTER_CR 0 + +/** + * @brief 使用CRLF作为命令行回车触发 + * 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_CRLF 1 + +#ifndef SHELL_PRINT_BUFFER +/** + * @brief shell格式化输出的缓冲大小 + * 为0时不使用shell格式化输出 + */ +#define SHELL_PRINT_BUFFER 256 +#endif /** SHELL_PRINT_BUFFER */ + +/** + * @brief shell格式化输入的缓冲大小 + * 为0时不使用shell格式化输入 + * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用 + */ +#define SHELL_SCAN_BUFFER 256 + +/** + * @brief 使用函数签名 + * 使能后,可以在声明命令时,指定函数的签名,shell 会根据函数签名进行参数转换, + * 而不是自动判断参数的类型,如果参数和函数签名不匹配,会停止执行命令 + */ +#define SHELL_USING_FUNC_SIGNATURE 1 + +//+******************************** log组件配置 ***************************************/ +//>log组件的配置在log.h中配置 + +#endif diff --git a/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c b/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c new file mode 100644 index 0000000..c800c90 --- /dev/null +++ b/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c @@ -0,0 +1,161 @@ +/** + * @file stm32_HAL_adapt.c + * @author 独霸一方 (2696652257@qq.com) + * @brief //> stm32 HAL库适配letter shell + * @version 1.0 + * @date 2024-08-07 + * + * @copyright Copyright (c) 2024 + * + */ + +#include "stm32_HAL_adapt.h" + +#include "../shell_all.h" + +// 写入是否可以阻塞,默认不可以阻塞,一般判断是否在中断中就可以判断是否可以阻塞 +#ifndef SHELL_WRITE_CAN_BLOCK +#define SHELL_WRITE_CAN_BLOCK() (false) +#endif // !SHELL_WRITE_CAN_BLOCK + +// 如果有操作系统,可以使用操作系统提供的递归互斥锁 + +void shell_lock(struct shell_def *shell) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { + // 操作系统的加锁 + } + else + { + // 处于不能阻塞的地方,一般认为是中断,直接不管 + } +} + +void shell_unlock(struct shell_def *shell) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { + // 操作系统的解锁 + } + else + { + } +} + +void log_lock(struct log_def *log) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { + } + else + { + } +} + +void log_unlock(struct log_def *log) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { + } + else + { + } +} + +// shell使用的硬件初始化,使用cubemx开启串口,然后使能对应的串口中断,DMA发送与接收中断 +void user_hardware_init() +{ + // 由于初始化已经由CUBEMX处理好了,这里什么都不需要做,建议关闭DMA接收半满中断 + // __HAL_DMA_DISABLE_IT(SHELL_UART_ADDR, DMA_IT_HT); +} + +//+******************************** 平台的中断回调 ***************************************/ +//! 如果有自己其他串口的中断回调,请自行按照这个格式添加 + +#if 1 + +#if (PLATFORM_MODE == PLATFORM_MODE_DMA) +void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) // 串口接收中断 +{ + UNUSED(huart); + UNUSED(Size); + + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_rx_end(Size); + } +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 +{ + UNUSED(huart); + + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 + } +} +#elif (PLATFORM_MODE == PLATFORM_MODE_IT) +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_rx_end(1); // 中断接收的时候是单字节接收,因此实际接收到1个字节就会进入此中断 + } +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 +{ + UNUSED(huart); + + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 + } +} +#endif + +#endif + +//+******************************** 导出一些可能常用的命令 ***************************************/ +int Reboot() +{ + HAL_NVIC_SystemReset(); // 单片机重启 + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), Reboot, Reboot, reboot the mcu); + +#if 1 + +#include +int date() +{ + Shell *shell = shellGetCurrent(); + + if (!shell) + return 0; + + int64_t ticks = SHELL_GET_TICK(); + +#if SHELL_USING_LOCK == 1 + shell->lock(shell); +#endif + + char str[120]; + snprintf(str, sizeof(str), "current time: %lld\r\n", ticks); + shellWriteString(shell, str); + + // 换算为天`时`分`秒`毫秒 + snprintf(str, sizeof(str), "current time: %lld天 %02lld时 %02lld分 %02lld秒 %03lld毫秒\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); + shellWriteString(shell, str); + +#if SHELL_USING_LOCK == 1 + shell->unlock(shell); +#endif + + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), date, date, current time); + +#endif \ No newline at end of file diff --git a/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h new file mode 100644 index 0000000..a7cb24c --- /dev/null +++ b/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h @@ -0,0 +1,75 @@ +/** + * @file stm32_HAL_adapt.h + * @author fool_dog (2696652257@qq.com) + * @brief // 裸机的对接方式 + * @version 1.0 + * @date 2024-08-08 + * + * @copyright Copyright (c) 2024 + * + */ + +#include "cmsis_compiler.h" +#include "usart.h" +#include "dma.h" + +// 接收发送方式,不使用阻塞式发送接收,有RTOS可以考虑阻塞发送(可以但没必要),发送和接收的方式是可以组合使用的, +#define PLATFORM_MODE_DMA 0 +#define PLATFORM_MODE_IT 1 + +// 使用DMA发送与接收 +#define PLATFORM_MODE PLATFORM_MODE_DMA + +struct shell_def; // shell的前置声明 +void shell_lock(struct shell_def *shell); +void shell_unlock(struct shell_def *shell); +struct log_def; // log的前置声明 +void log_lock(struct log_def *log); +void log_unlock(struct log_def *log); +// 加锁解锁的对应函数 +#define SHELL_LOCK_FUNC shell_lock +#define SHELL_UNLOCK_FUNC shell_unlock +#define LOG_LOCK_FUNC log_lock +#define LOG_UNLOCK_FUNC log_unlock + +//+********************************* 必须对接的宏 **********************************/ +// 写入是否可以阻塞的判断函数,通常不在中断中就可以阻塞 +#define SHELL_WRITE_CAN_BLOCK() (__get_IPSR() == 0) + +#define WAIT_A_MOMENT() HAL_Delay(1) // 等待一段时间,外设跟不上内核填充的速度 + +// 原子操作保证数据的完整性,支持嵌套更好 +#define SHELL_ATOMIC_ENTER() __disable_irq() +#define SHELL_ATOMIC_EXIT() __enable_irq() + +// 平台初始化 +extern void user_hardware_init(); +#define PLATFORM_INIT() user_hardware_init() + +#define SHELL_UART_ADDR (&huart1) +// clang-format off + +#if (PLATFORM_MODE == PLATFORM_MODE_DMA) + extern HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); + extern HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); + #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_DMA(SHELL_UART_ADDR, (uint8_t *)buffer, len) + #define PLATFORM_RX_WRAP(buffer, len) HAL_UARTEx_ReceiveToIdle_DMA(SHELL_UART_ADDR, (uint8_t *)buffer, len) +#elif (PLATFORM_MODE == PLATFORM_MODE_IT) + extern HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); + extern HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); + #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_IT(SHELL_UART_ADDR, (uint8_t *)buffer, len) + // 中断接收改成单个字节接收 + #define PLATFORM_RX_WRAP(buffer, len) HAL_UART_Receive_IT(SHELL_UART_ADDR, (uint8_t *)buffer, 1) +#endif + +// clang-format on + +#ifndef SHELL_GET_TICK +/** + * @brief 获取系统时间(ms) + * 定义此宏为获取系统Tick,如`HAL_GetTick()` + * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 + */ +extern uint32_t HAL_GetTick(void); +#define SHELL_GET_TICK() HAL_GetTick() +#endif /** SHELL_GET_TICK */ diff --git a/extensions/log/log.h b/extensions/log/log.h index 4c4075e..d576825 100644 --- a/extensions/log/log.h +++ b/extensions/log/log.h @@ -4,9 +4,9 @@ * @brief log * @version 1.0.0 * @date 2020-07-30 - * + * * @copyright (c) 2020 Letter - * + * */ #ifndef __LOG_H__ #define __LOG_H__ @@ -27,7 +27,7 @@ extern "C" { #define LOG_MAX_NUMBER 5 /**< 允许注册的最大log对象数量 */ #define LOG_AUTO_TAG 1 /**< 是否自动添加TAG */ #define LOG_END "\r\n" /**< log信息结尾 */ -#define LOG_TIME_STAMP 0 /**< 设置获取系统时间戳 */ +#define LOG_TIME_STAMP SHELL_GET_TICK() /**< 设置获取系统时间戳 */ #ifndef LOG_TAG #define LOG_TAG __FUNCTION__ /**< 自定添加的TAG */ @@ -90,7 +90,7 @@ extern "C" { /** * @brief 日志级别定义 - * + * */ typedef enum { @@ -106,14 +106,14 @@ typedef enum /** * @brief log对象定义 - * + * */ typedef struct log_def { void (*write)(char *, short); /**< 写buffer */ char active; /**< 是否激活 */ LogLevel level; /**< 日志级别 */ -#if LOG_USING_LOCK == 1 +#if LOG_USING_LOCK == 1 int (*lock)(struct log_def *); /**< log 加锁 */ int (*unlock)(struct log_def *); /**< log 解锁 */ #endif /** LOG_USING_LOCK == 1 */ @@ -124,7 +124,7 @@ typedef struct log_def /** * @brief log打印(自动换行) - * + * * @param fmt 格式 * @param ... 参数 */ @@ -134,7 +134,7 @@ typedef struct log_def /** * @brief 日志格式化输出 - * + * * @param text 消息文本 * @param level 日志级别 * @param fmt 格式 @@ -147,7 +147,7 @@ typedef struct log_def /** * @brief 错误log输出 - * + * * @param fmt 格式 * @param ... 参数 */ @@ -156,7 +156,7 @@ typedef struct log_def /** * @brief 警告log输出 - * + * * @param fmt 格式 * @param ... 参数 */ @@ -165,7 +165,7 @@ typedef struct log_def /** * @brief 信息log输出 - * + * * @param fmt 格式 * @param ... 参数 */ @@ -174,7 +174,7 @@ typedef struct log_def /** * @brief 调试log输出 - * + * * @param fmt 格式 * @param ... 参数 */ @@ -183,7 +183,7 @@ typedef struct log_def /** * @brief 冗余log输出 - * + * * @param fmt 格式 * @param ... 参数 */ @@ -192,7 +192,7 @@ typedef struct log_def /** * @brief 断言 - * + * * @param expr 表达式 * @param action 断言失败操作 */ @@ -204,7 +204,7 @@ typedef struct log_def /** * @brief 16进制输出到所有终端 - * + * * @param base 内存基址 * @param length 长度 */ diff --git a/extensions/shell_enhance/shell_cmd_group.h b/extensions/shell_enhance/shell_cmd_group.h index 5200681..3a02d9e 100644 --- a/extensions/shell_enhance/shell_cmd_group.h +++ b/extensions/shell_enhance/shell_cmd_group.h @@ -9,6 +9,7 @@ * */ #include "shell.h" +#include /** * @brief shell 命令组函数名 From 74b33737f7e5a2d548ae52b1b16f0a614f121ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Fri, 9 Aug 2024 23:37:02 +0800 Subject: [PATCH 02/12] =?UTF-8?q?docs:=20=F0=9F=93=9D=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E7=A7=BB=E6=A4=8D=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/easy_transplant/call_demo/user_main.c | 41 +++ .../image/readme/1723214231937.png | Bin 0 -> 139230 bytes .../image/readme/1723216984202.png | Bin 0 -> 126858 bytes .../image/readme/1723217000891.png | Bin 0 -> 125778 bytes .../image/readme/1723217009356.png | Bin 0 -> 64150 bytes demo/easy_transplant/readme.md | 37 ++ demo/easy_transplant/ringbuffer/ringbuffer.c | 227 ++++++++++++ demo/easy_transplant/ringbuffer/ringbuffer.h | 64 ++++ demo/easy_transplant/shell_all.c | 334 ++++++++++++++++++ demo/easy_transplant/shell_all.h | 86 +++++ demo/easy_transplant/shell_cfg_user.h | 113 ++++++ .../stm32_HAL_adapt/stm32_HAL_adapt.c | 182 ++++++++++ .../stm32_HAL_adapt/stm32_HAL_adapt.h | 65 ++++ demo/quick_for_keil/shell_all.c | 0 demo/quick_for_keil/shell_all.h | 0 demo/quick_for_keil/shell_cfg_user.h | 0 16 files changed, 1149 insertions(+) create mode 100644 demo/easy_transplant/call_demo/user_main.c create mode 100644 demo/easy_transplant/image/readme/1723214231937.png create mode 100644 demo/easy_transplant/image/readme/1723216984202.png create mode 100644 demo/easy_transplant/image/readme/1723217000891.png create mode 100644 demo/easy_transplant/image/readme/1723217009356.png create mode 100644 demo/easy_transplant/readme.md create mode 100644 demo/easy_transplant/ringbuffer/ringbuffer.c create mode 100644 demo/easy_transplant/ringbuffer/ringbuffer.h create mode 100644 demo/easy_transplant/shell_all.c create mode 100644 demo/easy_transplant/shell_all.h create mode 100644 demo/easy_transplant/shell_cfg_user.h create mode 100644 demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c create mode 100644 demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h create mode 100644 demo/quick_for_keil/shell_all.c create mode 100644 demo/quick_for_keil/shell_all.h create mode 100644 demo/quick_for_keil/shell_cfg_user.h diff --git a/demo/easy_transplant/call_demo/user_main.c b/demo/easy_transplant/call_demo/user_main.c new file mode 100644 index 0000000..16a998d --- /dev/null +++ b/demo/easy_transplant/call_demo/user_main.c @@ -0,0 +1,41 @@ +/** + * @file user_main.c + * @author fool_dog (2696652257@qq.com) + * @brief //> 此文件仅用于展示如何调用shell的逻辑,不要添加此文件进行编译 + * @version 1.0 + * @date 2024-08-09 + * + * @copyright Copyright (c) 2024 + * + */ + +#include "../shell_all.h" + +int user_main(void) +{ + letter_shell_init(); // 初始化shell + + for (;;) + { + letter_shell_task(); // 处理shell任务 + + // 建议隔一定时间调用这两个函数,可以在中断中调用,也可以在主循环中调用 + { + port_tx_trigger(); + port_rx_trigger(); + } + } +} + +//+********************************* 通常下面是接收和发送中断 **********************************/ +void rx_end_callback() +{ + // 在接收函数回调中或者实际接收到数据后调用 + port_rx_end(-1); // 如果知道实际接收了多少个字节就传入实际的字节数,不然传入负数让其自动根据上次调用是传入的大小进行处理 +} + +void tx_end_callback() +{ + // 在发送函数回调中,或者实际发送数据后调用 + port_tx_end(-1); // 如果知道实际发送了多少个字节就传入实际的字节数,不然传入负数让其自动根据上次调用是传入的大小进行处理 +} \ No newline at end of file diff --git a/demo/easy_transplant/image/readme/1723214231937.png b/demo/easy_transplant/image/readme/1723214231937.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3f31c1a9026eabf49b1e14f0b0adfe2f5cc801 GIT binary patch literal 139230 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ɺS?;xZFy*tWWKFmZgZWiW8PP^HN+wdE}Q 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 N+SAp~Wt~$(697h)pH2V( literal 0 HcmV?d00001 diff --git a/demo/easy_transplant/image/readme/1723216984202.png b/demo/easy_transplant/image/readme/1723216984202.png new file mode 100644 index 0000000000000000000000000000000000000000..36db16fc2849e84cebd463464d03167f2e0d9953 GIT binary patch literal 126858 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 z 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 z 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≦vcQJ%1vLl%~k7m{P*z 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 Mg6iG8+YkNz7j|e(NB{r; literal 0 HcmV?d00001 diff --git a/demo/easy_transplant/image/readme/1723217000891.png b/demo/easy_transplant/image/readme/1723217000891.png new file mode 100644 index 0000000000000000000000000000000000000000..076cd6d84b312b2d2db2d1aa1933048c27ffa465 GIT binary patch literal 125778 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%0DaSH2~#}u*V_TcZS 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�`V$e5Z^j87vlZLJ6^uO* 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 z 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 Dd$SiZ literal 0 HcmV?d00001 diff --git a/demo/easy_transplant/image/readme/1723217009356.png b/demo/easy_transplant/image/readme/1723217009356.png new file mode 100644 index 0000000000000000000000000000000000000000..1533f6a45e839834a837e822d970eaf65ce91886 GIT binary patch literal 64150 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 ij@|A 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 Zk3t*MrmVrfo<#b}6`?9O@~#;@`442x7d8L@ literal 0 HcmV?d00001 diff --git a/demo/easy_transplant/readme.md b/demo/easy_transplant/readme.md new file mode 100644 index 0000000..0ce8a8c --- /dev/null +++ b/demo/easy_transplant/readme.md @@ -0,0 +1,37 @@ +# easy_transplant demo + +此目录文件为通用 letter-shell 移植的实例,目前仅提供了STM32 HAL库的适配文件 + +## 使用(以STM32 HAL库串口1 DMA适配为例)--AC6编译 + +在cubemx中开启串口,并且开启串口中断,添加串口的DMA发送和接收,DMA模式选择常规模式------其他时钟,调试接口之类的配置请自行配置 + +![1723214231937](image/readme/1723214231937.png) + +生成工程后打开 + +此处以keil为例 + +1. 将keil编译器切换为AC6,AC5太老了编译又慢,一定要选用AC5导致的编译报错请自行解决 +2. 将此文件夹下shell_all.c和stm32_HAL_adapt文件夹下stm32_HAL_adapt.c添加编译 +3. 将shell根目录下src文件夹和extensions/shell_enhance和shell_all.h所在文件夹添加头文件包含 + +![1723216984202](image/readme/1723216984202.png) + +在main.c中包含shell_all.h头文件,调用一次 `letter_shell_init`,轮询调用 `letter_shell_task`,轮询或定期调用 `port_tx_trigger`和 `port_rx_trigger` + +![1723217000891](image/readme/1723217000891.png) + +OK,编译,烧录完事 + +![1723217009356](image/readme/1723217009356.png) + +# 其他移植可以参考stm32_HAL_adapt文件夹下实现 + +按照上诉方法进行移植也请看一下该文件夹下的实现,该实现下重写了STM32 HAL库的两个串口中断回调 + +# 其他说明 + +此例程移植同样力求不更改letter shell原仓库文件分布情况 + +shell对接最重要的在于read与write,通常是直接对接到外设上(例如串口),但是外设的速度是远低于内核的运行速度的,于是此例的移植对shell的输入输出都采用ringbuffer缓冲,这样方便解决在中断中调用shell读写(比如log组件)导致中断的的长时间运行,以及stm32_HAL_adapt中实现了支持FreeRTOS的情况下加锁之类的操作 diff --git a/demo/easy_transplant/ringbuffer/ringbuffer.c b/demo/easy_transplant/ringbuffer/ringbuffer.c new file mode 100644 index 0000000..02ba04f --- /dev/null +++ b/demo/easy_transplant/ringbuffer/ringbuffer.c @@ -0,0 +1,227 @@ +#include "ringbuffer.h" +#include + +#undef USER_ASSERT +#define USER_ASSERT(exp) (void)0 // 开启此宏关闭此文件用户自定义断言 + +// clang-format off +#ifndef USER_ASSERT + #include + #define USER_ASSERT(exp) \ + if (!(exp)) \ + { \ + printf("\"" #exp "\" assert failed at file: %s, line: %d", __FILE__, __LINE__); \ + for (;;) \ + ; \ + } +#endif // ! USER_ASSERT +// clang-format on + +void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + rb->buffer = buffer; + rb->buffer_size = size; + rb->busy = false; + + ringbuffer_reset(rb); +} + +void ringbuffer_reset(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + rb->head = 0; + rb->tail = 0; + rb->data_count = 0; +} + +uint16_t ringbuffer_get_free(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->buffer_size - rb->data_count; +} + +uint16_t ringbuffer_get_used(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->data_count; +} + +uint16_t ringbuffer_get_size(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->buffer_size; +} + +uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->last_series_count; +} + +uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + uint16_t free_size = ringbuffer_get_free(rb); + + if (size > free_size) + { + size = free_size; // 多余的数据不写入(丢掉) + } + + // 判断超过尾部没有 + if (rb->tail + size > rb->buffer_size) + { + uint16_t first_size = rb->buffer_size - rb->tail; + memcpy((uint8_t *)(rb->buffer) + rb->tail, data, first_size); + memcpy(rb->buffer, data + first_size, size - first_size); + } + else + { + memcpy((uint8_t *)(rb->buffer) + rb->tail, data, size); + } + + // 限制尾部位置 + if (rb->tail + size >= rb->buffer_size) + { + rb->tail = size - (rb->buffer_size - rb->tail); + } + else + { + rb->tail += size; + } + + rb->data_count += size; + + return size; +} + +uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + uint16_t used_size = ringbuffer_get_used(rb); + + if (size > used_size) + { + size = used_size; // 读取的数据超过了已有数据量 + } + + // 判断超过尾部没有 + if (rb->head + size > rb->buffer_size) + { + uint16_t first_size = rb->buffer_size - rb->head; + memcpy(data, (uint8_t *)(rb->buffer) + rb->head, first_size); + memcpy(data + first_size, rb->buffer, size - first_size); + } + else + { + memcpy(data, (uint8_t *)(rb->buffer) + rb->head, size); + } + + // 限制头部位置 + if (rb->head + size >= rb->buffer_size) + { + rb->head = size - (rb->buffer_size - rb->head); + } + else + { + rb->head += size; + } + + rb->data_count -= size; + + return size; +} + +uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size) +{ + USER_ASSERT(rb != NULL); + USER_ASSERT(size != NULL); + uint16_t max_size = ringbuffer_get_free(rb); + + if (max_size + rb->tail > rb->buffer_size) + { + max_size = rb->buffer_size - rb->tail; + } + + *size = max_size; + rb->last_series_count = max_size; + + return (uint8_t *)(rb->buffer) + rb->tail; +} + +uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size) +{ + USER_ASSERT(rb != NULL); + USER_ASSERT(size != NULL); + uint16_t max_size = ringbuffer_get_used(rb); + + if (max_size + rb->head > rb->buffer_size) + { + max_size = rb->buffer_size - rb->head; + } + + *size = max_size; + rb->last_series_count = max_size; + + return (uint8_t *)(rb->buffer) + rb->head; +} + +uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + // 限制尾部位置 + if (rb->tail + size >= rb->buffer_size) + { + rb->tail = size - (rb->buffer_size - rb->tail); + } + else + { + rb->tail += size; + } + + rb->data_count += size; + + return size; +} + +uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size) +{ + USER_ASSERT(rb != NULL); + + // 限制头部位置 + if (rb->head + size >= rb->buffer_size) + { + rb->head = size - (rb->buffer_size - rb->head); + } + else + { + rb->head += size; + } + + rb->data_count -= size; + + return size; +} + +void ringbuffer_mark_busy(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + rb->busy = true; +} + +void ringbuffer_mark_idle(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + rb->busy = false; +} + +bool ringbuffer_is_busy(ringbuffer_t *rb) +{ + USER_ASSERT(rb != NULL); + return rb->busy; +} diff --git a/demo/easy_transplant/ringbuffer/ringbuffer.h b/demo/easy_transplant/ringbuffer/ringbuffer.h new file mode 100644 index 0000000..c79d2d2 --- /dev/null +++ b/demo/easy_transplant/ringbuffer/ringbuffer.h @@ -0,0 +1,64 @@ +/** + * @file ringbuffer.h + * @author 独霸一方 (2696652257@qq.com) + * @brief //> 部分参考cherryRB实现的环形缓冲区,完整实现参考:https://github.com/cherry-embedded/CherryRB + * 源码直接加入shell_all.c中进行编译,无需再次添加此目录下.c文件进行编译 + * @version 1.0 + * @date 2024-08-05 + * + * @copyright Copyright (c) 2024 + * + */ + +// > 单次包含宏定义 +#ifndef __RINGBUFFER_H_ +#define __RINGBUFFER_H_ + +#include +#include +#include + +// > C/C++兼容性宏定义 +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct __ringbuffer_t ringbuffer_t; + struct __ringbuffer_t + { + bool busy; // 用于指示'慢速'外设是否正在操作缓冲区,比如DMA传输 + uint16_t head; + uint16_t tail; + uint16_t data_count; // 当前队列中的数据量 + uint16_t last_series_count; // 调用连续读或写时候实际设置的值 + uint16_t buffer_size; // 缓冲区大小 + uint8_t *buffer; + }; + + void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size); + void ringbuffer_reset(ringbuffer_t *rb); + + uint16_t ringbuffer_get_free(ringbuffer_t *rb); // 获取剩余空间 + uint16_t ringbuffer_get_used(ringbuffer_t *rb); // 获取已使用空间 + uint16_t ringbuffer_get_size(ringbuffer_t *rb); // 获取缓冲区大小 + uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb); // 获取上次调用线性读取或者写入时候的设置的大小 + + uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size); // 返回实际写入的数据量 + uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size); // 返回实际读取的数据量 + + // for linear read/write operation(such as DMA) + extern uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size); // 返回写入的地址并设置实际能写入的数据量 + extern uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size); // 返回读取的地址并设置实际能读取的数据量 + extern uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size); // 返回实际写入的数据量 + extern uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size); // 返回实际读取的数据量 + + void ringbuffer_mark_busy(ringbuffer_t *rb); + void ringbuffer_mark_idle(ringbuffer_t *rb); + bool ringbuffer_is_busy(ringbuffer_t *rb); + +#ifdef __cplusplus +} +#endif //\ __cplusplus + +#endif //\ __RINGBUFFER_H_ diff --git a/demo/easy_transplant/shell_all.c b/demo/easy_transplant/shell_all.c new file mode 100644 index 0000000..0fc00aa --- /dev/null +++ b/demo/easy_transplant/shell_all.c @@ -0,0 +1,334 @@ +#include "shell_all.h" + +#include +#include + +// 将所有的源码文件加入到这一个文件中,方便Keil工程的添加 + +#if 1 + +#include "./ringbuffer/ringbuffer.c" // 环形队列 + +// shell核心实现包含 +#include "../../src/shell.c" +#include "../../src/shell_ext.c" +#include "../../src/shell_cmd_list.c" +#include "../../src/shell_companion.c" + +// shell拓展组件 + +// shell增强组件 +#include "../../extensions/shell_enhance/shell_cmd_group.c" // 命令组 +#include "../../extensions/shell_enhance/shell_passthrough.c" // 透传 +#include "../../extensions/shell_enhance/shell_secure_user.c" // 安全用户 + +// shell log组件 +#include "../../extensions/log/log.c" // 日志 + +//// shell fs组件 +// #include "../../extensions/fs_support/shell_fs.c" // 文件命令 + +//// shell telnet组件 +// #include "../../extensions/telnet/telnetd.c" // telnet,需要命令组拓展(注意头文件路径包含) + +#endif + +//// shell game组件需要单独添加.c到工程中,不然会有一些同名函数的问题 +// #include "../../extensions/game/game.c" // 游戏,需要命令组拓展(注意头文件路径包含) +// #include "../../extensions/game/2048/2048.c" // 2048 +// #include "../../extensions/game/pushbox/pushbox.c" // 贪吃蛇 + +//+********************************* 环形队列中转 **********************************/ +#if SHELL_SHOW_INFO == 1 +#if SHELL_TX_BUFFER_SIZE < 400 +#warning "建议将环形队列的大小设置为大于400,否则打印初始化信息的时候可能会出现部分打印数据丢失" +#warning "shell tx buffer size is too small, please increase the buffer size" +#endif +#endif + +// 定义shell和log对象 +static Shell user_shell; +static Log user_log; + +// 发送和接收的中转环形缓冲队列 +static ringbuffer_t rb_rx; +static ringbuffer_t rb_tx; + +// 写入是否可以阻塞,默认不可以阻塞,一般判断是否在中断中就可以判断是否可以阻塞 +#ifndef SHELL_WRITE_CAN_BLOCK +#define SHELL_WRITE_CAN_BLOCK() (false) +#endif // !SHELL_WRITE_CAN_BLOCK + +//+********************************* shell读写对接 **********************************/ + +short write_to_ringbuffer(char *data, unsigned short len) +{ + short total_written = 0; + short ret = 0; + + while (len > 0) + { + SHELL_ATOMIC_ENTER(); + + ret = ringbuffer_write(&rb_tx, (uint8_t *)data, len); + + SHELL_ATOMIC_EXIT(); + + if (ret >= len) // 只可能小于等于 + { + return total_written; // 全部数据写入成功 + } + else + { + if (!SHELL_WRITE_CAN_BLOCK()) + { + total_written += ret; + WRITE_OVER_FLOW_HOOK(); + break; // 如果在中断中,直接退出,未写入的数据直接丢弃,避免长时间占用中断 + } + + total_written += ret; + data += ret; + len -= ret; + port_tx_trigger(); // 主动尝试触发发送 + + WAIT_A_MOMENT(); // 等待一段时间,避免频繁触发发送 + } + } + + return total_written; +} + +short read_from_ringbuffer(char *data, unsigned short len) +{ + short ret = 0; + SHELL_ATOMIC_ENTER(); + + ret = ringbuffer_read(&rb_rx, (uint8_t *)data, len); + + SHELL_ATOMIC_EXIT(); + return ret; +} + +//+******************************** log组件对接 ***************************************/ + +void UserLogWrite(char *buffer, short len) +{ +#if SHELL_SUPPORT_END_LINE == 1 + USER_ASSERT(user_log.shell != NULL); + shellWriteEndLine(user_log.shell, buffer, len); +#else + USER_ASSERT(user_log.shell != NULL); + USER_ASSERT(user_log.shell->write != NULL); + user_log.shell->write(buffer, len); +#endif +} + +//+******************************** 对外调用接口 ***************************************/ +void port_tx_trigger(void) +{ + if (ringbuffer_is_busy(&rb_tx) || ringbuffer_get_used(&rb_tx) <= 0) + { + return; // 没有数据或者外设还在响应上一次的发送 + } + + // 这两个栈变量可能会在极端情况下破坏原子操作性,改成static然后提到函数开头效果可能会更好 + uint16_t size; + uint8_t *p; + + SHELL_ATOMIC_ENTER(); + + // 获取ringbuffer当前的读指针和最大线性可读数据大小 + ringbuffer_mark_busy(&rb_tx); // 标记为忙,调用port_tx_end函数后再标记为闲 + p = ringbuffer_linear_read_setup(&rb_tx, &size); + + SHELL_ATOMIC_EXIT(); + + // 发送数据,调用平台相关的发送函数 + PLATFORM_TX_WRAP(p, size); +} + +void port_rx_trigger(void) +{ + + if (ringbuffer_is_busy(&rb_rx) || ringbuffer_get_free(&rb_rx) <= 0) // 性能优化,对于接收,外设忙的情况更多先判断是否在忙 + { + return; // 没有空间接收或者正在接收数据 + } + + // 这两个栈变量可能会在极端情况下破坏原子操作性,改成static然后提到函数开头效果可能会更好 + uint16_t size; + uint8_t *p; + + SHELL_ATOMIC_ENTER(); + ringbuffer_mark_busy(&rb_rx); // 标记为忙,调用port_rx_end函数后再标记为闲 + // 获取ringbuffer当前的写指针和最大线性可写数据大小 + p = ringbuffer_linear_write_setup(&rb_rx, &size); + + SHELL_ATOMIC_EXIT(); + + // 接收数据,调用平台相关的接收函数 + PLATFORM_RX_WRAP(p, size); +} + +// 通常用于中断中调用 +void port_tx_end(short truely_tx_len) +{ + SHELL_ATOMIC_ENTER(); + if (truely_tx_len < 0) + { + truely_tx_len = ringbuffer_get_last_series_size(&rb_tx); + } + + ringbuffer_linear_read_done(&rb_tx, truely_tx_len); + ringbuffer_mark_idle(&rb_tx); + + SHELL_ATOMIC_EXIT(); + +#if SHELL_TX_CONTINUOUSLY + port_tx_trigger(); // 继续发送 +#endif +} + +void port_rx_end(short truely_rx_len) +{ + SHELL_ATOMIC_ENTER(); + if (truely_rx_len < 0) + { + truely_rx_len = ringbuffer_get_last_series_size(&rb_rx); + } + + ringbuffer_linear_write_done(&rb_rx, truely_rx_len); + ringbuffer_mark_idle(&rb_rx); + SHELL_ATOMIC_EXIT(); + +#if SHELL_RX_CONTINUOUSLY + //! 继续接收,如果这里由于队列满了导致没有触发接收,那么直到再次触发接收之前,都不会再接收数据了 + port_rx_trigger(); +#endif +} + +//+******************************** shell和log组件初始化,shell任务 ***************************************/ +// 锁函数需要在对应的适配文件中实现 +// shell 锁实现函数 +extern void shell_lock(struct shell_def *shell); +extern void shell_unlock(struct shell_def *shell); + +// log锁实现函数 +extern void log_lock(struct log_def *log); +extern void log_unlock(struct log_def *log); + +extern void user_init_before_shell(); + +void letter_shell_init(void) +{ + user_init_before_shell(); + + // 初始化输入输出环形队列 + static char rb_rx_buffer[SHELL_RX_BUFFER_SIZE]; + static char rb_tx_buffer[SHELL_TX_BUFFER_SIZE]; + ringbuffer_init(&rb_rx, (uint8_t *)rb_rx_buffer, sizeof(rb_rx_buffer)); + ringbuffer_init(&rb_tx, (uint8_t *)rb_tx_buffer, sizeof(rb_tx_buffer)); + + // 用于存放命令之类的buffer + static char shell_buffer[512]; + + user_shell.write = write_to_ringbuffer; + user_shell.read = read_from_ringbuffer; +#if SHELL_USING_LOCK == 1 + +#if !defined(SHELL_LOCK_FUNC) || !defined(SHELL_UNLOCK_FUNC) +#error "请定义shell的加锁与解锁函数或者不使用log锁(设置SHELL_USING_LOCK为0)" +#error "please define SHELL_LOCK_FUNC and SHELL_UNLOCK_FUNC" +#endif + user_shell.lock = shell_lock; + user_shell.unlock = shell_unlock; +#endif + shellInit(&user_shell, shell_buffer, sizeof(shell_buffer)); // 初始化shell + + user_log.active = 1; // 创建log对象,默认输出所有等级的log + user_log.level = LOG_ALL; + user_log.write = UserLogWrite, +#if LOG_USING_LOCK == 1 + +#if !defined(LOG_LOCK_FUNC) || !defined(LOG_UNLOCK_FUNC) +#error "请定义log的加锁与解锁函数或者不使用log锁(设置LOG_USING_LOCK为0)" +#error "please define LOG_LOCK_FUNC and LOG_UNLOCK_FUNC" +#endif + + user_log.lock = log_lock; + user_log.unlock = log_unlock; +#endif + + logRegister(&user_log, &user_shell); // 注册log +} + +void letter_shell_task() +{ +#if SHELL_TASK_WHILE == 1 + for (;;) + { +#endif + //> 请自行定期调用两个trigger函数 + // port_tx_trigger(); + // port_rx_trigger(); + + // 读取数据进行处理,这里可以多读几个字节,提高处理效率 + static char data; + // while (user_shell.read(&data, 1)) + if (user_shell.read(&data, 1)) + { + shellHandler(&user_shell, data); + } +#if SHELL_TASK_WHILE == 1 + } +#endif +} + +//+********************************* 导出一些可能用到的命令或快捷键 **********************************/ +static void logChangeLevel() +{ + Log *log = &user_log; + SHELL_ASSERT(log, return); + log->level = (LogLevel)(log->level >= LOG_ALL ? LOG_NONE : (log->level + 1)); + + char logLevel[40] = {0}; + switch (log->level) + { + case LOG_NONE: + sprintf(logLevel, "set log level : LOG_NONE\t(%d)", log->level); + break; + + case LOG_ERROR: + sprintf(logLevel, "set log level : LOG_ERROR\t(%d)", log->level); + break; + + case LOG_WRANING: + sprintf(logLevel, "set log level : LOG_WRANING\t(%d)", log->level); + break; + + case LOG_INFO: + sprintf(logLevel, "set log level : LOG_INFO\t(%d)", log->level); + break; + + case LOG_DEBUG: + sprintf(logLevel, "set log level : LOG_DEBUG\t(%d)", log->level); + break; + + case LOG_VERBOSE: + sprintf(logLevel, "set log level : LOG_VERBOSE\t(%d)", log->level); + break; + + case LOG_ALL: + sprintf(logLevel, "set log level : LOG_ALL\t\t(%d)", log->level); + break; + + default: + break; + } + + logPrintln("%s", logLevel); +} +//> 0x04000000对应的应该是鼠标中键,但是在Xshell中,按下鼠标中间会以字符串的形式发送04000000,导致无法触发,现在修改为 ~ 的按键值 +// SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x04000000, logChangeLevel, switch log level); +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x60000000, logChangeLevel, '~' switch log level); \ No newline at end of file diff --git a/demo/easy_transplant/shell_all.h b/demo/easy_transplant/shell_all.h new file mode 100644 index 0000000..08fe791 --- /dev/null +++ b/demo/easy_transplant/shell_all.h @@ -0,0 +1,86 @@ +/** + * @file shell_all.h + * @author 独霸一方 (2696652257@qq.com) + * @brief //> 这个文件将包含letter shell的所有头文件实现(相对路径),方便在Keil工程中使用 + * @version 1.0 + * @date 2024-08-05 + * + * @copyright Copyright (c) 2024 + * + */ + +// 此文件使用相对路径,保证在任何地方都可以使用 + +// > 单次包含宏定义 +#ifndef __SHELL_ALL_H_ +#define __SHELL_ALL_H_ + +//> 平台适配的头文件必须放在最前面,确保宏定义的预处理定义正确 +#include "./stm32_HAL_adapt/stm32_HAL_adapt.h" + +#include "shell_cfg_user.h" // 使用本文件目录下的自定义配置文件 + +//> 环形队列用来等待接收和发送的数据,这样就可以在中断中调用shell的读写函数 +#define SHELL_RX_BUFFER_SIZE 512 +#define SHELL_TX_BUFFER_SIZE 512 + +// 连续发送与接收宏定义,当使用阻塞式接收发送时必须关闭指定的宏定义 +#define SHELL_TX_CONTINUOUSLY 1 // 使能连续发送(end中继续检测是否还有数据需要发送) +#define SHELL_RX_CONTINUOUSLY 1 // 使能连续接收(end中继续检测是否还有空间可以接收) + +// shell 写入溢出的时候可以调用钩子函数进行一些处理 +#define WRITE_OVER_FLOW_HOOK() (void)0 + +// > C/C++兼容性宏定义 +#ifdef __cplusplus +extern "C" +{ +#endif + + //+******************************** C scope ***************************************/ + +#include "../../src/shell.h" + +// shell核心头文件 +#include "../../src/shell_cfg.h" +#include "../../src/shell.h" +#include "../../src/shell_ext.h" + +// shell增强组件 +#include "../../extensions/shell_enhance/shell_cmd_group.h" // 命令组 +#include "../../extensions/shell_enhance/shell_passthrough.h" // 透传 +#include "../../extensions/shell_enhance/shell_secure_user.h" // 安全用户 + + // #undef LOG_ENABLE + // #define LOG_ENABLE 0 //>在对应的C文件中使用此定义即可关闭当前文件的日志输出,需要加在文件最前面,直接打开这里的注释是关闭所有文件的日志输出 + +// shell log组件 +#include "../../extensions/log/log.h" // 日志 + + //// shell fs组件 + // #include "../../extensions/fs_support/shell_fs.h" // 文件命令 + + //// shell telnet组件 + // #include "../../extensions/telnet/telnetd.h" // telnet + + void port_tx_trigger(void); // 触发发送,定期调用 + void port_tx_end(short truely_tx_len); // 实际发送完后一定要调用,发送中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 + + void port_rx_trigger(void); // 触发接收,定期调用 + void port_rx_end(short truely_rx_len); // 实际接收完后一定要调用,接收中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 + + // 初始化shell和log + void letter_shell_init(void); + + // shell任务 + void letter_shell_task(); + +#ifdef __cplusplus +} +//+******************************** c++ scope ***************************************/ +// shell C++支持组件 +#include "../../extensions/cpp_support/shell_cpp.h" // C++命令 + +#endif //\ __cplusplus + +#endif //\ __SHELL_ALL_H_ diff --git a/demo/easy_transplant/shell_cfg_user.h b/demo/easy_transplant/shell_cfg_user.h new file mode 100644 index 0000000..b894014 --- /dev/null +++ b/demo/easy_transplant/shell_cfg_user.h @@ -0,0 +1,113 @@ +/** + * @file shell_cfg_user.h + * @author Letter (nevermindzzt@gmail.com) + * @brief shell config + * @version 3.0.0 + * @date 2019-12-31 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_CFG_USER_H__ +#define __SHELL_CFG_USER_H__ + +#include + +// clang-format off + +/** + * @brief shell默认用户 + */ +#define SHELL_DEFAULT_USER "letter_shell" + +// /** +// * @brief 是否使用shell伴生对象,开启后需要支持malloc和free接口 +// * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 +// */ +// #define SHELL_USING_COMPANION 0 + +// /** +// * @brief shell内存分配 +// * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 +// */ +// extern void *pvPortMalloc(size_t xSize); +// #define SHELL_MALLOC(size) pvPortMalloc(size) + +// /** +// * @brief shell内存释放 +// * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 +// */ +// extern void vPortFree(void *pv); +// #define SHELL_FREE(obj) vPortFree(obj) + +/** + * @brief 使用锁 + * @note 使用shell锁时,需要对加锁和解锁进行实现 + */ +#define SHELL_USING_LOCK 0 + +#ifndef SHELL_TASK_WHILE +/** + * @brief 是否使用默认shell任务while循环 + * 使能此宏,则`shell_task()`函数会一直循环读取输入,一般使用操作系统建立shell + * 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shell_task()` + */ +#define SHELL_TASK_WHILE 0 +#endif /** SHELL_TASK_WHILE */ + +/** + * @brief 是否显示shell信息 + */ +#define SHELL_SHOW_INFO 1 + +/** + * @brief 支持shell尾行模式 + */ +#define SHELL_SUPPORT_END_LINE 1 + + +/** + * @brief 使用LF作为命令行回车触发 + * 可以和SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_LF 0 + +/** + * @brief 使用CR作为命令行回车触发 + * 可以和SHELL_ENTER_LF同时开启 + */ +#define SHELL_ENTER_CR 0 + +/** + * @brief 使用CRLF作为命令行回车触发 + * 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启 + */ +#define SHELL_ENTER_CRLF 1 + +#ifndef SHELL_PRINT_BUFFER +/** + * @brief shell格式化输出的缓冲大小 + * 为0时不使用shell格式化输出 + */ +#define SHELL_PRINT_BUFFER 256 +#endif /** SHELL_PRINT_BUFFER */ + +/** + * @brief shell格式化输入的缓冲大小 + * 为0时不使用shell格式化输入 + * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用 + */ +#define SHELL_SCAN_BUFFER 256 + +/** + * @brief 使用函数签名 + * 使能后,可以在声明命令时,指定函数的签名,shell 会根据函数签名进行参数转换, + * 而不是自动判断参数的类型,如果参数和函数签名不匹配,会停止执行命令 + */ +#define SHELL_USING_FUNC_SIGNATURE 0 + +//+******************************** log组件配置 ***************************************/ +//>log组件的配置在log.h中配置 + +#endif diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c new file mode 100644 index 0000000..314184f --- /dev/null +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c @@ -0,0 +1,182 @@ +/** + * @file stm32_HAL_adapt.c + * @author 独霸一方 (2696652257@qq.com) + * @brief //> stm32 HAL库适配letter shell + * @version 1.0 + * @date 2024-08-07 + * + * @copyright Copyright (c) 2024 + * + */ + +#include "stm32_HAL_adapt.h" + +#include "../shell_all.h" + +#if (RTOS_MODE == RTOS_FREERTOS) +#include "FreeRTOS.h" +#include "semphr.h" +static SemaphoreHandle_t _shell_mutex; // 互斥锁,防止输出混乱 +static SemaphoreHandle_t _log_mutex; // 互斥锁,防止输出混乱 +#endif + +// 写入是否可以阻塞,默认不可以阻塞,一般判断是否在中断中来决定是否可以阻塞 +#ifndef SHELL_WRITE_CAN_BLOCK +#define SHELL_WRITE_CAN_BLOCK() (false) +#endif // !SHELL_WRITE_CAN_BLOCK + +// 如果有操作系统,可以使用操作系统提供的递归互斥锁 +void shell_lock(struct shell_def *shell) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { // 操作系统的加锁 +#if (RTOS_MODE == RTOS_FREERTOS) + xSemaphoreTakeRecursive(_shell_mutex, portMAX_DELAY); +#endif + } + else + { + // 处于不能阻塞的地方,一般认为是中断,直接不管 + } +} + +void shell_unlock(struct shell_def *shell) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { // 操作系统的解锁 +#if (RTOS_MODE == RTOS_FREERTOS) + xSemaphoreGiveRecursive(_shell_mutex); +#endif + } + else + { + } +} + +void log_lock(struct log_def *log) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { // 操作系统的加锁 +#if (RTOS_MODE == RTOS_FREERTOS) + xSemaphoreTakeRecursive(_log_mutex, portMAX_DELAY); +#endif + } + else + { + } +} + +void log_unlock(struct log_def *log) +{ + if (SHELL_WRITE_CAN_BLOCK()) + { // 操作系统的解锁 +#if (RTOS_MODE == RTOS_FREERTOS) + xSemaphoreGiveRecursive(_log_mutex); +#endif + } + else + { + } +} + +// shell使用的硬件初始化,使用cubemx开启串口,然后使能对应的串口中断,DMA发送与接收中断 +void user_init_before_shell() +{ + // 由于初始化已经由CUBEMX处理好了,这里什么都不需要做,建议关闭DMA接收半满中断 + // __HAL_DMA_DISABLE_IT(SHELL_UART_ADDR, DMA_IT_HT); + +#if (RTOS_MODE == RTOS_FREERTOS) + _shell_mutex = xSemaphoreCreateMutex(); + _log_mutex = xSemaphoreCreateMutex(); +#endif +} + +//+******************************** 平台的中断回调 ***************************************/ +//! 如果有自己其他串口的中断回调,请自行按照这个格式添加 + +#if 1 + +#if (PLATFORM_MODE == PLATFORM_MODE_DMA) +void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) // 串口接收中断 +{ + UNUSED(huart); + UNUSED(Size); + + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_rx_end(Size); + } +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 +{ + UNUSED(huart); + + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 + } +} +#elif (PLATFORM_MODE == PLATFORM_MODE_IT) +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_rx_end(1); // 中断接收的时候是单字节接收,因此实际接收到1个字节就会进入此中断 + } +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 +{ + UNUSED(huart); + + if (huart->Instance == SHELL_UART_ADDR->Instance) + { + port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 + } +} +#endif + +#endif + +//+******************************** 导出一些可能常用的命令 ***************************************/ +int Reboot() +{ + HAL_NVIC_SystemReset(); // 单片机重启 + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), Reboot, Reboot, reboot the mcu); + +#if 1 + +#include +int date() +{ + Shell *shell = shellGetCurrent(); + + if (!shell) + return 0; + + int64_t ticks = SHELL_GET_TICK(); + +#if SHELL_USING_LOCK == 1 + shell->lock(shell); +#endif + + char str[100]; + snprintf(str, sizeof(str), "current time: %lld\r\n", ticks); + shellWriteString(shell, str); + + // 换算为天`时`分`秒`毫秒 + snprintf(str, sizeof(str), "current time: %lld天 %02lld时 %02lld分 %02lld秒 %03lld毫秒\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); + shellWriteString(shell, str); + +#if SHELL_USING_LOCK == 1 + shell->unlock(shell); +#endif + + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), date, date, current time); + +#endif \ No newline at end of file diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h new file mode 100644 index 0000000..8c16be6 --- /dev/null +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h @@ -0,0 +1,65 @@ +/** + * @file stm32_HAL_adapt.h + * @author fool_dog (2696652257@qq.com) + * @brief // 裸机的对接方式 + * @version 1.0 + * @date 2024-08-08 + * + * @copyright Copyright (c) 2024 + * + */ + +#include "cmsis_compiler.h" +#include "usart.h" +#include "dma.h" + +// 接收发送方式,不使用阻塞式发送接收,有RTOS可以考虑阻塞发送(可以但没必要),发送和接收的方式是可以组合使用的需自行更改 +#define PLATFORM_MODE_DMA 0 // 使用DMA发送与接收 +#define PLATFORM_MODE_IT 1 // 使用中断发送与接收 +// #define PLATFORM_MODE_POLL 2 // 使用轮询发送与接收(阻塞) +// 使用DMA发送与接收 +#define PLATFORM_MODE PLATFORM_MODE_DMA + +#define RTOS_NONE 0 // 无操作系统 +#define RTOS_FREERTOS 1 // 使用FreeRTOS +// 定义使用的操作系统 +#define RTOS_MODE RTOS_NONE // 未使用操作系统 + +//+********************************* 必须对接的宏 **********************************/ +// 写入是否可以阻塞的判断函数,通常不在中断中就可以阻塞 +#define SHELL_WRITE_CAN_BLOCK() (__get_IPSR() == 0) + +#define WAIT_A_MOMENT() HAL_Delay(1) // 等待一段时间,外设跟不上内核填充的速度 + +// 原子操作保证数据的完整性,支持嵌套更好 +#define SHELL_ATOMIC_ENTER() __disable_irq() +#define SHELL_ATOMIC_EXIT() __enable_irq() + +#define SHELL_UART_ADDR (&huart1) +// clang-format off + +#if (PLATFORM_MODE == PLATFORM_MODE_DMA) + extern HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); + extern HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); + #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_DMA(SHELL_UART_ADDR, (uint8_t *)buffer, len) + #define PLATFORM_RX_WRAP(buffer, len) HAL_UARTEx_ReceiveToIdle_DMA(SHELL_UART_ADDR, (uint8_t *)buffer, len) +#elif (PLATFORM_MODE == PLATFORM_MODE_IT) + extern HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); + extern HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); + #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_IT(SHELL_UART_ADDR, (uint8_t *)buffer, len) + // 中断接收改成单个字节接收 + #define PLATFORM_RX_WRAP(buffer, len) HAL_UART_Receive_IT(SHELL_UART_ADDR, (uint8_t *)buffer, 1) +#else +#error "请实现自己的接收与发送函数对接" +#error "please implement your own receive and send function docking" +#endif + +// clang-format on + +/** + * @brief 获取系统时间(ms) + * 定义此宏为获取系统Tick,如`HAL_GetTick()` + * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 + */ +extern uint32_t HAL_GetTick(void); +#define SHELL_GET_TICK() HAL_GetTick() diff --git a/demo/quick_for_keil/shell_all.c b/demo/quick_for_keil/shell_all.c new file mode 100644 index 0000000..e69de29 diff --git a/demo/quick_for_keil/shell_all.h b/demo/quick_for_keil/shell_all.h new file mode 100644 index 0000000..e69de29 diff --git a/demo/quick_for_keil/shell_cfg_user.h b/demo/quick_for_keil/shell_cfg_user.h new file mode 100644 index 0000000..e69de29 From a8dea8ab8e5ea315cb8c0923c0fe457b9948320b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Fri, 9 Aug 2024 23:42:43 +0800 Subject: [PATCH 03/12] =?UTF-8?q?docs:=20=F0=9F=93=9D=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E7=A7=BB=E6=A4=8D=E8=AF=B4=E6=98=8E,=E5=8E=BB=E9=99=A4?= =?UTF-8?q?=E5=86=97=E4=BD=99=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/easy_for_keil/ringbuffer/ringbuffer.c | 227 ------------- demo/easy_for_keil/ringbuffer/ringbuffer.h | 64 ---- demo/easy_for_keil/shell_all.c | 321 ------------------ demo/easy_for_keil/shell_all.h | 83 ----- demo/easy_for_keil/shell_cfg_user.h | 113 ------ .../stm32_HAL_adapt/stm32_HAL_adapt.c | 161 --------- .../stm32_HAL_adapt/stm32_HAL_adapt.h | 75 ---- 7 files changed, 1044 deletions(-) delete mode 100644 demo/easy_for_keil/ringbuffer/ringbuffer.c delete mode 100644 demo/easy_for_keil/ringbuffer/ringbuffer.h delete mode 100644 demo/easy_for_keil/shell_all.c delete mode 100644 demo/easy_for_keil/shell_all.h delete mode 100644 demo/easy_for_keil/shell_cfg_user.h delete mode 100644 demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c delete mode 100644 demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h diff --git a/demo/easy_for_keil/ringbuffer/ringbuffer.c b/demo/easy_for_keil/ringbuffer/ringbuffer.c deleted file mode 100644 index 02ba04f..0000000 --- a/demo/easy_for_keil/ringbuffer/ringbuffer.c +++ /dev/null @@ -1,227 +0,0 @@ -#include "ringbuffer.h" -#include - -#undef USER_ASSERT -#define USER_ASSERT(exp) (void)0 // 开启此宏关闭此文件用户自定义断言 - -// clang-format off -#ifndef USER_ASSERT - #include - #define USER_ASSERT(exp) \ - if (!(exp)) \ - { \ - printf("\"" #exp "\" assert failed at file: %s, line: %d", __FILE__, __LINE__); \ - for (;;) \ - ; \ - } -#endif // ! USER_ASSERT -// clang-format on - -void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - rb->buffer = buffer; - rb->buffer_size = size; - rb->busy = false; - - ringbuffer_reset(rb); -} - -void ringbuffer_reset(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - rb->head = 0; - rb->tail = 0; - rb->data_count = 0; -} - -uint16_t ringbuffer_get_free(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->buffer_size - rb->data_count; -} - -uint16_t ringbuffer_get_used(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->data_count; -} - -uint16_t ringbuffer_get_size(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->buffer_size; -} - -uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->last_series_count; -} - -uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - uint16_t free_size = ringbuffer_get_free(rb); - - if (size > free_size) - { - size = free_size; // 多余的数据不写入(丢掉) - } - - // 判断超过尾部没有 - if (rb->tail + size > rb->buffer_size) - { - uint16_t first_size = rb->buffer_size - rb->tail; - memcpy((uint8_t *)(rb->buffer) + rb->tail, data, first_size); - memcpy(rb->buffer, data + first_size, size - first_size); - } - else - { - memcpy((uint8_t *)(rb->buffer) + rb->tail, data, size); - } - - // 限制尾部位置 - if (rb->tail + size >= rb->buffer_size) - { - rb->tail = size - (rb->buffer_size - rb->tail); - } - else - { - rb->tail += size; - } - - rb->data_count += size; - - return size; -} - -uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - uint16_t used_size = ringbuffer_get_used(rb); - - if (size > used_size) - { - size = used_size; // 读取的数据超过了已有数据量 - } - - // 判断超过尾部没有 - if (rb->head + size > rb->buffer_size) - { - uint16_t first_size = rb->buffer_size - rb->head; - memcpy(data, (uint8_t *)(rb->buffer) + rb->head, first_size); - memcpy(data + first_size, rb->buffer, size - first_size); - } - else - { - memcpy(data, (uint8_t *)(rb->buffer) + rb->head, size); - } - - // 限制头部位置 - if (rb->head + size >= rb->buffer_size) - { - rb->head = size - (rb->buffer_size - rb->head); - } - else - { - rb->head += size; - } - - rb->data_count -= size; - - return size; -} - -uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size) -{ - USER_ASSERT(rb != NULL); - USER_ASSERT(size != NULL); - uint16_t max_size = ringbuffer_get_free(rb); - - if (max_size + rb->tail > rb->buffer_size) - { - max_size = rb->buffer_size - rb->tail; - } - - *size = max_size; - rb->last_series_count = max_size; - - return (uint8_t *)(rb->buffer) + rb->tail; -} - -uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size) -{ - USER_ASSERT(rb != NULL); - USER_ASSERT(size != NULL); - uint16_t max_size = ringbuffer_get_used(rb); - - if (max_size + rb->head > rb->buffer_size) - { - max_size = rb->buffer_size - rb->head; - } - - *size = max_size; - rb->last_series_count = max_size; - - return (uint8_t *)(rb->buffer) + rb->head; -} - -uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - // 限制尾部位置 - if (rb->tail + size >= rb->buffer_size) - { - rb->tail = size - (rb->buffer_size - rb->tail); - } - else - { - rb->tail += size; - } - - rb->data_count += size; - - return size; -} - -uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - // 限制头部位置 - if (rb->head + size >= rb->buffer_size) - { - rb->head = size - (rb->buffer_size - rb->head); - } - else - { - rb->head += size; - } - - rb->data_count -= size; - - return size; -} - -void ringbuffer_mark_busy(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - rb->busy = true; -} - -void ringbuffer_mark_idle(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - rb->busy = false; -} - -bool ringbuffer_is_busy(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->busy; -} diff --git a/demo/easy_for_keil/ringbuffer/ringbuffer.h b/demo/easy_for_keil/ringbuffer/ringbuffer.h deleted file mode 100644 index c79d2d2..0000000 --- a/demo/easy_for_keil/ringbuffer/ringbuffer.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file ringbuffer.h - * @author 独霸一方 (2696652257@qq.com) - * @brief //> 部分参考cherryRB实现的环形缓冲区,完整实现参考:https://github.com/cherry-embedded/CherryRB - * 源码直接加入shell_all.c中进行编译,无需再次添加此目录下.c文件进行编译 - * @version 1.0 - * @date 2024-08-05 - * - * @copyright Copyright (c) 2024 - * - */ - -// > 单次包含宏定义 -#ifndef __RINGBUFFER_H_ -#define __RINGBUFFER_H_ - -#include -#include -#include - -// > C/C++兼容性宏定义 -#ifdef __cplusplus -extern "C" -{ -#endif - - typedef struct __ringbuffer_t ringbuffer_t; - struct __ringbuffer_t - { - bool busy; // 用于指示'慢速'外设是否正在操作缓冲区,比如DMA传输 - uint16_t head; - uint16_t tail; - uint16_t data_count; // 当前队列中的数据量 - uint16_t last_series_count; // 调用连续读或写时候实际设置的值 - uint16_t buffer_size; // 缓冲区大小 - uint8_t *buffer; - }; - - void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size); - void ringbuffer_reset(ringbuffer_t *rb); - - uint16_t ringbuffer_get_free(ringbuffer_t *rb); // 获取剩余空间 - uint16_t ringbuffer_get_used(ringbuffer_t *rb); // 获取已使用空间 - uint16_t ringbuffer_get_size(ringbuffer_t *rb); // 获取缓冲区大小 - uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb); // 获取上次调用线性读取或者写入时候的设置的大小 - - uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size); // 返回实际写入的数据量 - uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size); // 返回实际读取的数据量 - - // for linear read/write operation(such as DMA) - extern uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size); // 返回写入的地址并设置实际能写入的数据量 - extern uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size); // 返回读取的地址并设置实际能读取的数据量 - extern uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size); // 返回实际写入的数据量 - extern uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size); // 返回实际读取的数据量 - - void ringbuffer_mark_busy(ringbuffer_t *rb); - void ringbuffer_mark_idle(ringbuffer_t *rb); - bool ringbuffer_is_busy(ringbuffer_t *rb); - -#ifdef __cplusplus -} -#endif //\ __cplusplus - -#endif //\ __RINGBUFFER_H_ diff --git a/demo/easy_for_keil/shell_all.c b/demo/easy_for_keil/shell_all.c deleted file mode 100644 index d61c2c6..0000000 --- a/demo/easy_for_keil/shell_all.c +++ /dev/null @@ -1,321 +0,0 @@ -#include "shell_all.h" - -#include -#include - -// 将所有的源码文件加入到这一个文件中,方便Keil工程的添加 - -#if 1 - -#include "./ringbuffer/ringbuffer.c" // 环形队列 - -// shell核心实现包含 -#include "../../src/shell.c" -#include "../../src/shell_ext.c" -#include "../../src/shell_cmd_list.c" -#include "../../src/shell_companion.c" - -// shell拓展组件 - -// shell增强组件 -#include "../../extensions/shell_enhance/shell_cmd_group.c" // 命令组 -#include "../../extensions/shell_enhance/shell_passthrough.c" // 透传 -#include "../../extensions/shell_enhance/shell_secure_user.c" // 安全用户 - -// shell log组件 -#include "../../extensions/log/log.c" // 日志 - -//// shell fs组件 -// #include "../../extensions/fs_support/shell_fs.c" // 文件命令 - -//// shell telnet组件 -// #include "../../extensions/telnet/telnetd.c" // telnet,需要命令组拓展(注意头文件路径包含) - -#endif - -//// shell game组件需要单独添加.c到工程中,不然会有一些同名函数的问题 -// #include "../../extensions/game/game.c" // 游戏,需要命令组拓展(注意头文件路径包含) -// #include "../../extensions/game/2048/2048.c" // 2048 -// #include "../../extensions/game/pushbox/pushbox.c" // 贪吃蛇 - -//+********************************* 环形队列中转 **********************************/ -#if SHELL_SHOW_INFO == 1 -#if SHELL_TX_BUFFER_SIZE < 400 -#warning "建议将环形队列的大小设置为大于400,否则打印初始化信息的时候可能会出现部分打印数据丢失" -#warning "shell tx buffer size is too small, please increase the buffer size" -#endif -#endif - -// 定义shell和log对象 -static Shell user_shell; -static Log user_log; - -// 发送和接收的中转环形缓冲队列 -static ringbuffer_t rb_rx; -static ringbuffer_t rb_tx; - -// 写入是否可以阻塞,默认不可以阻塞,一般判断是否在中断中就可以判断是否可以阻塞 -#ifndef SHELL_WRITE_CAN_BLOCK -#define SHELL_WRITE_CAN_BLOCK() (false) -#endif // !SHELL_WRITE_CAN_BLOCK - -//+********************************* shell读写对接 **********************************/ - -short write_to_ringbuffer(char *data, unsigned short len) -{ - short total_written = 0; - short ret = 0; - - while (len > 0) - { - SHELL_ATOMIC_ENTER(); - - ret = ringbuffer_write(&rb_tx, (uint8_t *)data, len); - - SHELL_ATOMIC_EXIT(); - - if (ret >= len) // 只可能小于等于 - { - return total_written; // 全部数据写入成功 - } - else - { - if (!SHELL_WRITE_CAN_BLOCK()) - { - total_written += ret; - break; // 如果在中断中,直接退出,未写入的数据直接丢弃,避免长时间占用中断 - } - - total_written += ret; - data += ret; - len -= ret; - port_tx_trigger(); // 主动尝试触发发送 - - WAIT_A_MOMENT(); // 等待一段时间,避免频繁触发发送 - } - } - - return total_written; -} - -short read_from_ringbuffer(char *data, unsigned short len) -{ - short ret = 0; - SHELL_ATOMIC_ENTER(); - - ret = ringbuffer_read(&rb_rx, (uint8_t *)data, len); - - SHELL_ATOMIC_EXIT(); - return ret; -} - -//+******************************** log组件对接 ***************************************/ - -void UserLogWrite(char *buffer, short len) -{ -#if SHELL_SUPPORT_END_LINE == 1 - USER_ASSERT(user_log.shell != NULL); - shellWriteEndLine(user_log.shell, buffer, len); -#else - USER_ASSERT(user_log.shell != NULL); - USER_ASSERT(user_log.shell->write != NULL); - user_log.shell->write(buffer, len); -#endif -} - -//+******************************** 对外调用接口 ***************************************/ -void port_tx_trigger(void) -{ - if (ringbuffer_is_busy(&rb_tx) || ringbuffer_get_used(&rb_tx) <= 0) - { - return; // 没有数据或者外设还在响应上一次的发送 - } - - // 这两个栈变量可能会在极端情况下破坏原子操作性,改成static然后提到函数开头效果可能会更好 - uint16_t size; - uint8_t *p; - - SHELL_ATOMIC_ENTER(); - - // 获取ringbuffer当前的读指针和最大线性可读数据大小 - ringbuffer_mark_busy(&rb_tx); // 标记为忙,调用port_tx_end函数后再标记为闲 - p = ringbuffer_linear_read_setup(&rb_tx, &size); - - SHELL_ATOMIC_EXIT(); - - // 发送数据,调用平台相关的发送函数 - PLATFORM_TX_WRAP(p, size); -} - -void port_rx_trigger(void) -{ - - if (ringbuffer_is_busy(&rb_rx) || ringbuffer_get_free(&rb_rx) <= 0) // 性能优化,对于接收,外设忙的情况更多先判断是否在忙 - { - return; // 没有空间接收或者正在接收数据 - } - - // 这两个栈变量可能会在极端情况下破坏原子操作性,改成static然后提到函数开头效果可能会更好 - uint16_t size; - uint8_t *p; - - SHELL_ATOMIC_ENTER(); - ringbuffer_mark_busy(&rb_rx); // 标记为忙,调用port_rx_end函数后再标记为闲 - // 获取ringbuffer当前的写指针和最大线性可写数据大小 - p = ringbuffer_linear_write_setup(&rb_rx, &size); - - SHELL_ATOMIC_EXIT(); - - // 接收数据,调用平台相关的接收函数 - PLATFORM_RX_WRAP(p, size); -} - -// 通常用于中断中调用 -void port_tx_end(short truely_tx_len) -{ - SHELL_ATOMIC_ENTER(); - if (truely_tx_len < 0) - { - truely_tx_len = ringbuffer_get_last_series_size(&rb_tx); - } - - ringbuffer_linear_read_done(&rb_tx, truely_tx_len); - ringbuffer_mark_idle(&rb_tx); - - SHELL_ATOMIC_EXIT(); - -#if SHELL_TX_CONTINUOUSLY - port_tx_trigger(); // 继续发送 -#endif -} - -void port_rx_end(short truely_rx_len) -{ - SHELL_ATOMIC_ENTER(); - if (truely_rx_len < 0) - { - truely_rx_len = ringbuffer_get_last_series_size(&rb_rx); - } - - ringbuffer_linear_write_done(&rb_rx, truely_rx_len); - ringbuffer_mark_idle(&rb_rx); - SHELL_ATOMIC_EXIT(); - -#if SHELL_RX_CONTINUOUSLY - //! 继续接收,如果这里由于队列满了导致没有触发接收,那么直到再次触发接收之前,都不会再接收数据了 - port_rx_trigger(); -#endif -} - -//+******************************** shell和log组件初始化,shell任务 ***************************************/ - -void letter_shell_init(void) -{ - PLATFORM_INIT(); - - // 初始化输入输出环形队列 - static char rb_rx_buffer[SHELL_RX_BUFFER_SIZE]; - static char rb_tx_buffer[SHELL_TX_BUFFER_SIZE]; - ringbuffer_init(&rb_rx, (uint8_t *)rb_rx_buffer, sizeof(rb_rx_buffer)); - ringbuffer_init(&rb_tx, (uint8_t *)rb_tx_buffer, sizeof(rb_tx_buffer)); - - // 用于存放命令之类的buffer - static char shell_buffer[512]; - - user_shell.write = write_to_ringbuffer; - user_shell.read = read_from_ringbuffer; -#if SHELL_USING_LOCK == 1 - -#if !defined(SHELL_LOCK_FUNC) || !defined(SHELL_UNLOCK_FUNC) -#error "请定义shell的加锁与解锁函数或者不使用log锁(设置SHELL_USING_LOCK为0)" -#error "please define SHELL_LOCK_FUNC and SHELL_UNLOCK_FUNC" -#endif - user_shell.lock = SHELL_LOCK_FUNC; - user_shell.unlock = SHELL_UNLOCK_FUNC; -#endif - shellInit(&user_shell, shell_buffer, sizeof(shell_buffer)); // 初始化shell - - user_log.active = 1; // 创建log对象,默认输出所有等级的log - user_log.level = LOG_ALL; - user_log.write = UserLogWrite, -#if LOG_USING_LOCK == 1 - -#if !defined(LOG_LOCK_FUNC) || !defined(LOG_UNLOCK_FUNC) -#error "请定义log的加锁与解锁函数或者不使用log锁(设置LOG_USING_LOCK为0)" -#error "please define LOG_LOCK_FUNC and LOG_UNLOCK_FUNC" -#endif - - user_log.lock = LOG_LOCK_FUNC; - user_log.unlock = LOG_UNLOCK_FUNC; -#endif - - logRegister(&user_log, &user_shell); // 注册log -} - -void shell_task() -{ -#if SHELL_TASK_WHILE == 1 - for (;;) - { -#endif - port_tx_trigger(); - port_rx_trigger(); - // 读取数据进行处理,这里可以多读几个字节,提高处理效率 - static char data; - // while (user_shell.read(&data, 1)) - if (user_shell.read(&data, 1)) - { - shellHandler(&user_shell, data); - } -#if SHELL_TASK_WHILE == 1 - } -#endif -} - -//+********************************* 导出一些可能用到的命令或快捷键 **********************************/ -static void logChangeLevel() -{ - Log *log = &user_log; - SHELL_ASSERT(log, return); - log->level = (LogLevel)(log->level >= LOG_ALL ? LOG_NONE : (log->level + 1)); - - char logLevel[40] = {0}; - switch (log->level) - { - case LOG_NONE: - sprintf(logLevel, "set log level : LOG_NONE\t(%d)", log->level); - break; - - case LOG_ERROR: - sprintf(logLevel, "set log level : LOG_ERROR\t(%d)", log->level); - break; - - case LOG_WRANING: - sprintf(logLevel, "set log level : LOG_WRANING\t(%d)", log->level); - break; - - case LOG_INFO: - sprintf(logLevel, "set log level : LOG_INFO\t(%d)", log->level); - break; - - case LOG_DEBUG: - sprintf(logLevel, "set log level : LOG_DEBUG\t(%d)", log->level); - break; - - case LOG_VERBOSE: - sprintf(logLevel, "set log level : LOG_VERBOSE\t(%d)", log->level); - break; - - case LOG_ALL: - sprintf(logLevel, "set log level : LOG_ALL\t\t(%d)", log->level); - break; - - default: - break; - } - - logPrintln("%s", logLevel); -} -//> 0x04000000对应的应该是鼠标中键,但是在Xshell中,按下鼠标中间会以字符串的形式发送04000000,导致无法触发,现在修改为 ~ 的按键值 -// SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x04000000, logChangeLevel, switch log level); -SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x60000000, logChangeLevel, '~' switch log level); \ No newline at end of file diff --git a/demo/easy_for_keil/shell_all.h b/demo/easy_for_keil/shell_all.h deleted file mode 100644 index 5790039..0000000 --- a/demo/easy_for_keil/shell_all.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file shell_all.h - * @author 独霸一方 (2696652257@qq.com) - * @brief //> 这个文件将包含letter shell的所有头文件实现(相对路径),方便在Keil工程中使用 - * @version 1.0 - * @date 2024-08-05 - * - * @copyright Copyright (c) 2024 - * - */ - -// 此文件使用相对路径,保证在任何地方都可以使用 - -// > 单次包含宏定义 -#ifndef __SHELL_ALL_H_ -#define __SHELL_ALL_H_ - -// 包含对接的头文件,使用相对路径 -#include "./stm32_HAL_adapt/stm32_HAL_adapt.h" - -#include "shell_cfg_user.h" // 使用本文件目录下的自定义配置文件 - -//> 环形队列用来等待接收和发送的数据,这样就可以在中断中调用shell的读写函数 -#define SHELL_RX_BUFFER_SIZE 512 -#define SHELL_TX_BUFFER_SIZE 512 - -// 连续发送与接收宏定义,当使用阻塞式接收发送时必须关闭指定的宏定义 -#define SHELL_TX_CONTINUOUSLY 1 // 使能连续发送(end中继续检测是否还有数据需要发送) -#define SHELL_RX_CONTINUOUSLY 1 // 使能连续接收(end中继续检测是否还有空间可以接收) - -// > C/C++兼容性宏定义 -#ifdef __cplusplus -extern "C" -{ -#endif - - //+******************************** C scope ***************************************/ - -#include "../../src/shell.h" - -// shell核心头文件 -#include "../../src/shell_cfg.h" -#include "../../src/shell.h" -#include "../../src/shell_ext.h" - -// shell增强组件 -#include "../../extensions/shell_enhance/shell_cmd_group.h" // 命令组 -#include "../../extensions/shell_enhance/shell_passthrough.h" // 透传 -#include "../../extensions/shell_enhance/shell_secure_user.h" // 安全用户 - - // #undef LOG_ENABLE - // #define LOG_ENABLE 0 //>在对应的C文件中使用此定义即可关闭当前文件的日志输出,需要加在文件最前面,直接打开这里的注释是关闭所有文件的日志输出 - -// shell log组件 -#include "../../extensions/log/log.h" // 日志 - - //// shell fs组件 - // #include "../../extensions/fs_support/shell_fs.h" // 文件命令 - - //// shell telnet组件 - // #include "../../extensions/telnet/telnetd.h" // telnet - - void port_tx_trigger(void); // 触发发送,定期调用 - void port_tx_end(short truely_tx_len); // 实际发送完后一定要调用,发送中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 - - void port_rx_trigger(void); // 触发接收,定期调用 - void port_rx_end(short truely_rx_len); // 实际接收完后一定要调用,接收中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 - - // 初始化shell和log - void letter_shell_init(void); - - // shell任务 - void shell_task(); - -#ifdef __cplusplus -} -//+******************************** c++ scope ***************************************/ -// shell C++支持组件 -#include "../../extensions/cpp_support/shell_cpp.h" // C++命令 - -#endif //\ __cplusplus - -#endif //\ __SHELL_ALL_H_ diff --git a/demo/easy_for_keil/shell_cfg_user.h b/demo/easy_for_keil/shell_cfg_user.h deleted file mode 100644 index 7c98bc2..0000000 --- a/demo/easy_for_keil/shell_cfg_user.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file shell_cfg_user.h - * @author Letter (nevermindzzt@gmail.com) - * @brief shell config - * @version 3.0.0 - * @date 2019-12-31 - * - * @copyright (c) 2019 Letter - * - */ - -#ifndef __SHELL_CFG_USER_H__ -#define __SHELL_CFG_USER_H__ - -#include - -// clang-format off - -/** - * @brief shell默认用户 - */ -#define SHELL_DEFAULT_USER "letter_shell" - -// /** -// * @brief 是否使用shell伴生对象,开启后需要支持malloc和free接口 -// * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 -// */ -// #define SHELL_USING_COMPANION 0 - -// /** -// * @brief shell内存分配 -// * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 -// */ -// extern void *pvPortMalloc(size_t xSize); -// #define SHELL_MALLOC(size) pvPortMalloc(size) - -// /** -// * @brief shell内存释放 -// * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 -// */ -// extern void vPortFree(void *pv); -// #define SHELL_FREE(obj) vPortFree(obj) - -/** - * @brief 使用锁 - * @note 使用shell锁时,需要对加锁和解锁进行实现 - */ -#define SHELL_USING_LOCK 0 - -#ifndef SHELL_TASK_WHILE -/** - * @brief 是否使用默认shell任务while循环 - * 使能此宏,则`shell_task()`函数会一直循环读取输入,一般使用操作系统建立shell - * 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shell_task()` - */ -#define SHELL_TASK_WHILE 0 -#endif /** SHELL_TASK_WHILE */ - -/** - * @brief 是否显示shell信息 - */ -#define SHELL_SHOW_INFO 1 - -/** - * @brief 支持shell尾行模式 - */ -#define SHELL_SUPPORT_END_LINE 1 - - -/** - * @brief 使用LF作为命令行回车触发 - * 可以和SHELL_ENTER_CR同时开启 - */ -#define SHELL_ENTER_LF 0 - -/** - * @brief 使用CR作为命令行回车触发 - * 可以和SHELL_ENTER_LF同时开启 - */ -#define SHELL_ENTER_CR 0 - -/** - * @brief 使用CRLF作为命令行回车触发 - * 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启 - */ -#define SHELL_ENTER_CRLF 1 - -#ifndef SHELL_PRINT_BUFFER -/** - * @brief shell格式化输出的缓冲大小 - * 为0时不使用shell格式化输出 - */ -#define SHELL_PRINT_BUFFER 256 -#endif /** SHELL_PRINT_BUFFER */ - -/** - * @brief shell格式化输入的缓冲大小 - * 为0时不使用shell格式化输入 - * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用 - */ -#define SHELL_SCAN_BUFFER 256 - -/** - * @brief 使用函数签名 - * 使能后,可以在声明命令时,指定函数的签名,shell 会根据函数签名进行参数转换, - * 而不是自动判断参数的类型,如果参数和函数签名不匹配,会停止执行命令 - */ -#define SHELL_USING_FUNC_SIGNATURE 1 - -//+******************************** log组件配置 ***************************************/ -//>log组件的配置在log.h中配置 - -#endif diff --git a/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c b/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c deleted file mode 100644 index c800c90..0000000 --- a/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.c +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file stm32_HAL_adapt.c - * @author 独霸一方 (2696652257@qq.com) - * @brief //> stm32 HAL库适配letter shell - * @version 1.0 - * @date 2024-08-07 - * - * @copyright Copyright (c) 2024 - * - */ - -#include "stm32_HAL_adapt.h" - -#include "../shell_all.h" - -// 写入是否可以阻塞,默认不可以阻塞,一般判断是否在中断中就可以判断是否可以阻塞 -#ifndef SHELL_WRITE_CAN_BLOCK -#define SHELL_WRITE_CAN_BLOCK() (false) -#endif // !SHELL_WRITE_CAN_BLOCK - -// 如果有操作系统,可以使用操作系统提供的递归互斥锁 - -void shell_lock(struct shell_def *shell) -{ - if (SHELL_WRITE_CAN_BLOCK()) - { - // 操作系统的加锁 - } - else - { - // 处于不能阻塞的地方,一般认为是中断,直接不管 - } -} - -void shell_unlock(struct shell_def *shell) -{ - if (SHELL_WRITE_CAN_BLOCK()) - { - // 操作系统的解锁 - } - else - { - } -} - -void log_lock(struct log_def *log) -{ - if (SHELL_WRITE_CAN_BLOCK()) - { - } - else - { - } -} - -void log_unlock(struct log_def *log) -{ - if (SHELL_WRITE_CAN_BLOCK()) - { - } - else - { - } -} - -// shell使用的硬件初始化,使用cubemx开启串口,然后使能对应的串口中断,DMA发送与接收中断 -void user_hardware_init() -{ - // 由于初始化已经由CUBEMX处理好了,这里什么都不需要做,建议关闭DMA接收半满中断 - // __HAL_DMA_DISABLE_IT(SHELL_UART_ADDR, DMA_IT_HT); -} - -//+******************************** 平台的中断回调 ***************************************/ -//! 如果有自己其他串口的中断回调,请自行按照这个格式添加 - -#if 1 - -#if (PLATFORM_MODE == PLATFORM_MODE_DMA) -void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) // 串口接收中断 -{ - UNUSED(huart); - UNUSED(Size); - - if (huart->Instance == SHELL_UART_ADDR->Instance) - { - port_rx_end(Size); - } -} - -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 -{ - UNUSED(huart); - - if (huart->Instance == SHELL_UART_ADDR->Instance) - { - port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 - } -} -#elif (PLATFORM_MODE == PLATFORM_MODE_IT) -void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) -{ - if (huart->Instance == SHELL_UART_ADDR->Instance) - { - port_rx_end(1); // 中断接收的时候是单字节接收,因此实际接收到1个字节就会进入此中断 - } -} - -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 -{ - UNUSED(huart); - - if (huart->Instance == SHELL_UART_ADDR->Instance) - { - port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 - } -} -#endif - -#endif - -//+******************************** 导出一些可能常用的命令 ***************************************/ -int Reboot() -{ - HAL_NVIC_SystemReset(); // 单片机重启 - return 0; -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), Reboot, Reboot, reboot the mcu); - -#if 1 - -#include -int date() -{ - Shell *shell = shellGetCurrent(); - - if (!shell) - return 0; - - int64_t ticks = SHELL_GET_TICK(); - -#if SHELL_USING_LOCK == 1 - shell->lock(shell); -#endif - - char str[120]; - snprintf(str, sizeof(str), "current time: %lld\r\n", ticks); - shellWriteString(shell, str); - - // 换算为天`时`分`秒`毫秒 - snprintf(str, sizeof(str), "current time: %lld天 %02lld时 %02lld分 %02lld秒 %03lld毫秒\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); - shellWriteString(shell, str); - -#if SHELL_USING_LOCK == 1 - shell->unlock(shell); -#endif - - return 0; -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), date, date, current time); - -#endif \ No newline at end of file diff --git a/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h deleted file mode 100644 index a7cb24c..0000000 --- a/demo/easy_for_keil/stm32_HAL_adapt/stm32_HAL_adapt.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file stm32_HAL_adapt.h - * @author fool_dog (2696652257@qq.com) - * @brief // 裸机的对接方式 - * @version 1.0 - * @date 2024-08-08 - * - * @copyright Copyright (c) 2024 - * - */ - -#include "cmsis_compiler.h" -#include "usart.h" -#include "dma.h" - -// 接收发送方式,不使用阻塞式发送接收,有RTOS可以考虑阻塞发送(可以但没必要),发送和接收的方式是可以组合使用的, -#define PLATFORM_MODE_DMA 0 -#define PLATFORM_MODE_IT 1 - -// 使用DMA发送与接收 -#define PLATFORM_MODE PLATFORM_MODE_DMA - -struct shell_def; // shell的前置声明 -void shell_lock(struct shell_def *shell); -void shell_unlock(struct shell_def *shell); -struct log_def; // log的前置声明 -void log_lock(struct log_def *log); -void log_unlock(struct log_def *log); -// 加锁解锁的对应函数 -#define SHELL_LOCK_FUNC shell_lock -#define SHELL_UNLOCK_FUNC shell_unlock -#define LOG_LOCK_FUNC log_lock -#define LOG_UNLOCK_FUNC log_unlock - -//+********************************* 必须对接的宏 **********************************/ -// 写入是否可以阻塞的判断函数,通常不在中断中就可以阻塞 -#define SHELL_WRITE_CAN_BLOCK() (__get_IPSR() == 0) - -#define WAIT_A_MOMENT() HAL_Delay(1) // 等待一段时间,外设跟不上内核填充的速度 - -// 原子操作保证数据的完整性,支持嵌套更好 -#define SHELL_ATOMIC_ENTER() __disable_irq() -#define SHELL_ATOMIC_EXIT() __enable_irq() - -// 平台初始化 -extern void user_hardware_init(); -#define PLATFORM_INIT() user_hardware_init() - -#define SHELL_UART_ADDR (&huart1) -// clang-format off - -#if (PLATFORM_MODE == PLATFORM_MODE_DMA) - extern HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); - extern HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); - #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_DMA(SHELL_UART_ADDR, (uint8_t *)buffer, len) - #define PLATFORM_RX_WRAP(buffer, len) HAL_UARTEx_ReceiveToIdle_DMA(SHELL_UART_ADDR, (uint8_t *)buffer, len) -#elif (PLATFORM_MODE == PLATFORM_MODE_IT) - extern HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); - extern HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); - #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_IT(SHELL_UART_ADDR, (uint8_t *)buffer, len) - // 中断接收改成单个字节接收 - #define PLATFORM_RX_WRAP(buffer, len) HAL_UART_Receive_IT(SHELL_UART_ADDR, (uint8_t *)buffer, 1) -#endif - -// clang-format on - -#ifndef SHELL_GET_TICK -/** - * @brief 获取系统时间(ms) - * 定义此宏为获取系统Tick,如`HAL_GetTick()` - * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 - */ -extern uint32_t HAL_GetTick(void); -#define SHELL_GET_TICK() HAL_GetTick() -#endif /** SHELL_GET_TICK */ From 323a502e150eedb2a3f20ddbe115051edf980bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Fri, 9 Aug 2024 23:58:55 +0800 Subject: [PATCH 04/12] =?UTF-8?q?docs:=20=F0=9F=93=9D=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=86=97=E4=BD=99=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/quick_for_keil/shell_all.c | 0 demo/quick_for_keil/shell_all.h | 0 demo/quick_for_keil/shell_cfg_user.h | 0 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 demo/quick_for_keil/shell_all.c delete mode 100644 demo/quick_for_keil/shell_all.h delete mode 100644 demo/quick_for_keil/shell_cfg_user.h diff --git a/demo/quick_for_keil/shell_all.c b/demo/quick_for_keil/shell_all.c deleted file mode 100644 index e69de29..0000000 diff --git a/demo/quick_for_keil/shell_all.h b/demo/quick_for_keil/shell_all.h deleted file mode 100644 index e69de29..0000000 diff --git a/demo/quick_for_keil/shell_cfg_user.h b/demo/quick_for_keil/shell_cfg_user.h deleted file mode 100644 index e69de29..0000000 From 348bab8dad66a0c6ab4d0dc75578d4bf7af53e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Sun, 11 Aug 2024 14:27:50 +0800 Subject: [PATCH 05/12] =?UTF-8?q?fix:=20=F0=9F=90=9B=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=AE=8F=E7=9A=84=E6=A0=BC=E5=BC=8F,?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=83=A8=E5=88=86=E5=AE=8F=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/easy_transplant/shell_all.c | 2 +- demo/easy_transplant/shell_all.h | 10 +++++++++- .../stm32_HAL_adapt/stm32_HAL_adapt.h | 12 ++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/demo/easy_transplant/shell_all.c b/demo/easy_transplant/shell_all.c index 0fc00aa..fb3a55d 100644 --- a/demo/easy_transplant/shell_all.c +++ b/demo/easy_transplant/shell_all.c @@ -83,7 +83,7 @@ short write_to_ringbuffer(char *data, unsigned short len) if (!SHELL_WRITE_CAN_BLOCK()) { total_written += ret; - WRITE_OVER_FLOW_HOOK(); + WRITE_OVER_FLOW_HOOK((char *)data - total_written, total_written, len); break; // 如果在中断中,直接退出,未写入的数据直接丢弃,避免长时间占用中断 } diff --git a/demo/easy_transplant/shell_all.h b/demo/easy_transplant/shell_all.h index 08fe791..41bf77a 100644 --- a/demo/easy_transplant/shell_all.h +++ b/demo/easy_transplant/shell_all.h @@ -16,6 +16,7 @@ #define __SHELL_ALL_H_ //> 平台适配的头文件必须放在最前面,确保宏定义的预处理定义正确 +//> 如果有自己的实现请替换为对应自己的头文件 #include "./stm32_HAL_adapt/stm32_HAL_adapt.h" #include "shell_cfg_user.h" // 使用本文件目录下的自定义配置文件 @@ -29,7 +30,14 @@ #define SHELL_RX_CONTINUOUSLY 1 // 使能连续接收(end中继续检测是否还有空间可以接收) // shell 写入溢出的时候可以调用钩子函数进行一些处理 -#define WRITE_OVER_FLOW_HOOK() (void)0 +#ifndef WRITE_OVER_FLOW_HOOK +#define WRITE_OVER_FLOW_HOOK(data, len_written, len_lose) (void)0 +#endif + +#if !defined(PLATFORM_TX_WRAP) || !defined(PLATFORM_RX_WRAP) +#error "请实现自己的接收与发送函数对接" +#error "please implement your own receive and send function docking" +#endif // > C/C++兼容性宏定义 #ifdef __cplusplus diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h index 8c16be6..0ecd1ba 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h @@ -1,7 +1,7 @@ /** * @file stm32_HAL_adapt.h * @author fool_dog (2696652257@qq.com) - * @brief // 裸机的对接方式 + * @brief // 裸机与FreeRTOS的对接方式 * @version 1.0 * @date 2024-08-08 * @@ -9,19 +9,24 @@ * */ +// > 单次包含宏定义 +#ifndef _STM32_HAL_ADAPT_H_ +#define _STM32_HAL_ADAPT_H_ + #include "cmsis_compiler.h" #include "usart.h" -#include "dma.h" // 接收发送方式,不使用阻塞式发送接收,有RTOS可以考虑阻塞发送(可以但没必要),发送和接收的方式是可以组合使用的需自行更改 #define PLATFORM_MODE_DMA 0 // 使用DMA发送与接收 #define PLATFORM_MODE_IT 1 // 使用中断发送与接收 // #define PLATFORM_MODE_POLL 2 // 使用轮询发送与接收(阻塞) + // 使用DMA发送与接收 #define PLATFORM_MODE PLATFORM_MODE_DMA #define RTOS_NONE 0 // 无操作系统 #define RTOS_FREERTOS 1 // 使用FreeRTOS + // 定义使用的操作系统 #define RTOS_MODE RTOS_NONE // 未使用操作系统 @@ -39,6 +44,7 @@ // clang-format off #if (PLATFORM_MODE == PLATFORM_MODE_DMA) +#include "dma.h" extern HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); extern HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_DMA(SHELL_UART_ADDR, (uint8_t *)buffer, len) @@ -63,3 +69,5 @@ */ extern uint32_t HAL_GetTick(void); #define SHELL_GET_TICK() HAL_GetTick() + +#endif //\ _STM32_HAL_ADAPT_H_ From c63a8d8e13af05de0ef3faa7fd43afd65070f369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:14:51 +0800 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20=E2=9C=A8=20=E6=96=B0=E5=A2=9Elog?= =?UTF-8?q?Printf=E5=AE=8F,=E4=BC=98=E5=8C=96demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stm32_HAL_adapt/stm32_HAL_adapt.c | 3 +- .../stm32_HAL_adapt/stm32_HAL_adapt.h | 28 +++++++++++++------ extensions/log/log.h | 8 ++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c index 314184f..a2a3191 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c @@ -82,8 +82,7 @@ void log_unlock(struct log_def *log) // shell使用的硬件初始化,使用cubemx开启串口,然后使能对应的串口中断,DMA发送与接收中断 void user_init_before_shell() { - // 由于初始化已经由CUBEMX处理好了,这里什么都不需要做,建议关闭DMA接收半满中断 - // __HAL_DMA_DISABLE_IT(SHELL_UART_ADDR, DMA_IT_HT); + // 由于初始化已经由CUBEMX处理好了,这里什么都不需要做,建议开启DMA半满中断(默认开启) #if (RTOS_MODE == RTOS_FREERTOS) _shell_mutex = xSemaphoreCreateMutex(); diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h index 0ecd1ba..88eb794 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h @@ -17,24 +17,36 @@ #include "usart.h" // 接收发送方式,不使用阻塞式发送接收,有RTOS可以考虑阻塞发送(可以但没必要),发送和接收的方式是可以组合使用的需自行更改 -#define PLATFORM_MODE_DMA 0 // 使用DMA发送与接收 -#define PLATFORM_MODE_IT 1 // 使用中断发送与接收 -// #define PLATFORM_MODE_POLL 2 // 使用轮询发送与接收(阻塞) - +enum PLATFORM_MODE_t +{ + PLATFORM_MODE_DMA = 0, + PLATFORM_MODE_IT, + PLATFORM_MODE_POLL +}; // 使用DMA发送与接收 #define PLATFORM_MODE PLATFORM_MODE_DMA -#define RTOS_NONE 0 // 无操作系统 -#define RTOS_FREERTOS 1 // 使用FreeRTOS - +enum RTOS_TYPE_t +{ + RTOS_NONE = 0, // 无操作系统 + RTOS_FREERTOS, // FreeRTOS + // ... 其他操作系统 +}; // 定义使用的操作系统 -#define RTOS_MODE RTOS_NONE // 未使用操作系统 +#define RTOS_MODE RTOS_NONE //+********************************* 必须对接的宏 **********************************/ // 写入是否可以阻塞的判断函数,通常不在中断中就可以阻塞 #define SHELL_WRITE_CAN_BLOCK() (__get_IPSR() == 0) +#if (RTOS_MODE == RTOS_NONE) #define WAIT_A_MOMENT() HAL_Delay(1) // 等待一段时间,外设跟不上内核填充的速度 +#elif (RTOS_MODE == RTOS_FREERTOS) +#define WAIT_A_MOMENT() vTaskDelay(1) +#else +#warning "请实现自己的等待函数" +#warning "please implement your own wait function" +#endif // 原子操作保证数据的完整性,支持嵌套更好 #define SHELL_ATOMIC_ENTER() __disable_irq() diff --git a/extensions/log/log.h b/extensions/log/log.h index d576825..ac3fc36 100644 --- a/extensions/log/log.h +++ b/extensions/log/log.h @@ -131,6 +131,14 @@ typedef struct log_def #define logPrintln(format, ...) \ logWrite(LOG_ALL_OBJ, LOG_NONE, format "\r\n", ##__VA_ARGS__) +/** + * @brief log打印(不换行),用于直接替换printf + * + * @param fmt 格式 + * @param ... 参数 + */ +#define logPrint(format, ...) \ + logWrite(LOG_ALL_OBJ, LOG_NONE, format, ##__VA_ARGS__) /** * @brief 日志格式化输出 From ca54e36322e210caa70446004b4b0025c41b5675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:17:55 +0800 Subject: [PATCH 07/12] =?UTF-8?q?feat:=20=E2=9C=A8=20=E6=8F=90=E4=BE=9BAPI?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E6=9F=A5=E8=AF=A2ringbuffer=E7=9A=84?= =?UTF-8?q?=E5=B7=B2=E5=8D=A0=E7=94=A8=E7=A9=BA=E9=97=B4,=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E7=94=B1=E6=AD=A4=E5=87=8F=E5=B0=91=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E5=8D=A0=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/easy_transplant/shell_all.c | 9 +++++++++ demo/easy_transplant/shell_all.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/demo/easy_transplant/shell_all.c b/demo/easy_transplant/shell_all.c index fb3a55d..5a2600b 100644 --- a/demo/easy_transplant/shell_all.c +++ b/demo/easy_transplant/shell_all.c @@ -208,6 +208,15 @@ void port_rx_end(short truely_rx_len) #endif } +int port_tx_available(void) +{ + return ringbuffer_get_used(&rb_tx); +} + +int port_rx_available(void) +{ + return ringbuffer_get_used(&rb_rx); +} //+******************************** shell和log组件初始化,shell任务 ***************************************/ // 锁函数需要在对应的适配文件中实现 // shell 锁实现函数 diff --git a/demo/easy_transplant/shell_all.h b/demo/easy_transplant/shell_all.h index 41bf77a..9cbab7b 100644 --- a/demo/easy_transplant/shell_all.h +++ b/demo/easy_transplant/shell_all.h @@ -47,6 +47,8 @@ extern "C" //+******************************** C scope ***************************************/ +#include "./ringbuffer/ringbuffer.h" // 环形队列 + #include "../../src/shell.h" // shell核心头文件 @@ -73,9 +75,11 @@ extern "C" void port_tx_trigger(void); // 触发发送,定期调用 void port_tx_end(short truely_tx_len); // 实际发送完后一定要调用,发送中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 + int port_tx_available(void); // 获取发送缓冲区已有的数据量 void port_rx_trigger(void); // 触发接收,定期调用 void port_rx_end(short truely_rx_len); // 实际接收完后一定要调用,接收中断中调用(如果有的话),end函数如果传入负数表示使用上次调用时候记录的值 + int port_rx_available(void); // 获取接收缓冲区已有的数据量,可以根据此函数判断是否需要调用shell任务,对于RTOS可以在无数据时释放CPU // 初始化shell和log void letter_shell_init(void); From e7876fbb7098341845d2c14e34973d7c1a7aa055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:41:56 +0800 Subject: [PATCH 08/12] =?UTF-8?q?feat:=20=E2=9C=A8=20llog=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=96=B0=E5=A2=9ElogPrintf=E5=AE=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/log/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/log/log.h b/extensions/log/log.h index ac3fc36..20f4e14 100644 --- a/extensions/log/log.h +++ b/extensions/log/log.h @@ -137,7 +137,7 @@ typedef struct log_def * @param fmt 格式 * @param ... 参数 */ -#define logPrint(format, ...) \ +#define logPrintf(format, ...) \ logWrite(LOG_ALL_OBJ, LOG_NONE, format, ##__VA_ARGS__) /** From 16659b003b66f5f6f126c0c9a9d0c7d0df152cc1 Mon Sep 17 00:00:00 2001 From: magic_overload <59137524+fool-cat@users.noreply.github.com> Date: Sun, 13 Oct 2024 15:47:01 +0800 Subject: [PATCH 09/12] =?UTF-8?q?feat:=20=E2=9C=A8=20=E5=A2=9E=E5=8A=A0she?= =?UTF-8?q?ll=5Fprintf=E4=BB=A3=E6=9B=BF=E6=A0=87=E5=87=86=E5=BA=93?= =?UTF-8?q?=E7=9A=84printf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/easy_transplant/shell_all.c | 14 ++++++++++++++ demo/easy_transplant/shell_all.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/demo/easy_transplant/shell_all.c b/demo/easy_transplant/shell_all.c index 5a2600b..b616f30 100644 --- a/demo/easy_transplant/shell_all.c +++ b/demo/easy_transplant/shell_all.c @@ -294,6 +294,20 @@ void letter_shell_task() #endif } +int shell_printf(const char *format, ...) +{ + int len = 0; + char buf[SHELL_TX_BUFFER_SIZE]; + va_list args; + va_start(args, format); + len = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + + shellWriteEndLine(&user_shell, buf, strlen(buf)); + + return len; +} + //+********************************* 导出一些可能用到的命令或快捷键 **********************************/ static void logChangeLevel() { diff --git a/demo/easy_transplant/shell_all.h b/demo/easy_transplant/shell_all.h index 9cbab7b..f232de4 100644 --- a/demo/easy_transplant/shell_all.h +++ b/demo/easy_transplant/shell_all.h @@ -87,6 +87,9 @@ extern "C" // shell任务 void letter_shell_task(); + // shell尾随printf用于代替标准库的printf + int shell_printf(const char *format, ...); + #ifdef __cplusplus } //+******************************** c++ scope ***************************************/ From 1b6689ce7a3262f5f96ca8939a6832df4c5837b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:55:37 +0800 Subject: [PATCH 10/12] =?UTF-8?q?fix:=20=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=AE=8F=E5=AE=9A=E4=B9=89=E4=BD=BF=E7=94=A8=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 修复了宏定义为枚举导致预编译分支错误问题 2. 完善了keil ac5编译器的支持,目前能正常通过编译无警告 3. 新增了xprintf库的字符串格式化输出,提供了类似标准库的printf --- demo/easy_transplant/readme.md | 8 +- demo/easy_transplant/ringbuffer/ringbuffer.c | 227 ----- demo/easy_transplant/ringbuffer/ringbuffer.h | 330 ++++++- demo/easy_transplant/shell_all.c | 98 ++- demo/easy_transplant/shell_all.h | 8 +- .../stm32_HAL_adapt/stm32_HAL_adapt.c | 8 +- .../stm32_HAL_adapt/stm32_HAL_adapt.h | 22 +- demo/easy_transplant/xprintf/doc/css_e.css | 59 ++ demo/easy_transplant/xprintf/doc/css_j.css | 62 ++ demo/easy_transplant/xprintf/doc/xprintf.html | 214 +++++ .../xprintf/doc/xprintf_j.html | 216 +++++ demo/easy_transplant/xprintf/src/xprintf.c | 807 ++++++++++++++++++ demo/easy_transplant/xprintf/src/xprintf.h | 55 ++ extensions/shell_enhance/shell_passthrough.c | 2 +- extensions/shell_enhance/shell_passthrough.h | 2 +- 15 files changed, 1836 insertions(+), 282 deletions(-) delete mode 100644 demo/easy_transplant/ringbuffer/ringbuffer.c create mode 100644 demo/easy_transplant/xprintf/doc/css_e.css create mode 100644 demo/easy_transplant/xprintf/doc/css_j.css create mode 100644 demo/easy_transplant/xprintf/doc/xprintf.html create mode 100644 demo/easy_transplant/xprintf/doc/xprintf_j.html create mode 100644 demo/easy_transplant/xprintf/src/xprintf.c create mode 100644 demo/easy_transplant/xprintf/src/xprintf.h diff --git a/demo/easy_transplant/readme.md b/demo/easy_transplant/readme.md index 0ce8a8c..5779101 100644 --- a/demo/easy_transplant/readme.md +++ b/demo/easy_transplant/readme.md @@ -2,7 +2,7 @@ 此目录文件为通用 letter-shell 移植的实例,目前仅提供了STM32 HAL库的适配文件 -## 使用(以STM32 HAL库串口1 DMA适配为例)--AC6编译 +## 使用(以STM32 HAL库串口1 DMA适配为例)--AC6编译--AC5编译器已完善支持 在cubemx中开启串口,并且开启串口中断,添加串口的DMA发送和接收,DMA模式选择常规模式------其他时钟,调试接口之类的配置请自行配置 @@ -12,9 +12,9 @@ 此处以keil为例 -1. 将keil编译器切换为AC6,AC5太老了编译又慢,一定要选用AC5导致的编译报错请自行解决 -2. 将此文件夹下shell_all.c和stm32_HAL_adapt文件夹下stm32_HAL_adapt.c添加编译 -3. 将shell根目录下src文件夹和extensions/shell_enhance和shell_all.h所在文件夹添加头文件包含 +~~ 将keil编译器切换为AC6,AC5太老了编译又慢,一定要选用AC5导致的编译报错请自行解决 ~~ 已完善AC5编译器支持 +1. 将此文件夹下shell_all.c和stm32_HAL_adapt文件夹下stm32_HAL_adapt.c添加编译 +2. 将shell根目录下src文件夹和extensions/shell_enhance和shell_all.h所在文件夹添加头文件包含 ![1723216984202](image/readme/1723216984202.png) diff --git a/demo/easy_transplant/ringbuffer/ringbuffer.c b/demo/easy_transplant/ringbuffer/ringbuffer.c deleted file mode 100644 index 02ba04f..0000000 --- a/demo/easy_transplant/ringbuffer/ringbuffer.c +++ /dev/null @@ -1,227 +0,0 @@ -#include "ringbuffer.h" -#include - -#undef USER_ASSERT -#define USER_ASSERT(exp) (void)0 // 开启此宏关闭此文件用户自定义断言 - -// clang-format off -#ifndef USER_ASSERT - #include - #define USER_ASSERT(exp) \ - if (!(exp)) \ - { \ - printf("\"" #exp "\" assert failed at file: %s, line: %d", __FILE__, __LINE__); \ - for (;;) \ - ; \ - } -#endif // ! USER_ASSERT -// clang-format on - -void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - rb->buffer = buffer; - rb->buffer_size = size; - rb->busy = false; - - ringbuffer_reset(rb); -} - -void ringbuffer_reset(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - rb->head = 0; - rb->tail = 0; - rb->data_count = 0; -} - -uint16_t ringbuffer_get_free(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->buffer_size - rb->data_count; -} - -uint16_t ringbuffer_get_used(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->data_count; -} - -uint16_t ringbuffer_get_size(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->buffer_size; -} - -uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->last_series_count; -} - -uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - uint16_t free_size = ringbuffer_get_free(rb); - - if (size > free_size) - { - size = free_size; // 多余的数据不写入(丢掉) - } - - // 判断超过尾部没有 - if (rb->tail + size > rb->buffer_size) - { - uint16_t first_size = rb->buffer_size - rb->tail; - memcpy((uint8_t *)(rb->buffer) + rb->tail, data, first_size); - memcpy(rb->buffer, data + first_size, size - first_size); - } - else - { - memcpy((uint8_t *)(rb->buffer) + rb->tail, data, size); - } - - // 限制尾部位置 - if (rb->tail + size >= rb->buffer_size) - { - rb->tail = size - (rb->buffer_size - rb->tail); - } - else - { - rb->tail += size; - } - - rb->data_count += size; - - return size; -} - -uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - uint16_t used_size = ringbuffer_get_used(rb); - - if (size > used_size) - { - size = used_size; // 读取的数据超过了已有数据量 - } - - // 判断超过尾部没有 - if (rb->head + size > rb->buffer_size) - { - uint16_t first_size = rb->buffer_size - rb->head; - memcpy(data, (uint8_t *)(rb->buffer) + rb->head, first_size); - memcpy(data + first_size, rb->buffer, size - first_size); - } - else - { - memcpy(data, (uint8_t *)(rb->buffer) + rb->head, size); - } - - // 限制头部位置 - if (rb->head + size >= rb->buffer_size) - { - rb->head = size - (rb->buffer_size - rb->head); - } - else - { - rb->head += size; - } - - rb->data_count -= size; - - return size; -} - -uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size) -{ - USER_ASSERT(rb != NULL); - USER_ASSERT(size != NULL); - uint16_t max_size = ringbuffer_get_free(rb); - - if (max_size + rb->tail > rb->buffer_size) - { - max_size = rb->buffer_size - rb->tail; - } - - *size = max_size; - rb->last_series_count = max_size; - - return (uint8_t *)(rb->buffer) + rb->tail; -} - -uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size) -{ - USER_ASSERT(rb != NULL); - USER_ASSERT(size != NULL); - uint16_t max_size = ringbuffer_get_used(rb); - - if (max_size + rb->head > rb->buffer_size) - { - max_size = rb->buffer_size - rb->head; - } - - *size = max_size; - rb->last_series_count = max_size; - - return (uint8_t *)(rb->buffer) + rb->head; -} - -uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - // 限制尾部位置 - if (rb->tail + size >= rb->buffer_size) - { - rb->tail = size - (rb->buffer_size - rb->tail); - } - else - { - rb->tail += size; - } - - rb->data_count += size; - - return size; -} - -uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size) -{ - USER_ASSERT(rb != NULL); - - // 限制头部位置 - if (rb->head + size >= rb->buffer_size) - { - rb->head = size - (rb->buffer_size - rb->head); - } - else - { - rb->head += size; - } - - rb->data_count -= size; - - return size; -} - -void ringbuffer_mark_busy(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - rb->busy = true; -} - -void ringbuffer_mark_idle(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - rb->busy = false; -} - -bool ringbuffer_is_busy(ringbuffer_t *rb) -{ - USER_ASSERT(rb != NULL); - return rb->busy; -} diff --git a/demo/easy_transplant/ringbuffer/ringbuffer.h b/demo/easy_transplant/ringbuffer/ringbuffer.h index c79d2d2..88ceef0 100644 --- a/demo/easy_transplant/ringbuffer/ringbuffer.h +++ b/demo/easy_transplant/ringbuffer/ringbuffer.h @@ -2,7 +2,7 @@ * @file ringbuffer.h * @author 独霸一方 (2696652257@qq.com) * @brief //> 部分参考cherryRB实现的环形缓冲区,完整实现参考:https://github.com/cherry-embedded/CherryRB - * 源码直接加入shell_all.c中进行编译,无需再次添加此目录下.c文件进行编译 + * 这里的API调用不进行加锁,请自行保证线程安全 * @version 1.0 * @date 2024-08-05 * @@ -18,44 +18,330 @@ #include #include +#include + +#undef RINGBUFFER_ASSERT +#define RINGBUFFER_ASSERT(exp) (void)0 // 开启此宏关闭此文件用户自定义断言 + +// clang-format off +#ifndef RINGBUFFER_ASSERT + #include + #define RINGBUFFER_ASSERT(exp) \ + if (!(exp)) \ + { \ + printf("\"" #exp "\" assert failed at file: %s, line: %d", __FILE__, __LINE__); \ + for (;;) \ + ; \ + } +#endif // ! RINGBUFFER_ASSERT +// clang-format on + // > C/C++兼容性宏定义 #ifdef __cplusplus extern "C" { #endif + typedef uint16_t ring_size_t; + typedef struct __ringbuffer_t ringbuffer_t; struct __ringbuffer_t { bool busy; // 用于指示'慢速'外设是否正在操作缓冲区,比如DMA传输 - uint16_t head; - uint16_t tail; - uint16_t data_count; // 当前队列中的数据量 - uint16_t last_series_count; // 调用连续读或写时候实际设置的值 - uint16_t buffer_size; // 缓冲区大小 + ring_size_t head; + ring_size_t tail; + ring_size_t data_count; // 当前队列中的数据量 + ring_size_t last_series_count; // 调用连续读或写时候实际设置的值 + ring_size_t buffer_size; // 缓冲区大小 uint8_t *buffer; }; - void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, uint16_t size); - void ringbuffer_reset(ringbuffer_t *rb); + static inline void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, ring_size_t size); + static inline void ringbuffer_reset(ringbuffer_t *rb); + + static inline ring_size_t ringbuffer_get_free(ringbuffer_t *rb); // 获取剩余空间 + static inline ring_size_t ringbuffer_get_used(ringbuffer_t *rb); // 获取已使用空间 + static inline ring_size_t ringbuffer_get_size(ringbuffer_t *rb); // 获取缓冲区大小 + static inline ring_size_t ringbuffer_get_last_series_size(ringbuffer_t *rb); // 获取上次调用线性读取或者写入时候的设置的大小 - uint16_t ringbuffer_get_free(ringbuffer_t *rb); // 获取剩余空间 - uint16_t ringbuffer_get_used(ringbuffer_t *rb); // 获取已使用空间 - uint16_t ringbuffer_get_size(ringbuffer_t *rb); // 获取缓冲区大小 - uint16_t ringbuffer_get_last_series_size(ringbuffer_t *rb); // 获取上次调用线性读取或者写入时候的设置的大小 + static inline ring_size_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, ring_size_t size); // 返回实际写入的数据量 + static inline ring_size_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, ring_size_t size); // 返回实际读取的数据量 - uint16_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, uint16_t size); // 返回实际写入的数据量 - uint16_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, uint16_t size); // 返回实际读取的数据量 + static inline bool ringbuffer_write_byte(ringbuffer_t *rb, uint8_t data); // 返回是否写入成功 + static inline bool ringbuffer_read_byte(ringbuffer_t *rb, uint8_t *data); // 返回是否读取成功 // for linear read/write operation(such as DMA) - extern uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, uint16_t *size); // 返回写入的地址并设置实际能写入的数据量 - extern uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, uint16_t *size); // 返回读取的地址并设置实际能读取的数据量 - extern uint16_t ringbuffer_linear_write_done(ringbuffer_t *rb, uint16_t size); // 返回实际写入的数据量 - extern uint16_t ringbuffer_linear_read_done(ringbuffer_t *rb, uint16_t size); // 返回实际读取的数据量 - - void ringbuffer_mark_busy(ringbuffer_t *rb); - void ringbuffer_mark_idle(ringbuffer_t *rb); - bool ringbuffer_is_busy(ringbuffer_t *rb); + static inline uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, ring_size_t *size); // 返回写入的地址并设置实际能写入的数据量 + static inline uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, ring_size_t *size); // 返回读取的地址并设置实际能读取的数据量 + static inline ring_size_t ringbuffer_linear_write_done(ringbuffer_t *rb, ring_size_t size); // 返回实际写入的数据量 + static inline ring_size_t ringbuffer_linear_read_done(ringbuffer_t *rb, ring_size_t size); // 返回实际读取的数据量 + + static inline void ringbuffer_mark_busy(ringbuffer_t *rb); // 标记慢速外设正在操作缓冲区 + static inline void ringbuffer_mark_idle(ringbuffer_t *rb); // 标记慢速外设操作缓冲区结束 + static inline bool ringbuffer_is_busy(ringbuffer_t *rb); // 返回慢速外设是否正在操作缓冲区 + + //+********************************* 函数实现 **********************************/ + + static inline void ringbuffer_init(ringbuffer_t *rb, uint8_t *buffer, ring_size_t size) + { + RINGBUFFER_ASSERT(rb != NULL); + + rb->buffer = buffer; + rb->buffer_size = size; + rb->busy = false; + + ringbuffer_reset(rb); + } + + static inline void ringbuffer_reset(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + rb->head = 0; + rb->tail = 0; + rb->data_count = 0; + } + + static inline ring_size_t ringbuffer_get_free(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + return rb->buffer_size - rb->data_count; + } + + static inline ring_size_t ringbuffer_get_used(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + return rb->data_count; + } + + static inline ring_size_t ringbuffer_get_size(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + return rb->buffer_size; + } + + static inline ring_size_t ringbuffer_get_last_series_size(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + return rb->last_series_count; + } + + static inline ring_size_t ringbuffer_write(ringbuffer_t *rb, const uint8_t *data, ring_size_t size) + { + RINGBUFFER_ASSERT(rb != NULL); + + ring_size_t free_size = ringbuffer_get_free(rb); + + if (size > free_size) + { + size = free_size; // 多余的数据不写入(丢掉) + } + + // 判断超过尾部没有 + if (rb->tail + size > rb->buffer_size) + { + ring_size_t first_size = rb->buffer_size - rb->tail; + memcpy((uint8_t *)(rb->buffer) + rb->tail, data, first_size); + memcpy(rb->buffer, data + first_size, size - first_size); + } + else + { + memcpy((uint8_t *)(rb->buffer) + rb->tail, data, size); + } + + // 限制尾部位置 + if (rb->tail + size >= rb->buffer_size) + { + rb->tail = size - (rb->buffer_size - rb->tail); + } + else + { + rb->tail += size; + } + + rb->data_count += size; + + return size; + } + + static inline ring_size_t ringbuffer_read(ringbuffer_t *rb, uint8_t *data, ring_size_t size) + { + RINGBUFFER_ASSERT(rb != NULL); + + ring_size_t used_size = ringbuffer_get_used(rb); + + if (size > used_size) + { + size = used_size; // 读取的数据超过了已有数据量 + } + + // 判断超过尾部没有 + if (rb->head + size > rb->buffer_size) + { + ring_size_t first_size = rb->buffer_size - rb->head; + memcpy(data, (uint8_t *)(rb->buffer) + rb->head, first_size); + memcpy(data + first_size, rb->buffer, size - first_size); + } + else + { + memcpy(data, (uint8_t *)(rb->buffer) + rb->head, size); + } + + // 限制头部位置 + if (rb->head + size >= rb->buffer_size) + { + rb->head = size - (rb->buffer_size - rb->head); + } + else + { + rb->head += size; + } + + rb->data_count -= size; + + return size; + } + + static inline bool ringbuffer_write_byte(ringbuffer_t *rb, uint8_t data) + { + RINGBUFFER_ASSERT(rb != NULL); + + if (ringbuffer_get_free(rb) == 0) + { + return false; + } + + *((uint8_t *)(rb->buffer) + rb->tail) = data; + + // 限制尾部位置 + if (rb->tail + 1 >= rb->buffer_size) + { + rb->tail = 0; + } + else + { + rb->tail++; + } + + rb->data_count++; + + return true; + } + + static inline bool ringbuffer_read_byte(ringbuffer_t *rb, uint8_t *data) + { + RINGBUFFER_ASSERT(rb != NULL); + + if (ringbuffer_get_used(rb) == 0) + { + return false; + } + + *data = *((uint8_t *)(rb->buffer) + rb->head); + + // 限制头部位置 + if (rb->head + 1 >= rb->buffer_size) + { + rb->head = 0; + } + else + { + rb->head++; + } + + rb->data_count--; + + return true; + } + + static inline uint8_t *ringbuffer_linear_write_setup(ringbuffer_t *rb, ring_size_t *size) + { + RINGBUFFER_ASSERT(rb != NULL); + RINGBUFFER_ASSERT(size != NULL); + ring_size_t max_size = ringbuffer_get_free(rb); + + if (max_size + rb->tail > rb->buffer_size) + { + max_size = rb->buffer_size - rb->tail; + } + + *size = max_size; + rb->last_series_count = max_size; + + return (uint8_t *)(rb->buffer) + rb->tail; + } + + static inline uint8_t *ringbuffer_linear_read_setup(ringbuffer_t *rb, ring_size_t *size) + { + RINGBUFFER_ASSERT(rb != NULL); + RINGBUFFER_ASSERT(size != NULL); + ring_size_t max_size = ringbuffer_get_used(rb); + + if (max_size + rb->head > rb->buffer_size) + { + max_size = rb->buffer_size - rb->head; + } + + *size = max_size; + rb->last_series_count = max_size; + + return (uint8_t *)(rb->buffer) + rb->head; + } + + static inline ring_size_t ringbuffer_linear_write_done(ringbuffer_t *rb, ring_size_t size) + { + RINGBUFFER_ASSERT(rb != NULL); + + // 限制尾部位置 + if (rb->tail + size >= rb->buffer_size) + { + rb->tail = size - (rb->buffer_size - rb->tail); + } + else + { + rb->tail += size; + } + + rb->data_count += size; + + return size; + } + + static inline ring_size_t ringbuffer_linear_read_done(ringbuffer_t *rb, ring_size_t size) + { + RINGBUFFER_ASSERT(rb != NULL); + + // 限制头部位置 + if (rb->head + size >= rb->buffer_size) + { + rb->head = size - (rb->buffer_size - rb->head); + } + else + { + rb->head += size; + } + + rb->data_count -= size; + + return size; + } + + static inline void ringbuffer_mark_busy(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + rb->busy = true; + } + + static inline void ringbuffer_mark_idle(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + rb->busy = false; + } + + static inline bool ringbuffer_is_busy(ringbuffer_t *rb) + { + RINGBUFFER_ASSERT(rb != NULL); + return rb->busy; + } #ifdef __cplusplus } diff --git a/demo/easy_transplant/shell_all.c b/demo/easy_transplant/shell_all.c index b616f30..85a0453 100644 --- a/demo/easy_transplant/shell_all.c +++ b/demo/easy_transplant/shell_all.c @@ -7,8 +7,6 @@ #if 1 -#include "./ringbuffer/ringbuffer.c" // 环形队列 - // shell核心实现包含 #include "../../src/shell.c" #include "../../src/shell_ext.c" @@ -59,6 +57,22 @@ static ringbuffer_t rb_tx; #define SHELL_WRITE_CAN_BLOCK() (false) #endif // !SHELL_WRITE_CAN_BLOCK +#undef USER_ASSERT +#define USER_ASSERT(exp) (void)0 // 开启此宏关闭此文件用户自定义断言 + +// clang-format off +#ifndef USER_ASSERT + #include + #define USER_ASSERT(exp) \ + if (!(exp)) \ + { \ + printf("\"" #exp "\" assert failed at file: %s, line: %d", __FILE__, __LINE__); \ + for (;;) \ + ; \ + } +#endif // ! USER_ASSERT +// clang-format on + //+********************************* shell读写对接 **********************************/ short write_to_ringbuffer(char *data, unsigned short len) @@ -227,7 +241,7 @@ extern void shell_unlock(struct shell_def *shell); extern void log_lock(struct log_def *log); extern void log_unlock(struct log_def *log); -extern void user_init_before_shell(); +extern void user_init_before_shell(void); void letter_shell_init(void) { @@ -272,7 +286,7 @@ void letter_shell_init(void) logRegister(&user_log, &user_shell); // 注册log } -void letter_shell_task() +void letter_shell_task(void) { #if SHELL_TASK_WHILE == 1 for (;;) @@ -294,19 +308,87 @@ void letter_shell_task() #endif } +#if USE_SHELL_PRINTF +#include "./xprintf/src/xprintf.c" + +static volatile int _byte_count = 0; + +static inline void output_byte_buffer(int ch) +{ + if (ringbuffer_write_byte(&rb_tx, (uint8_t)ch)) + { + _byte_count++; + } +} + int shell_printf(const char *format, ...) { + // int len = 0; + // char buf[SHELL_TX_BUFFER_SIZE]; + // va_list args; + // va_start(args, format); + // len = vsnprintf(buf, sizeof(buf), format, args); + // va_end(args); + + // xfprintf + int len = 0; - char buf[SHELL_TX_BUFFER_SIZE]; + + Shell *shell = &user_shell; + +#if SHELL_SUPPORT_END_LINE == 1 + + // shellWriteEndLine(&user_shell, buf, strlen(buf)); + SHELL_LOCK(shell); + if (!shell->status.isActive) + { + shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_LINE]); + } + + _byte_count = 0; + va_list args; va_start(args, format); - len = vsnprintf(buf, sizeof(buf), format, args); + xvfprintf(output_byte_buffer, format, args); va_end(args); - shellWriteEndLine(&user_shell, buf, strlen(buf)); + len = _byte_count; + + if (!shell->status.isActive) + { + shellWritePrompt(shell, 0); + if (shell->parser.length > 0) + { + shellWriteString(shell, shell->parser.buffer); + for (short i = 0; i < shell->parser.length - shell->parser.cursor; i++) + { + shellWriteByte(shell, '\b'); + } + } + } + + SHELL_UNLOCK(shell); + +#else + + SHELL_LOCK(shell); + + _byte_count = 0; + + va_list args; + va_start(args, format); + xvfprintf(output_byte_buffer, format, args); + va_end(args); + + len = _byte_count; + + SHELL_UNLOCK(shell); + +#endif return len; } +#endif //+********************************* 导出一些可能用到的命令或快捷键 **********************************/ static void logChangeLevel() @@ -354,4 +436,4 @@ static void logChangeLevel() } //> 0x04000000对应的应该是鼠标中键,但是在Xshell中,按下鼠标中间会以字符串的形式发送04000000,导致无法触发,现在修改为 ~ 的按键值 // SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x04000000, logChangeLevel, switch log level); -SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x60000000, logChangeLevel, '~' switch log level); \ No newline at end of file +SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x60000000, logChangeLevel, '~' switch log level); diff --git a/demo/easy_transplant/shell_all.h b/demo/easy_transplant/shell_all.h index f232de4..70f9a7f 100644 --- a/demo/easy_transplant/shell_all.h +++ b/demo/easy_transplant/shell_all.h @@ -85,10 +85,14 @@ extern "C" void letter_shell_init(void); // shell任务 - void letter_shell_task(); + void letter_shell_task(void); - // shell尾随printf用于代替标准库的printf +#define USE_SHELL_PRINTF 1 +#if USE_SHELL_PRINTF + // shell尾随printf用于代替标准库的printf,shell_printf使用xprintf的格式化输出,以源码形式添加编译 int shell_printf(const char *format, ...); +#define SHELL_PRINTF +#endif #ifdef __cplusplus } diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c index a2a3191..5e09f64 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c @@ -80,9 +80,9 @@ void log_unlock(struct log_def *log) } // shell使用的硬件初始化,使用cubemx开启串口,然后使能对应的串口中断,DMA发送与接收中断 -void user_init_before_shell() +void user_init_before_shell(void) { - // 由于初始化已经由CUBEMX处理好了,这里什么都不需要做,建议开启DMA半满中断(默认开启) + // 由于初始化已经由CUBEMX处理好了,这里什么都不需要做 #if (RTOS_MODE == RTOS_FREERTOS) _shell_mutex = xSemaphoreCreateMutex(); @@ -167,7 +167,7 @@ int date() shellWriteString(shell, str); // 换算为天`时`分`秒`毫秒 - snprintf(str, sizeof(str), "current time: %lld天 %02lld时 %02lld分 %02lld秒 %03lld毫秒\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); + snprintf(str, sizeof(str), "current time: %lld day %02lld hour %02lld min %02lld sec %03lld ms\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); shellWriteString(shell, str); #if SHELL_USING_LOCK == 1 @@ -178,4 +178,4 @@ int date() } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), date, date, current time); -#endif \ No newline at end of file +#endif diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h index 88eb794..7bf7207 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h @@ -17,21 +17,17 @@ #include "usart.h" // 接收发送方式,不使用阻塞式发送接收,有RTOS可以考虑阻塞发送(可以但没必要),发送和接收的方式是可以组合使用的需自行更改 -enum PLATFORM_MODE_t -{ - PLATFORM_MODE_DMA = 0, - PLATFORM_MODE_IT, - PLATFORM_MODE_POLL -}; +#define PLATFORM_MODE_DMA 0 // DMA发送与接收 +#define PLATFORM_MODE_IT 1 // 单字节中断发送与接收 +#define PLATFORM_MODE_POLL 2 // 轮询发送与接收 + // 使用DMA发送与接收 #define PLATFORM_MODE PLATFORM_MODE_DMA -enum RTOS_TYPE_t -{ - RTOS_NONE = 0, // 无操作系统 - RTOS_FREERTOS, // FreeRTOS - // ... 其他操作系统 -}; +#define RTOS_NONE 0 // 无操作系统 +#define RTOS_FREERTOS 1 // FreeRTOS +// ... 其他操作系统 + // 定义使用的操作系统 #define RTOS_MODE RTOS_NONE @@ -52,7 +48,7 @@ enum RTOS_TYPE_t #define SHELL_ATOMIC_ENTER() __disable_irq() #define SHELL_ATOMIC_EXIT() __enable_irq() -#define SHELL_UART_ADDR (&huart1) +#define SHELL_UART_ADDR (&huart2) // clang-format off #if (PLATFORM_MODE == PLATFORM_MODE_DMA) diff --git a/demo/easy_transplant/xprintf/doc/css_e.css b/demo/easy_transplant/xprintf/doc/css_e.css new file mode 100644 index 0000000..64664b1 --- /dev/null +++ b/demo/easy_transplant/xprintf/doc/css_e.css @@ -0,0 +1,59 @@ +* {margin: 0; padding: 0; border-width: 0;} +body {margin: 8px; background-color: #e0ffff; font-color: black; font-family: serif; line-height: 133%; max-width: 1024px;} +a:link {color: blue;} +a:visited {color: darkmagenta;} +a:hover {background-color: #a0ffff;} +a:active {color: darkmagenta; overflow: hidden; outline:none; position: relative; top: 1px; left: 1px;} +abbr {border-width: 1px;} + +p {margin: 0 0 0.3em 1em;} +em {font-style: normal; font-weight: bold; margin: 0 0.1em;} +strong {} +pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; font-size: 85%; font-family: "Consolas", "Courier New", monospace; background-color: white;} +pre span.c {color: green;}, +pre span.k {color: blue;} +tt {margin: 0 0.2em; font-size: 85%; font-family: "Consolas", "Courier New", monospace; } +ol {margin: 0 2.5em;} +ul {margin: 0 2em;} +dl {margin: 0 1em;} +dt {font-size: 85%; font-family: "Consolas", "Courier New", monospace;} +dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; } +dl.ret dt {margin: 0.5em 0 0 0 ; } +dd {margin: 0 2em;} +hr {border-width: 1px; margin: 1em;} +div.abst {font-family: sans-serif;} +div.para {clear: both; font-family: serif;} +div.ret a {font-size: 85%; font-family: "Consolas", "Courier New", monospace; } +.equ {text-indent: 0; margin: 1em 2em 1em;} +.indent {margin-left: 2em;} +.rset {float: right; margin: 0 0 0.5em 0.5em;} +.lset {float: left; margin: 0 0.5em 0.5em 0.5em;} +ul.flat li {list-style-type: none; margin: 0;} +a.imglnk img {border: 1px solid;} +.iequ {white-space: nowrap; font-weight: bold;} +.clr {clear: both;} +.arg {font-style: italic;} +.it {font-style: italic;} +.mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap} + +h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;} +p.hdd {float: right; text-align: right; margin-top: 0.5em;} +hr.hds {clear: both; margin-bottom: 1em;} + +h2 {font-size: 2em; font-family: sans-serif; background-color: #d8d8FF; padding: 0.5em 0.5em; margin: 0 0 0.5em;} +h3 {font-size: 1.5em; font-family: sans-serif; margin: 1.5em 0 0.5em;} +h4 {font-size: 1.2em; font-family: sans-serif; margin: 1em 0 0.2em;} +h5 {font-size: 1em; font-family: sans-serif; margin: 0.5em 0 0em;} +small {font-size: 80%;} +.indent {margin-left: 2em;} + +/* Tables */ +table {margin: 0.5em 1em; border-collapse: collapse; border: 2px solid black; } +th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: black; padding: 0 3px; vertical-align: top; white-space: nowrap;} +td {background-color: white; border: 1px solid black; padding: 0 3px; vertical-align: top; line-height: 1.3em;} +table.lst td:first-child {font-size: 85%; font-family: "Consolas", "Courier New", monospace;} +table.lst2 td {font-size: 85%; font-family: "Consolas", "Courier New", monospace;} +table caption {font-family: sans-serif; font-weight: bold;} +tr.lst3 td { border-width: 2px 1px 1px; } + +p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;} diff --git a/demo/easy_transplant/xprintf/doc/css_j.css b/demo/easy_transplant/xprintf/doc/css_j.css new file mode 100644 index 0000000..ec3f9db --- /dev/null +++ b/demo/easy_transplant/xprintf/doc/css_j.css @@ -0,0 +1,62 @@ +@charset "Shift_JIS"; +/* Common style sheet for Tech Notes */ + +* {margin: 0; padding: 0; border-width: 0;} +body {margin: 8px; background-color: #e0ffff; font-color: black; font-family:"lr o", serif; line-height: 150%; letter-spacing: 1px; max-width: 1024px;} +a:link {color: blue;} +a:visited {color: darkmagenta;} +a:hover {background-color: #a0ffff;} +a:active {color: darkmagenta; overflow: hidden; outline:none; position: relative; top: 1px; left: 1px;} +abbr {border-width: 1px;} + +p {text-indent: 1em; margin: 0 0 0.3em 0.5em;} +em {font-style: normal; font-weight: bold; margin: 0 0.1em;} +strong {} +pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; letter-spacing: 0; font-size: 85%; font-family: "Consolas", "Courier New", "lr SVbN", monospace; background-color: white;} +pre span.c {color: green;} +pre span.k {color: blue;} +tt {margin: 0 0.2em; letter-spacing: 0; font-size: 85%; font-family: "Consolas", "Courier New", "lr SVbN", monospace;} +ol {margin: 0 2.5em;} +ul {margin: 0 2em;} +dl {margin: 0 1em;} +dt {font-size: 85%; font-family: "Consolas", "Courier New", "lr SVbN", monospace;} +dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; letter-spacing: 0;} +dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 85%; font-family: "Consolas", "Courier New", "lr SVbN", monospace; letter-spacing: 0; } +dd {margin: 0 2em;} +hr {border-width: 1px; margin: 1em;} +div.abst {font-family: "lr oSVbN",sans-serif;} +div.para {clear: both; font-family: "lr o",serif;} +div.ret a {font-size: 85%; font-family: "Consolas", "Courier New", "lr SVbN", monospace; } +.equ {text-indent: 0; margin: 1em 2em 1em;} +.indent {margin-left: 2em;} +.rset {float: right; margin: 0 0 0.5em 0.5em;} +.lset {float: left; margin: 0 0.5em 0.5em 0.5em;} +ul.flat li {list-style-type: none; margin: 0;} +a.imglnk img {border: 1px solid;} +.iequ {white-space: nowrap; font-weight: bold;} +.clr {clear: both;} +.arg {font-style: italic;} +.it {font-style: italic;} +.mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap} + +h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;} +p.hdd {float: right; text-align: right; margin-top: 0.5em;} +hr.hds {clear: both; margin-bottom: 1em;} + +h2 {font-size: 2em; font-family: "lr oSVbN",sans-serif; background-color: #d8d8FF; padding: 0.5em 0.5em; margin: 0 0 0.5em;} +h3 {font-size: 1.5em; font-family: "lr oSVbN",sans-serif; margin: 1.5em 0 0.5em;} +h4 {font-size: 1.2em; font-family: "lr oSVbN",sans-serif; margin: 1em 0 0.2em;} +h5 {font-size: 1em; font-family: "lr oSVbN",sans-serif; margin: 0.5em 0 0em;} +small {font-size: 80%;} +.indent {margin-left: 2em;} + +/* Tables */ +table {margin: 0.5em 1em; border-collapse: collapse; border: 2px solid black; letter-spacing: 0;} +th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: black; padding: 0 3px; vertical-align: top;} +td {background-color: white; border: 1px solid black; padding: 0 3px; vertical-align: top; line-height: 1.3em;} +table.lst td:first-child {font-size: 85%; font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} +table.lst2 td {font-size: 85%; font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} +table caption {font-family: sans-serif; font-weight: bold;} +tr.lst3 td {border-width: 2px 1px 1px; } + +p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;} diff --git a/demo/easy_transplant/xprintf/doc/xprintf.html b/demo/easy_transplant/xprintf/doc/xprintf.html new file mode 100644 index 0000000..2144571 --- /dev/null +++ b/demo/easy_transplant/xprintf/doc/xprintf.html @@ -0,0 +1,214 @@ + + + + + + + +ELM - Embedded String Functions + + + +

xprintf - Embedded String Functions

+
+ +
+

xprintf is a compact string I/O library. It is ideal for tiny microcontrollers that has insufficient program memory for regular printf function. The recommended use is: writing formatted strings into LCD or UART and for debug/maintenance console.

+

xprintf can be configured with configuration options to reduce the module size. Following table shows the example of code size in Cortex-M3 (gcc -Os). long long and float want C99 or later.

+ + + + + + +
Feature.text
Basic output789
long long integer+91
Floating point+1027
Input+238
+
+ +
+

Application Interface

+

The Embedded String Functions provides following functions.

+

Output

+
+/*----------------------------------------------/
+/  xputc - Put a character
+/----------------------------------------------*/
+
+void xputc (
+    int chr           /* A character to be output (0-255) */
+);
+
+void xfputc (
+    void(*func)(int), /* Pointer to the output function */
+    int chr           /* Character to be output (0-255) */
+);
+
+
+/*----------------------------------------------/
+/  xputs - Put a null-terminated string
+/----------------------------------------------*/
+
+void xputs (
+    const char* str   /* Pointer to the null-terminated string to be output */
+);
+
+void xfputs (
+    void(*func)(int), /* Pointer to the output function */
+    const char* str   /* Pointer to the null-terminated string to be output */
+);
+
+
+/*----------------------------------------------/
+/  xprintf - Formatted string output
+/----------------------------------------------*/
+
+void xprintf (        /* Put a formatted string to the default device */
+    const char* fmt,  /* Pointer to the null-terminated format string */
+    ...               /* Optional arguments... */
+);
+
+void xfprintf (       /* Put a formatted string to the specified device */
+    void(*func)(int), /* Pointer to the output function */
+    const char* fmt,  /* Pointer to the null-terminated format string */
+    ...               /* Optional arguments... */
+);
+
+void xsprintf (       /* Put a formatted string to the memory */
+    char* buff,       /* Pointer to the buffer to store output string */
+    const char* fmt,  /* Pointer to the null-terminated format string */
+    ...               /* Optional arguments... */
+);
+
+
+/*----------------------------------------------/
+/  put_dump - Put a line of binary dump
+/----------------------------------------------*/
+
+void put_dump (
+    const void* buff,   /* Pointer to the data to be displayed */
+    unsigned long adr,  /* Heading address */
+    int cnt,            /* Number of items to be displayed */
+    int width           /* Size of item (1, 2 or 4) */
+);
+
+

+The format control directive is a sub-set of standard library shown as follows: +

+
+    %[flag][width][precision][size]type
+
+
+
flag
Padding options. A - specifies left-aligned. A 0 specifies zero padded. The default setting is in right-aligned and space padded.
+
width
Minimum width of the field, 1-99 or *. If the width of generated string is less than the specified value, rest field is padded with spaces or zeros. An * specifies the value comes from an argument in int type.
+
precision
Specifies number of fractional digits or maximum width of string, .0-.99 or .*. If number is omitted, it will be same as .0. Default setting is 6 for number and no limit for string.
+
size
Specifies size of integer argument, l(long) and ll(long long). If sizeof (long) == sizeof (int) is true (this is typical of 32-bit systems), prefix l can be omitted for long integer argument. The default size is int for integer arrument and floating point argument is always assumed double.
+
type
Specifies type of the output format and the argument as shown below. The length of generated string is in assumtion of int is 32-bit. + + + + + + + + + + + +
TypeFormatArgumentLength
dSigned decimalint,
long,
long long
1 to 11 (20 for ll) characters.
uUnsigned decimal1 to 10 (20 for ll) characters.
oUnsigned octal1 to 11 (22 for ll) characters.
x XUnsigned hexdecimal1 to 8 (16 for ll) characters.
bUnsigned binary1 to 32 characters. Limited to lower 32 digits when ll is specified.
cCharacterint1 character.
sStringchar*As input string. If the maximum length of input string is unkown, precision should be specified to avoid output buffer overflow. Null pointer generates a null string.
fFloating point
(decimal)
double1 to 31 characters. If the number of characters exceeds 31, it generates "±OV". Not a number and infinite generate "NaN" and "±INF".
e EFloating point
(e notation)
4 to 31 characters. If the number of characters exceeds 31 or exponent exceeds +99, it generates "±OV".
+
+
+
+Examples:
+    xprintf("%d", 1234);             /* "1234" */
+    xprintf("%6d,%3d%%", -200, 5);   /* "  -200,  5%" */
+    xprintf("%-6u", 100);            /* "100   " */
+    xprintf("%ld", 12345678);        /* "12345678" */
+    xprintf("%llu", 0x100000000);    /* "4294967296"   <XF_USE_LLI> */
+    xprintf("%lld", -1LL);           /* "-1"           <XF_USE_LLI> */
+    xprintf("%04x", 0xA3);           /* "00a3" */
+    xprintf("%08lX", 0x123ABC);      /* "00123ABC" */
+    xprintf("%016b", 0x550F);        /* "0101010100001111" */
+    xprintf("%*d", 6, 100);          /* "   100" */
+    xprintf("%s", "abcdefg");        /* "abcdefg" */
+    xprintf("%5s", "abc");           /* "  abc" */
+    xprintf("%-5s", "abc");          /* "abc  " */
+    xprintf("%.5s", "abcdefg");      /* "abcde" */
+    xprintf("%-5.2s", "abcdefg");    /* "ab   " */
+    xprintf("%c", 'a');              /* "a" */
+    xprintf("%12f", 10.0);           /* "   10.000000" <XF_USE_FP> */
+    xprintf("%.4E", 123.45678);      /* "1.2346E+02"   <XF_USE_FP> */
+
+ + + +

Input

+
+/*----------------------------------------------/
+/  xgets - Get a line from the input device
+/----------------------------------------------*/
+
+int xgets (     /* 0:End of stream, 1:A line arrived */
+    char* buff, /* Pointer to the buffer to input */
+    int len     /* Buffer length */
+);
+
+
+/*----------------------------------------------/
+/  xatoi - Get a value of integer string
+/----------------------------------------------*/
+/* "123 -5    0x3ff 0b1111 0377 1.5 "
+       ^                            1st call returns 123 and next ptr
+          ^                         2nd call returns -5 and next ptr
+                   ^                3rd call returns 1023 and next ptr
+                          ^         4th call returns 15 and next ptr
+                               ^    5th call returns 255 and next ptr
+                                 ^  6th call fails and returns 0
+*/
+
+int xatoi (      /* 0:Failed, 1:Succeeded */
+    char** str,  /* Pointer to pointer to the string */
+    long* res    /* Pointer to the valiable to store the value */
+);
+
+
+/*----------------------------------------------/
+/  xatof - Get a value of floating point string
+/----------------------------------------------*/
+/* "123 -5.75 .6   +8.88E+5 1e-6  .  "
+       ^                              1st call returns 1.23e2 and next ptr
+             ^                        2nd call returns -5.75e0 and next ptr
+                ^                     3rd call returns 6e-1 and next ptr
+                           ^          4th call returns 8.88e5 and next ptr
+                                ^     5th call returns 1e-6 and next ptr
+                                   ^  6th call fails and returns 0
+*/
+
+int xatof (      /* 0:Failed, 1:Succeded */
+    char** str,  /* Pointer to pointer to the string */
+    double* res  /* Pointer to the valiable to store the value */
+);
+
+ +
+ + +
+

Device I/O functions

+

The output function is a user provided call-back function to write a byte to the output device. Its address should be set to the function pointer xfunc_output in the module, default output device. Typically, this function puts the byte to UART, LCD or some output device. The output function is called-back from xputc(). There is a macro to set it easy. For example, when attach void uart1_putc (uint8_t chr); to the module, xdev_out(uart1_putc); will do. If the output function has multiple arguments or simple output function is not available, a glue function will be needed. xfputc(), xfputs(), xfprintf() and xsprintf() override the default output device with its argument.

+

The input function is a user provided call-back function to read a byte from the input device. Its address should be set to the function pointer xfunc_input, default input device. There is a macro xdev_in() to set it easy. e.g. xdev_in(uart1_getc); The xfgets() function override the default input device with its argument. The input function is called-back from the xgets() function. Typically, input function reads a byte from input device or file. When the input device reported end of stream, the input function should return -1. The xgets() function aborts with zero and the application will able to detect it.

+
+/* Write a byte to the output dechvice */
+
+void output_func (
+    int chr  /* A byte to be written */
+);
+
+
+/* Read a byte from the input device */
+
+int input_func (void);  /* Returns 0 to 255 as a read character, -1 as EOF */
+
+
+ + + + diff --git a/demo/easy_transplant/xprintf/doc/xprintf_j.html b/demo/easy_transplant/xprintf/doc/xprintf_j.html new file mode 100644 index 0000000..57afdd5 --- /dev/null +++ b/demo/easy_transplant/xprintf/doc/xprintf_j.html @@ -0,0 +1,216 @@ + + + + + + + +ELM - 組み込み用printfモジュール + + + +

xprintf - 組み込み用printfモジュール

+
+ +
+

xprintfは組み込み用に特化したコンパクトなprintfとサポート関数群です。標準入出力関数のサポートされない組み込みシステムにおいて、既存の入出力デバイス(UARTやLCD)に結合することにより、それらに対してprintfで簡単に整形文字列を出力することができます。このため、LCDやUARTなどに手軽に整形出力したいときや、デバッグ・メンテナンス・コンソールなどに有効です。

+

xprintfは構成オプション(xprintf.h内に定義)で必要な機能のみ組み込むことでモジュールサイズを削減することができます。例としてCortex-M3でのコンパイル結果を次の表に示します。(gcc -Os) なお、long longと浮動小数点は、C99を必要とします。

+ + + + + + +
機能.text
基本出力789
long long+91
浮動小数点+1027
入力+238
+
+ + +
+

モジュールAPI

+

組み込み用printfモジュールは、次に示す関数を提供します。

+ +

出力

+
+/*----------------------------------------------/
+/  xputc - 1文字出力
+/----------------------------------------------*/
+
+void xputc (
+    int chr           /* 出力文字(0-255) */
+);
+
+void xfputc (
+    void(*func)(int), /* 出力デバイスの出力関数へのポインタ */
+    int chr           /* 出力する文字(0-255) */
+);
+
+
+/*----------------------------------------------/
+/  xputs - 文字列の出力
+/----------------------------------------------*/
+
+void xputs (
+    const char* str   /* 出力するASCIZ文字列へのポインタ(終端の'\0'は出力されません) */
+);
+
+void xfputs (
+    void(*func)(int), /* 出力デバイスの出力関数へのポインタ */
+    const char* str   /* 出力するASCIZ文字列へのポインタ(終端の'\0'は出力されません) */
+);
+
+
+/*----------------------------------------------/
+/  xprintf - 書式付き文字列出力
+/----------------------------------------------*/
+
+void xprintf (        /* デフォルト出力デバイスへの書式付き文字列出力 */
+    const char* fmt,  /* 書式文字列へのポインタ */
+    ...               /* オプションの引数... */
+);
+
+void xfprintf (       /* 指定出力デバイスへの書式付き文字列出力 */
+    void(*func)(int), /* 出力デバイスの出力関数へのポインタ */
+    const char* fmt,  /* 書式文字列へのポインタ */
+    ...               /* オプションの引数... */
+);
+
+void xsprintf (       /* メモリ上に書式付き文字列(ASCIZ)を出力 */
+    char* buff,       /* 文字列出力バッファへのポインタ */
+    const char* fmt,  /* 書式文字列へのポインタ */
+    ...               /* オプションの引数... */
+);
+
+ +
+/*----------------------------------------------/
+/  put_dump - 1行のバイナリ・ダンプを出力
+/----------------------------------------------*/
+
+void put_dump (
+    const void* buff,   /* 出力する配列へのポインタ */
+    unsigned long adr,  /* 行頭に表示するアドレス値 */
+    int cnt,            /* 出力する要素数 */
+    int width           /* 要素のサイズ (1, 2, 4) */
+);
+
+ +

+書式制御命令は次に示すように標準ライブラリのサブセットとなっています。 +

+
+    %[フラグ][最小幅][精度][サイズ]タイプ
+
+
+
フラグ
生成文字列の幅が最小幅に満たないときのパディング。0はゼロ'0'埋めを指定します。-は左詰めを指定します。デフォルトは、右詰めでスペースでパディングです。
+
最小幅
最小幅の指定。1-99または**は引数(int型)から値を取得します。デフォルト値は0です。
+
精度
浮動小数点数の小数部の桁数または文字列の最大幅を指定します。.0~.99または.*。数値を省略した場合は.0と同じです。デフォルトは、浮動小数点では6桁、文字列では無制限です。
+
サイズ
整数引数のサイズ。l(long)またはll(long long)。デフォルトはintで、sizeof (long) == sizeof (int)の場合(32ビット系の多く)はlを省略できます。浮動小数点引数は常にdoubleとみなされます。
+
タイプ
次の表に示すように引数の型および出力形式を指定します。(生成文字列長はintが32ビットの場合) + + + + + + + + + + + +
タイプフォーマット引数生成文字列長(パディング含まず)
d符号付き10進数int,
long,
long long
1~11(ll指定時は20)文字。
u符号なし10進数1~10(ll指定時は20)文字。
o符号なし8進数1~11(ll指定時は22)文字。
x X符号なし16進数1~8(ll指定時は16)文字。
b符号なし2進数1~32(ll指定時も下位32桁まで)文字。
cキャラクタint1文字。
s文字列char*xsprintfで入力文字列長が不明のときは適切な最大幅を指定すること。
ヌルポインタは文字列長0と見なされる。
f浮動小数点
(固定桁)
double1~31文字、文字数が31を越える場合は"±OV"、非数は"NaN", 無限大は"±INF"
e E浮動小数点
(指数)
4~31文字、文字数が31を越える場合や指数が+99を越える場合は"±OV"
+
+
+
+使用例:
+    xprintf("%d", 1234);             /* "1234" */
+    xprintf("%6d,%3d%%", -200, 5);   /* "  -200,  5%" */
+    xprintf("%-6u", 100);            /* "100   " */
+    xprintf("%ld", 12345678);        /* "12345678" */
+    xprintf("%llu", 0x100000000);    /* "4294967296"   <XF_USE_LLI> */
+    xprintf("%lld", -1LL);           /* "-1"           <XF_USE_LLI> */
+    xprintf("%04x", 0xA3);           /* "00a3" */
+    xprintf("%08lX", 0x123ABC);      /* "00123ABC" */
+    xprintf("%016b", 0x550F);        /* "0101010100001111" */
+    xprintf("%*d", 6, 100);          /* "   100" */
+    xprintf("%s", "abcdefg");        /* "abcdefg" */
+    xprintf("%5s", "abc");           /* "  abc" */
+    xprintf("%-5s", "abc");          /* "abc  " */
+    xprintf("%.5s", "abcdefg");      /* "abcde" */
+    xprintf("%-5.2s", "abcdefg");    /* "ab   " */
+    xprintf("%c", 'a');              /* "a" */
+    xprintf("%12f", 10.0);           /* "   10.000000" <XF_USE_FP> */
+    xprintf("%.4E", 123.45678);      /* "1.2346E+02"   <XF_USE_FP> */
+
+ +

入力

+
+/*----------------------------------------------/
+/  xgets - 入力デバイスから1行入力
+/----------------------------------------------*/
+
+int xgets (     /* 結果: 0:EOF, 1:1行確定 */
+    char* buff, /* 入力バッファへのポインタ */
+    int len     /* 入力バッファのサイズ(文字数) */
+);
+
+
+/*----------------------------------------------/
+/  xatoi - 整数文字列の数値を取得
+/----------------------------------------------*/
+/* "123 -5   0x3ff 0b1111 0377 1.5 "
+       ^                           1st call returns 123 and next ptr
+          ^                        2nd call returns -5 and next ptr
+                  ^                3rd call returns 1023 and next ptr
+                         ^         4th call returns 15 and next ptr
+                              ^    5th call returns 255 and next ptr
+                                ^  6th call fails and returns 0
+*/
+
+int xatoi (      /* 0:失敗, 1:成功 */
+    char** str,  /* 対象の文字列を指すポインタへのポインタ */
+    long* res    /* 結果をストアする変数へのポインタ */
+);
+
+
+/*----------------------------------------------/
+/  xatof - 実数文字列の数値を取得
+/----------------------------------------------*/
+/* "123 -5.75 .6   +8.88E+5 1e-6 .  "
+       ^                             1st call returns 1.23e2 and next ptr
+             ^                       2nd call returns -5.75e0 and next ptr
+                ^                    3rd call returns 6e-1 and next ptr
+                           ^         4th call returns 8.88e5 and next ptr
+                                ^    5th call returns 1e-6 and next ptr
+                                  ^  6th call fails and returns 0
+*/
+
+int xatof (      /* 0:失敗, 1:成功 */
+    char** str,  /* 対象の文字列を指すポインタへのポインタ */
+    double* res  /* 結果をストアする変数へのポインタ */
+);
+
+ +
+ + +
+

入出力デバイスとの結合

+

UARTやLCDなどの出力デバイスに結合するには、デフォルト出力デバイスとしてモジュールのグローバル変数xfunc_outputに、そのデバイスの1文字出力関数へのポインタを代入するだけでOKです。これにより、xputc/xputs/xprintf/put_dump関数の出力は指定された関数に渡されます。xfputc/xfputs/xfprintf/xsprintf関数の出力先は、それぞれの引数で直接指定されます。この設定のためマクロも用意されているので、例えば、void uart1_putc (uint8_t chr);に結合する場合、xdev_out(uart1_putc);とすればOKです。出力関数が複数の引数をとる場合や単純な1文字出力が無い場合は、グルー関数を間にかませる必要があるかも知れません。

+

UARTなどの入力デバイスに結合するには、デフォルト入力デバイスとしてモジュールのグローバル変数xfunc_inputに、そのデバイスの1文字読み出し関数へのポインタを代入するだけでOKです。(設定マクロを使用した例:xdev_in(uart1_getc);) xgets関数はデフォルト入力デバイスからライン入力を行います。xfgets関数は入力関数を引数で直接指定します。読みだされた文字は、順にバッファにストアされます。'\r'、'\b'以外の制御文字は無視されます。'\r'が読み出されると読み出しを終了してxgets関数は1を返します。'\r'はバッファにはストアされず、文字列は'\0'で終端されます。通常、入力があるまで読み出し関数は制御を返しませんが、入力デバイスはコンソールに限られるわけではない(ファイルに結合した例もあります)ので、入力ストリームの終端が明確なときは-1を返すべきです。これにより、xgets関数は中断して0を返すので、アプリケーションがストリーム終端を知ることが可能になります。

+
+/* デバイス出力関数の型 */
+
+void output_func (
+    int chr  /* 出力文字(0-255) */
+);
+
+
+/* デバイス入力関数の型 */
+
+int input_func (void);  /* 0-255:読み出した文字, -1:入力ストリームの終端 */
+
+
+ + + + diff --git a/demo/easy_transplant/xprintf/src/xprintf.c b/demo/easy_transplant/xprintf/src/xprintf.c new file mode 100644 index 0000000..c319203 --- /dev/null +++ b/demo/easy_transplant/xprintf/src/xprintf.c @@ -0,0 +1,807 @@ +/*------------------------------------------------------------------------/ +/ Universal String Handler for Console Input and Output +/-------------------------------------------------------------------------/ +/ +/ Copyright (C) 2021, ChaN, all right reserved. +/ +/ xprintf module is an open source software. Redistribution and use of +/ xprintf module in source and binary forms, with or without modification, +/ are permitted provided that the following condition is met: +/ +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/ +/-------------------------------------------------------------------------*/ + +#include "xprintf.h" + +#define SZB_OUTPUT 32 + +#if XF_USE_OUTPUT +#include +void (*xfunc_output)(int); /* Pointer to the default output device */ +static char *strptr; /* Pointer to the output memory (used by xsprintf) */ + +#if XF_USE_FP +/*----------------------------------------------*/ +/* Floating point output */ +/*----------------------------------------------*/ +#include + +static int ilog10(double n) /* Calculate log10(n) in integer output */ +{ + int rv = 0; + + while (n >= 10) + { /* Decimate digit in right shift */ + if (n >= 100000) + { + n /= 100000; + rv += 5; + } + else + { + n /= 10; + rv++; + } + } + while (n < 1) + { /* Decimate digit in left shift */ + if (n < 0.00001) + { + n *= 100000; + rv -= 5; + } + else + { + n *= 10; + rv--; + } + } + return rv; +} + +static double i10x(int n) /* Calculate 10^n */ +{ + double rv = 1; + + while (n > 0) + { /* Left shift */ + if (n >= 5) + { + rv *= 100000; + n -= 5; + } + else + { + rv *= 10; + n--; + } + } + while (n < 0) + { /* Right shift */ + if (n <= -5) + { + rv /= 100000; + n += 5; + } + else + { + rv /= 10; + n++; + } + } + return rv; +} + +static void ftoa( + char *buf, /* Buffer to output the generated string */ + double val, /* Real number to output */ + int prec, /* Number of fractinal digits */ + char fmt /* Notation */ +) +{ + int d; + int e = 0, m = 0; + char sign = 0; + double w; + const char *er = 0; + + if (isnan(val)) + { /* Not a number? */ + er = "NaN"; + } + else + { + if (prec < 0) + prec = 6; /* Default precision (6 fractional digits) */ + if (val < 0) + { /* Nagative value? */ + val = -val; + sign = '-'; + } + else + { + sign = '+'; + } + if (isinf(val)) + { /* Infinite? */ + er = "INF"; + } + else + { + if (fmt == 'f') + { /* Decimal notation? */ + val += i10x(-prec) / 2; /* Round (nearest) */ + m = ilog10(val); + if (m < 0) + m = 0; + if (m + prec + 3 >= SZB_OUTPUT) + er = "OV"; /* Buffer overflow? */ + } + else + { /* E notation */ + if (val != 0) + { /* Not a true zero? */ + val += i10x(ilog10(val) - prec) / 2; /* Round (nearest) */ + e = ilog10(val); + if (e > 99 || prec + 6 >= SZB_OUTPUT) + { /* Buffer overflow or E > +99? */ + er = "OV"; + } + else + { + if (e < -99) + e = -99; + val /= i10x(e); /* Normalize */ + } + } + } + } + if (!er) + { /* Not error condition */ + if (sign == '-') + *buf++ = sign; /* Add a - if negative value */ + do + { /* Put decimal number */ + w = i10x(m); /* Snip the highest digit d */ + d = val / w; + val -= d * w; + if (m == -1) + *buf++ = XF_DPC; /* Insert a decimal separarot if get into fractional part */ + *buf++ = '0' + d; /* Put the digit */ + } while (--m >= -prec); /* Output all digits specified by prec */ + if (fmt != 'f') + { /* Put exponent if needed */ + *buf++ = fmt; + if (e < 0) + { + e = -e; + *buf++ = '-'; + } + else + { + *buf++ = '+'; + } + *buf++ = '0' + e / 10; + *buf++ = '0' + e % 10; + } + } + } + if (er) + { /* Error condition? */ + if (sign) + *buf++ = sign; /* Add sign if needed */ + do + *buf++ = *er++; + while (*er); /* Put error symbol */ + } + *buf = 0; /* Term */ +} +#endif /* XF_USE_FLOAT */ + +/*----------------------------------------------*/ +/* Put a character */ +/*----------------------------------------------*/ + +void xputc( + int chr /* Character to be output */ +) +{ + xfputc(xfunc_output, chr); /* Output it to the default output device */ +} + +void xfputc( /* Put a character to the specified device */ + void (*func)(int), /* Pointer to the output function (null:strptr) */ + int chr /* Character to be output */ +) +{ + if (XF_CRLF && chr == '\n') + xfputc(func, '\r'); /* CR -> CRLF */ + + if (func) + { + func(chr); /* Write a character to the output device */ + } + else if (strptr) + { + *strptr++ = chr; /* Write a character to the memory */ + } +} + +/*----------------------------------------------*/ +/* Put a null-terminated string */ +/*----------------------------------------------*/ + +void xputs( /* Put a string to the default device */ + const char *str /* Pointer to the string */ +) +{ + xfputs(xfunc_output, str); +} + +void xfputs( /* Put a string to the specified device */ + void (*func)(int), /* Pointer to the output function */ + const char *str /* Pointer to the string */ +) +{ + while (*str) + { /* Put the string */ + xfputc(func, *str++); + } +} + +/*----------------------------------------------*/ +/* Formatted string output */ +/*----------------------------------------------*/ +/* xprintf("%d", 1234); "1234" + xprintf("%6d,%3d%%", -200, 5); " -200, 5%" + xprintf("%-6u", 100); "100 " + xprintf("%ld", 12345678); "12345678" + xprintf("%llu", 0x100000000); "4294967296" + xprintf("%lld", -1LL); "-1" + xprintf("%04x", 0xA3); "00a3" + xprintf("%08lX", 0x123ABC); "00123ABC" + xprintf("%016b", 0x550F); "0101010100001111" + xprintf("%*d", 6, 100); " 100" + xprintf("%s", "String"); "String" + xprintf("%5s", "abc"); " abc" + xprintf("%-5s", "abc"); "abc " + xprintf("%-5s", "abcdefg"); "abcdefg" + xprintf("%-5.5s", "abcdefg"); "abcde" + xprintf("%-.5s", "abcdefg"); "abcde" + xprintf("%-5.5s", "abc"); "abc " + xprintf("%c", 'a'); "a" + xprintf("%12f", 10.0); " 10.000000" + xprintf("%.4E", 123.45678); "1.2346E+02" +*/ + +static void xvfprintf( + void (*func)(int), /* Pointer to the output function */ + const char *fmt, /* Pointer to the format string */ + va_list arp /* Pointer to arguments */ +) +{ + unsigned int r, i, j, w, f; + int n, prec; + char str[SZB_OUTPUT], c, d, *p, pad; +#if XF_USE_LLI + long long v; + unsigned long long uv; +#else + long v; + unsigned long uv; +#endif + + for (;;) + { + c = *fmt++; /* Get a format character */ + if (!c) + break; /* End of format? */ + if (c != '%') + { /* Pass it through if not a % sequense */ + xfputc(func, c); + continue; + } + f = w = 0; /* Clear parms */ + pad = ' '; + prec = -1; + c = *fmt++; /* Get first char of the sequense */ + if (c == '0') + { /* Flag: left '0' padded */ + pad = '0'; + c = *fmt++; + } + else + { + if (c == '-') + { /* Flag: left justified */ + f = 2; + c = *fmt++; + } + } + if (c == '*') + { /* Minimum width from an argument */ + n = va_arg(arp, int); + if (n < 0) + { /* Flag: left justified */ + n = 0 - n; + f = 2; + } + w = n; + c = *fmt++; + } + else + { + while (c >= '0' && c <= '9') + { /* Minimum width */ + w = w * 10 + c - '0'; + c = *fmt++; + } + } + if (c == '.') + { /* Precision */ + c = *fmt++; + if (c == '*') + { /* Precision from an argument */ + prec = va_arg(arp, int); + c = *fmt++; + } + else + { + prec = 0; + while (c >= '0' && c <= '9') + { + prec = prec * 10 + c - '0'; + c = *fmt++; + } + } + } + if (c == 'l') + { /* Prefix: Size is long */ + f |= 4; + c = *fmt++; +#if XF_USE_LLI + if (c == 'l') + { /* Prefix: Size is long long */ + f |= 8; + c = *fmt++; + } +#endif + } + if (!c) + break; /* End of format? */ + switch (c) + { /* Type is... */ + case 'b': /* Unsigned binary */ + r = 2; + break; + case 'o': /* Unsigned octal */ + r = 8; + break; + case 'd': /* Signed decimal */ + case 'u': /* Unsigned decimal */ + r = 10; + break; + case 'x': /* Hexdecimal (lower case) */ + case 'X': /* Hexdecimal (upper case) */ + r = 16; + break; + case 'c': /* A character */ + xfputc(func, (char)va_arg(arp, int)); + continue; + case 's': /* String */ + p = va_arg(arp, char *); /* Get a pointer argument */ + if (!p) + p = ""; /* Null ptr generates a null string */ + j = strlen(p); + if (prec >= 0 && j > (unsigned int)prec) + j = prec; /* Limited length of string body */ + for (; !(f & 2) && j < w; j++) + xfputc(func, pad); /* Left pads */ + while (*p && prec--) + xfputc(func, *p++); /* String body */ + while (j++ < w) + xfputc(func, ' '); /* Right pads */ + continue; +#if XF_USE_FP + case 'f': /* Float (decimal) */ + case 'e': /* Float (e) */ + case 'E': /* Float (E) */ + ftoa(p = str, va_arg(arp, double), prec, c); /* Make fp string */ + for (j = strlen(p); !(f & 2) && j < w; j++) + xfputc(func, pad); /* Left pads */ + while (*p) + xfputc(func, *p++); /* Value */ + while (j++ < w) + xfputc(func, ' '); /* Right pads */ + continue; +#endif + default: /* Unknown type (passthrough) */ + xfputc(func, c); + continue; + } + + /* Get an integer argument and put it in numeral */ +#if XF_USE_LLI + if (f & 8) + { /* long long argument? */ + v = (long long)va_arg(arp, long long); + } + else + { + if (f & 4) + { /* long argument? */ + v = (c == 'd') ? (long long)va_arg(arp, long) : (long long)va_arg(arp, unsigned long); + } + else + { /* int/short/char argument */ + v = (c == 'd') ? (long long)va_arg(arp, int) : (long long)va_arg(arp, unsigned int); + } + } +#else + if (f & 4) + { /* long argument? */ + v = (long)va_arg(arp, long); + } + else + { /* int/short/char argument */ + v = (c == 'd') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int); + } +#endif + if (c == 'd' && v < 0) + { /* Negative value? */ + v = 0 - v; + f |= 1; + } + i = 0; + uv = v; + do + { /* Make an integer number string */ + d = (char)(uv % r); + uv /= r; + if (d > 9) + d += (c == 'x') ? 0x27 : 0x07; + str[i++] = d + '0'; + } while (uv != 0 && i < sizeof str); + if (f & 1) + str[i++] = '-'; /* Sign */ + for (j = i; !(f & 2) && j < w; j++) + xfputc(func, pad); /* Left pads */ + do + xfputc(func, str[--i]); + while (i != 0); /* Value */ + while (j++ < w) + xfputc(func, ' '); /* Right pads */ + } +} + +void xprintf( /* Put a formatted string to the default device */ + const char *fmt, /* Pointer to the format string */ + ... /* Optional arguments */ +) +{ + va_list arp; + + va_start(arp, fmt); + xvfprintf(xfunc_output, fmt, arp); + va_end(arp); +} + +void xfprintf( /* Put a formatted string to the specified device */ + void (*func)(int), /* Pointer to the output function */ + const char *fmt, /* Pointer to the format string */ + ... /* Optional arguments */ +) +{ + va_list arp; + + va_start(arp, fmt); + xvfprintf(func, fmt, arp); + va_end(arp); +} + +void xsprintf( /* Put a formatted string to the memory */ + char *buff, /* Pointer to the output buffer */ + const char *fmt, /* Pointer to the format string */ + ... /* Optional arguments */ +) +{ + va_list arp; + + strptr = buff; /* Enable destination for memory */ + va_start(arp, fmt); + xvfprintf(0, fmt, arp); + va_end(arp); + *strptr = 0; /* Terminate output string */ + strptr = 0; /* Disable destination for memory */ +} + +#if XF_USE_DUMP +/*----------------------------------------------*/ +/* Dump a line of binary dump */ +/*----------------------------------------------*/ + +void put_dump( + const void *buff, /* Pointer to the array to be dumped */ + unsigned long addr, /* Heading address value */ + int len, /* Number of items to be dumped */ + size_t width /* Size of buff[0] (1, 2 or 4) */ +) +{ + int i; + const unsigned char *bp; + const unsigned short *sp; + const unsigned long *lp; + + xprintf("%08lX ", addr); /* address */ + + switch (width) + { + case sizeof(char): + bp = buff; + for (i = 0; i < len; i++) + { /* Hexdecimal dump in (char) */ + xprintf(" %02X", bp[i]); + } + xputs(" "); + for (i = 0; i < len; i++) + { /* ASCII dump */ + xputc((unsigned char)((bp[i] >= ' ' && bp[i] <= '~') ? bp[i] : '.')); + } + break; + case sizeof(short): + sp = buff; + do + { /* Hexdecimal dump in (short) */ + xprintf(" %04X", *sp++); + } while (--len); + break; + case sizeof(long): + lp = buff; + do + { /* Hexdecimal dump in (short) */ + xprintf(" %08lX", *lp++); + } while (--len); + break; + } + + xputc('\n'); +} +#endif /* XF_USE_DUMP */ + +#endif /* XF_USE_OUTPUT */ + +#if XF_USE_INPUT +int (*xfunc_input)(void); /* Pointer to the default input stream */ + +/*----------------------------------------------*/ +/* Get a line from the input */ +/*----------------------------------------------*/ + +int xgets( /* 0:End of stream, 1:A line arrived */ + char *buff, /* Pointer to the buffer */ + int len /* Buffer length */ +) +{ + int c, i; + + if (!xfunc_input) + return 0; /* No input function is specified */ + + i = 0; + for (;;) + { + c = xfunc_input(); /* Get a char from the incoming stream */ + if (c < 0 || c == '\r') + break; /* End of stream or CR? */ + if (c == '\b' && i) + { /* BS? */ + i--; + if (XF_INPUT_ECHO) + xputc(c); + continue; + } + if (c >= ' ' && i < len - 1) + { /* Visible chars? */ + buff[i++] = c; + if (XF_INPUT_ECHO) + xputc(c); + } + } + if (XF_INPUT_ECHO) + { + xputc('\r'); + xputc('\n'); + } + buff[i] = 0; /* Terminate with a \0 */ + return (int)(c == '\r'); +} + +/*----------------------------------------------*/ +/* Get a value of integer string */ +/*----------------------------------------------*/ +/* "123 -5 0x3ff 0b1111 0377 w " + ^ 1st call returns 123 and next ptr + ^ 2nd call returns -5 and next ptr + ^ 3rd call returns 1023 and next ptr + ^ 4th call returns 15 and next ptr + ^ 5th call returns 255 and next ptr + ^ 6th call fails and returns 0 +*/ + +int xatoi( /* 0:Failed, 1:Successful */ + char **str, /* Pointer to pointer to the string */ + long *res /* Pointer to the valiable to store the value */ +) +{ + unsigned long val; + unsigned char c, r, s = 0; + + *res = 0; + + while ((c = **str) == ' ') + (*str)++; /* Skip leading spaces */ + + if (c == '-') + { /* negative? */ + s = 1; + c = *(++(*str)); + } + + if (c == '0') + { + c = *(++(*str)); + switch (c) + { + case 'x': /* hexdecimal */ + r = 16; + c = *(++(*str)); + break; + case 'b': /* binary */ + r = 2; + c = *(++(*str)); + break; + default: + if (c <= ' ') + return 1; /* single zero */ + if (c < '0' || c > '9') + return 0; /* invalid char */ + r = 8; /* octal */ + } + } + else + { + if (c < '0' || c > '9') + return 0; /* EOL or invalid char */ + r = 10; /* decimal */ + } + + val = 0; + while (c > ' ') + { + if (c >= 'a') + c -= 0x20; + c -= '0'; + if (c >= 17) + { + c -= 7; + if (c <= 9) + return 0; /* invalid char */ + } + if (c >= r) + return 0; /* invalid char for current radix */ + val = val * r + c; + c = *(++(*str)); + } + if (s) + val = 0 - val; /* apply sign if needed */ + + *res = val; + return 1; +} + +#if XF_USE_FP +/*----------------------------------------------*/ +/* Get a value of the real number string */ +/*----------------------------------------------*/ +/* Float version of xatoi + */ + +int xatof( /* 0:Failed, 1:Successful */ + char **str, /* Pointer to pointer to the string */ + double *res /* Pointer to the valiable to store the value */ +) +{ + double val; + int s, f, e; + unsigned char c; + + *res = 0; + s = f = 0; + + while ((c = **str) == ' ') + (*str)++; /* Skip leading spaces */ + if (c == '-') + { /* Negative? */ + c = *(++(*str)); + s = 1; + } + else if (c == '+') + { /* Positive? */ + c = *(++(*str)); + } + if (c == XF_DPC) + { /* Leading dp? */ + f = -1; /* Start at fractional part */ + c = *(++(*str)); + } + if (c <= ' ') + return 0; /* Wrong termination? */ + val = 0; + while (c > ' ') + { /* Get a value of decimal */ + if (c == XF_DPC) + { /* Embedded dp? */ + if (f < 0) + return 0; /* Wrong dp? */ + f = -1; /* Enter fractional part */ + } + else + { + if (c < '0' || c > '9') + break; /* End of decimal? */ + c -= '0'; + if (f == 0) + { /* In integer part */ + val = val * 10 + c; + } + else + { /* In fractional part */ + val += i10x(f--) * c; + } + } + c = *(++(*str)); + } + if (c > ' ') + { /* It may be an exponent */ + if (c != 'e' && c != 'E') + return 0; /* Wrong character? */ + c = *(++(*str)); + if (c == '-') + { + c = *(++(*str)); + s |= 2; /* Negative exponent */ + } + else if (c == '+') + { + c = *(++(*str)); /* Positive exponent */ + } + if (c <= ' ') + return 0; /* Wrong termination? */ + e = 0; + while (c > ' ') + { /* Get value of exponent */ + c -= '0'; + if (c > 9) + return 0; /* Not a numeral? */ + e = e * 10 + c; + c = *(++(*str)); + } + val *= i10x((s & 2) ? -e : e); /* Apply exponent */ + } + + if (s & 1) + val = -val; /* Negate sign if needed */ + + *res = val; + return 1; +} +#endif /* XF_USE_FP */ + +#endif /* XF_USE_INPUT */ diff --git a/demo/easy_transplant/xprintf/src/xprintf.h b/demo/easy_transplant/xprintf/src/xprintf.h new file mode 100644 index 0000000..19f4feb --- /dev/null +++ b/demo/easy_transplant/xprintf/src/xprintf.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------*/ +/* Universal string handler for user console interface (C)ChaN, 2021 */ +/*------------------------------------------------------------------------*/ + +#ifndef XPRINTF_DEF +#define XPRINTF_DEF +#include + +// clang-format off + +#ifdef __cplusplus +extern "C" { +#endif + +#define XF_USE_OUTPUT 1 /* 1: Enable output functions */ +#define XF_CRLF 1 /* 1: Convert \n ==> \r\n in the output char */ +#define XF_USE_DUMP 1 /* 1: Enable put_dump function */ +#define XF_USE_LLI 1 /* 1: Enable long long integer in size prefix ll */ +#define XF_USE_FP 1 /* 1: Enable support for floating point in type e and f */ +#define XF_DPC '.' /* Decimal separator for floating point */ +#define XF_USE_INPUT 1 /* 1: Enable input functions */ +#define XF_INPUT_ECHO 1 /* 1: Echo back input chars in xgets function */ + + // clang-format on + +#if defined(__GNUC__) && __GNUC__ >= 10 +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + +#if XF_USE_OUTPUT +#define xdev_out(func) xfunc_output = (void (*)(int))(func) + extern void (*xfunc_output)(int); + void xputc(int chr); + void xfputc(void (*func)(int), int chr); + void xputs(const char *str); + void xfputs(void (*func)(int), const char *str); + void xprintf(const char *fmt, ...); + void xsprintf(char *buff, const char *fmt, ...); + void xfprintf(void (*func)(int), const char *fmt, ...); + void put_dump(const void *buff, unsigned long addr, int len, size_t width); +#endif + +#if XF_USE_INPUT +#define xdev_in(func) xfunc_input = (int (*)(void))(func) + extern int (*xfunc_input)(void); + int xgets(char *buff, int len); + int xatoi(char **str, long *res); + int xatof(char **str, double *res); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extensions/shell_enhance/shell_passthrough.c b/extensions/shell_enhance/shell_passthrough.c index fec78a5..bea3b80 100644 --- a/extensions/shell_enhance/shell_passthrough.c +++ b/extensions/shell_enhance/shell_passthrough.c @@ -55,7 +55,7 @@ unsigned int shellPassthrough(Shell *shell, const char *prompt, ShellPassthrough shellWriteString(shell, "\r\n"); shell->parser.length = 0; shell->parser.cursor = 0; - return -1; + return (unsigned int)(-1); } else { diff --git a/extensions/shell_enhance/shell_passthrough.h b/extensions/shell_enhance/shell_passthrough.h index f257cf2..1ee606d 100644 --- a/extensions/shell_enhance/shell_passthrough.h +++ b/extensions/shell_enhance/shell_passthrough.h @@ -59,4 +59,4 @@ typedef int (*ShellPassthrough)(char *data, unsigned short len); unsigned int shellPassthrough(Shell *shell, const char *prompt, ShellPassthrough handler, int argc, char *argv[]); -#endif \ No newline at end of file +#endif From 915100dbe3acc8ce2fa117062c6a2f3a9e5c2489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Sun, 8 Dec 2024 02:45:06 +0800 Subject: [PATCH 11/12] =?UTF-8?q?fix:=20=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8Ds?= =?UTF-8?q?hell=E4=B8=8Elog=E7=BB=84=E4=BB=B6=E7=9A=84=E5=8A=A0=E9=94=81?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5FreeRTOS=E7=9A=84=E9=94=99=E8=AF=AF=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 加锁解锁的API对接问题 2. 添加部分移植描述等 --- demo/easy_transplant/readme.md | 3 +- demo/easy_transplant/shell_all.c | 193 +++++++++--------- demo/easy_transplant/shell_cfg_user.h | 2 +- .../stm32_HAL_adapt/stm32_HAL_adapt.c | 50 ++++- .../stm32_HAL_adapt/stm32_HAL_adapt.h | 25 ++- demo/easy_transplant/xprintf/src/xprintf.h | 4 +- extensions/log/log.h | 2 +- 7 files changed, 163 insertions(+), 116 deletions(-) diff --git a/demo/easy_transplant/readme.md b/demo/easy_transplant/readme.md index 5779101..1ab3de0 100644 --- a/demo/easy_transplant/readme.md +++ b/demo/easy_transplant/readme.md @@ -13,6 +13,7 @@ 此处以keil为例 ~~ 将keil编译器切换为AC6,AC5太老了编译又慢,一定要选用AC5导致的编译报错请自行解决 ~~ 已完善AC5编译器支持 + 1. 将此文件夹下shell_all.c和stm32_HAL_adapt文件夹下stm32_HAL_adapt.c添加编译 2. 将shell根目录下src文件夹和extensions/shell_enhance和shell_all.h所在文件夹添加头文件包含 @@ -32,6 +33,6 @@ OK,编译,烧录完事 # 其他说明 -此例程移植同样力求不更改letter shell原仓库文件分布情况 +此例程移植力求不更改letter shell原仓库文件分布情况 shell对接最重要的在于read与write,通常是直接对接到外设上(例如串口),但是外设的速度是远低于内核的运行速度的,于是此例的移植对shell的输入输出都采用ringbuffer缓冲,这样方便解决在中断中调用shell读写(比如log组件)导致中断的的长时间运行,以及stm32_HAL_adapt中实现了支持FreeRTOS的情况下加锁之类的操作 diff --git a/demo/easy_transplant/shell_all.c b/demo/easy_transplant/shell_all.c index 85a0453..dd22473 100644 --- a/demo/easy_transplant/shell_all.c +++ b/demo/easy_transplant/shell_all.c @@ -39,24 +39,30 @@ //+********************************* 环形队列中转 **********************************/ #if SHELL_SHOW_INFO == 1 #if SHELL_TX_BUFFER_SIZE < 400 -#warning "建议将环形队列的大小设置为大于400,否则打印初始化信息的时候可能会出现部分打印数据丢失" +#warning "建议将输出环形队列的大小设置为大于400,否则打印初始化信息的时候可能会出现部分打印数据丢失" #warning "shell tx buffer size is too small, please increase the buffer size" #endif #endif -// 定义shell和log对象 -static Shell user_shell; -static Log user_log; +// 原子操作进入和退出 +#ifndef SHELL_ATOMIC_ENTER +#define SHELL_ATOMIC_ENTER() (void)0 +#endif // !SHELL_ATOMIC_ENTER -// 发送和接收的中转环形缓冲队列 -static ringbuffer_t rb_rx; -static ringbuffer_t rb_tx; +#ifndef SHELL_ATOMIC_EXIT +#define SHELL_ATOMIC_EXIT() (void)0 +#endif // !SHELL_ATOMIC_EXIT // 写入是否可以阻塞,默认不可以阻塞,一般判断是否在中断中就可以判断是否可以阻塞 #ifndef SHELL_WRITE_CAN_BLOCK #define SHELL_WRITE_CAN_BLOCK() (false) #endif // !SHELL_WRITE_CAN_BLOCK +// 等待一段时间 +#ifndef WAIT_A_MOMENT +#define WAIT_A_MOMENT() (void)0 +#endif // !WAIT_A_MOMENT + #undef USER_ASSERT #define USER_ASSERT(exp) (void)0 // 开启此宏关闭此文件用户自定义断言 @@ -73,70 +79,13 @@ static ringbuffer_t rb_tx; #endif // ! USER_ASSERT // clang-format on -//+********************************* shell读写对接 **********************************/ - -short write_to_ringbuffer(char *data, unsigned short len) -{ - short total_written = 0; - short ret = 0; - - while (len > 0) - { - SHELL_ATOMIC_ENTER(); - - ret = ringbuffer_write(&rb_tx, (uint8_t *)data, len); - - SHELL_ATOMIC_EXIT(); - - if (ret >= len) // 只可能小于等于 - { - return total_written; // 全部数据写入成功 - } - else - { - if (!SHELL_WRITE_CAN_BLOCK()) - { - total_written += ret; - WRITE_OVER_FLOW_HOOK((char *)data - total_written, total_written, len); - break; // 如果在中断中,直接退出,未写入的数据直接丢弃,避免长时间占用中断 - } - - total_written += ret; - data += ret; - len -= ret; - port_tx_trigger(); // 主动尝试触发发送 - - WAIT_A_MOMENT(); // 等待一段时间,避免频繁触发发送 - } - } - - return total_written; -} - -short read_from_ringbuffer(char *data, unsigned short len) -{ - short ret = 0; - SHELL_ATOMIC_ENTER(); - - ret = ringbuffer_read(&rb_rx, (uint8_t *)data, len); - - SHELL_ATOMIC_EXIT(); - return ret; -} - -//+******************************** log组件对接 ***************************************/ +// 定义shell和log对象 +static Shell user_shell; +static Log user_log; -void UserLogWrite(char *buffer, short len) -{ -#if SHELL_SUPPORT_END_LINE == 1 - USER_ASSERT(user_log.shell != NULL); - shellWriteEndLine(user_log.shell, buffer, len); -#else - USER_ASSERT(user_log.shell != NULL); - USER_ASSERT(user_log.shell->write != NULL); - user_log.shell->write(buffer, len); -#endif -} +// 发送和接收的中转环形缓冲队列 +static ringbuffer_t rb_rx; +static ringbuffer_t rb_tx; //+******************************** 对外调用接口 ***************************************/ void port_tx_trigger(void) @@ -151,11 +100,9 @@ void port_tx_trigger(void) uint8_t *p; SHELL_ATOMIC_ENTER(); - // 获取ringbuffer当前的读指针和最大线性可读数据大小 ringbuffer_mark_busy(&rb_tx); // 标记为忙,调用port_tx_end函数后再标记为闲 p = ringbuffer_linear_read_setup(&rb_tx, &size); - SHELL_ATOMIC_EXIT(); // 发送数据,调用平台相关的发送函数 @@ -164,7 +111,6 @@ void port_tx_trigger(void) void port_rx_trigger(void) { - if (ringbuffer_is_busy(&rb_rx) || ringbuffer_get_free(&rb_rx) <= 0) // 性能优化,对于接收,外设忙的情况更多先判断是否在忙 { return; // 没有空间接收或者正在接收数据 @@ -178,7 +124,6 @@ void port_rx_trigger(void) ringbuffer_mark_busy(&rb_rx); // 标记为忙,调用port_rx_end函数后再标记为闲 // 获取ringbuffer当前的写指针和最大线性可写数据大小 p = ringbuffer_linear_write_setup(&rb_rx, &size); - SHELL_ATOMIC_EXIT(); // 接收数据,调用平台相关的接收函数 @@ -193,10 +138,8 @@ void port_tx_end(short truely_tx_len) { truely_tx_len = ringbuffer_get_last_series_size(&rb_tx); } - ringbuffer_linear_read_done(&rb_tx, truely_tx_len); ringbuffer_mark_idle(&rb_tx); - SHELL_ATOMIC_EXIT(); #if SHELL_TX_CONTINUOUSLY @@ -211,7 +154,6 @@ void port_rx_end(short truely_rx_len) { truely_rx_len = ringbuffer_get_last_series_size(&rb_rx); } - ringbuffer_linear_write_done(&rb_rx, truely_rx_len); ringbuffer_mark_idle(&rb_rx); SHELL_ATOMIC_EXIT(); @@ -231,15 +173,81 @@ int port_rx_available(void) { return ringbuffer_get_used(&rb_rx); } + +//+********************************* shell读写对接 **********************************/ + +static short write_to_ringbuffer(char *data, unsigned short len) +{ + short total_written = 0; + short ret = 0; + + while (len > 0) + { + SHELL_ATOMIC_ENTER(); + + ret = ringbuffer_write(&rb_tx, (uint8_t *)data, len); + + SHELL_ATOMIC_EXIT(); + + if (ret >= len) // 只可能小于等于 + { + return total_written; // 全部数据写入成功 + } + else + { + if (!SHELL_WRITE_CAN_BLOCK()) + { + total_written += ret; + WRITE_OVER_FLOW_HOOK((char *)data - total_written, total_written, len); + break; // 如果在中断中,直接退出,未写入的数据直接丢弃,避免长时间占用中断 + } + + total_written += ret; + data += ret; + len -= ret; + port_tx_trigger(); // 主动尝试触发发送 + + WAIT_A_MOMENT(); // 等待一段时间,避免频繁触发发送 + } + } + + return total_written; +} + +static short read_from_ringbuffer(char *data, unsigned short len) +{ + short ret = 0; + SHELL_ATOMIC_ENTER(); + + ret = ringbuffer_read(&rb_rx, (uint8_t *)data, len); + + SHELL_ATOMIC_EXIT(); + return ret; +} + +//+******************************** log组件对接 ***************************************/ + +static void UserLogWrite(char *buffer, short len) +{ +#if SHELL_SUPPORT_END_LINE == 1 + USER_ASSERT(user_log.shell != NULL); + shellWriteEndLine(user_log.shell, buffer, len); +#else + USER_ASSERT(user_log.shell != NULL); + USER_ASSERT(user_log.shell->write != NULL); + user_log.shell->write(buffer, len); +#endif +} + //+******************************** shell和log组件初始化,shell任务 ***************************************/ // 锁函数需要在对应的适配文件中实现 // shell 锁实现函数 -extern void shell_lock(struct shell_def *shell); -extern void shell_unlock(struct shell_def *shell); +extern int shell_lock(struct shell_def *shell); +extern int shell_unlock(struct shell_def *shell); // log锁实现函数 -extern void log_lock(struct log_def *log); -extern void log_unlock(struct log_def *log); +extern int log_lock(struct log_def *log); +extern int log_unlock(struct log_def *log); extern void user_init_before_shell(void); @@ -253,32 +261,21 @@ void letter_shell_init(void) ringbuffer_init(&rb_rx, (uint8_t *)rb_rx_buffer, sizeof(rb_rx_buffer)); ringbuffer_init(&rb_tx, (uint8_t *)rb_tx_buffer, sizeof(rb_tx_buffer)); - // 用于存放命令之类的buffer - static char shell_buffer[512]; - user_shell.write = write_to_ringbuffer; user_shell.read = read_from_ringbuffer; #if SHELL_USING_LOCK == 1 - -#if !defined(SHELL_LOCK_FUNC) || !defined(SHELL_UNLOCK_FUNC) -#error "请定义shell的加锁与解锁函数或者不使用log锁(设置SHELL_USING_LOCK为0)" -#error "please define SHELL_LOCK_FUNC and SHELL_UNLOCK_FUNC" -#endif user_shell.lock = shell_lock; user_shell.unlock = shell_unlock; #endif + + // 用于存放命令之类的buffer + static char shell_buffer[512]; shellInit(&user_shell, shell_buffer, sizeof(shell_buffer)); // 初始化shell - user_log.active = 1; // 创建log对象,默认输出所有等级的log + user_log.active = 1; // 激活log,默认输出所有等级的log,绑定log输出 user_log.level = LOG_ALL; user_log.write = UserLogWrite, #if LOG_USING_LOCK == 1 - -#if !defined(LOG_LOCK_FUNC) || !defined(LOG_UNLOCK_FUNC) -#error "请定义log的加锁与解锁函数或者不使用log锁(设置LOG_USING_LOCK为0)" -#error "please define LOG_LOCK_FUNC and LOG_UNLOCK_FUNC" -#endif - user_log.lock = log_lock; user_log.unlock = log_unlock; #endif @@ -330,11 +327,9 @@ int shell_printf(const char *format, ...) // len = vsnprintf(buf, sizeof(buf), format, args); // va_end(args); - // xfprintf - int len = 0; - Shell *shell = &user_shell; + Shell *shell = shellGetCurrent(); #if SHELL_SUPPORT_END_LINE == 1 diff --git a/demo/easy_transplant/shell_cfg_user.h b/demo/easy_transplant/shell_cfg_user.h index b894014..dd7df84 100644 --- a/demo/easy_transplant/shell_cfg_user.h +++ b/demo/easy_transplant/shell_cfg_user.h @@ -45,7 +45,7 @@ * @brief 使用锁 * @note 使用shell锁时,需要对加锁和解锁进行实现 */ -#define SHELL_USING_LOCK 0 +#define SHELL_USING_LOCK 1 #ifndef SHELL_TASK_WHILE /** diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c index 5e09f64..25717c3 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.c @@ -9,6 +9,25 @@ * */ +// clang-format off +//> 必须对接实现的API,哪怕是空函数也要定义一份(可以通过配置宏来预处理关掉,但是还是建议实现,哪怕是空函数) + +/* + +// shell锁实现函数 +int shell_lock(struct shell_def *shell) {}; +int shell_unlock(struct shell_def *shell) {}; + +// log锁实现函数 +int log_lock(struct log_def *log) {}; +int log_unlock(struct log_def *log) {}; + +// shell初始化之前的初始化函数主要是为了初始化硬件接口等 +void user_init_before_shell(void) {}; + +*/ +// clang-format on + #include "stm32_HAL_adapt.h" #include "../shell_all.h" @@ -26,7 +45,7 @@ static SemaphoreHandle_t _log_mutex; // 互斥锁,防止输出混乱 #endif // !SHELL_WRITE_CAN_BLOCK // 如果有操作系统,可以使用操作系统提供的递归互斥锁 -void shell_lock(struct shell_def *shell) +int shell_lock(struct shell_def *shell) { if (SHELL_WRITE_CAN_BLOCK()) { // 操作系统的加锁 @@ -36,11 +55,13 @@ void shell_lock(struct shell_def *shell) } else { - // 处于不能阻塞的地方,一般认为是中断,直接不管 + // 处于不能阻塞的地方,一般认为是中断,直接不管或者必须使用支持嵌套的原子加锁,下面的几个API类似 } + + return 0; } -void shell_unlock(struct shell_def *shell) +int shell_unlock(struct shell_def *shell) { if (SHELL_WRITE_CAN_BLOCK()) { // 操作系统的解锁 @@ -51,9 +72,11 @@ void shell_unlock(struct shell_def *shell) else { } + + return 0; } -void log_lock(struct log_def *log) +int log_lock(struct log_def *log) { if (SHELL_WRITE_CAN_BLOCK()) { // 操作系统的加锁 @@ -64,9 +87,11 @@ void log_lock(struct log_def *log) else { } + + return 0; } -void log_unlock(struct log_def *log) +int log_unlock(struct log_def *log) { if (SHELL_WRITE_CAN_BLOCK()) { // 操作系统的解锁 @@ -77,6 +102,8 @@ void log_unlock(struct log_def *log) else { } + + return 0; } // shell使用的硬件初始化,使用cubemx开启串口,然后使能对应的串口中断,DMA发送与接收中断 @@ -96,6 +123,7 @@ void user_init_before_shell(void) #if 1 #if (PLATFORM_MODE == PLATFORM_MODE_DMA) + void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) // 串口接收中断 { UNUSED(huart); @@ -116,7 +144,9 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 } } + #elif (PLATFORM_MODE == PLATFORM_MODE_IT) + void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == SHELL_UART_ADDR->Instance) @@ -134,11 +164,14 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) // 串口发送中断 port_tx_end(-1); // 传输默认是传输完了上一次的,传入负数让其自行处理 } } + #endif #endif //+******************************** 导出一些可能常用的命令 ***************************************/ +#if 1 + int Reboot() { HAL_NVIC_SystemReset(); // 单片机重启 @@ -146,8 +179,6 @@ int Reboot() } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), Reboot, Reboot, reboot the mcu); -#if 1 - #include int date() { @@ -162,12 +193,13 @@ int date() shell->lock(shell); #endif - char str[100]; + char str[150]; snprintf(str, sizeof(str), "current time: %lld\r\n", ticks); shellWriteString(shell, str); // 换算为天`时`分`秒`毫秒 - snprintf(str, sizeof(str), "current time: %lld day %02lld hour %02lld min %02lld sec %03lld ms\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); + // snprintf(str, sizeof(str), "current time: %lld 天 %02lld 时 %02lld 分 %02lld 秒 %03lld 毫秒\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); + snprintf(str, sizeof(str), "current time: %lld days %02lld hours %02lld minutes %02lld seconds %03lld milliseconds\r\n", ticks / (1000 * 60 * 60 * 24), (ticks / (1000 * 60 * 60)) % 24, (ticks / (1000 * 60)) % 60, (ticks / 1000) % 60, ticks % 1000); shellWriteString(shell, str); #if SHELL_USING_LOCK == 1 diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h index 7bf7207..352d934 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h @@ -1,7 +1,7 @@ /** * @file stm32_HAL_adapt.h * @author fool_dog (2696652257@qq.com) - * @brief // 裸机与FreeRTOS的对接方式 + * @brief // STM32HAL库 裸机与FreeRTOS的对接方式 * @version 1.0 * @date 2024-08-08 * @@ -13,6 +13,22 @@ #ifndef _STM32_HAL_ADAPT_H_ #define _STM32_HAL_ADAPT_H_ +// clang-format off +/** + * 此文件主要是必须对接的宏定义,包括: + * #define PLATFORM_TX_WRAP(buffer, len) ... //> 发送包装宏 + * #define PLATFORM_RX_WRAP(buffer, len) ... //> 接收包装宏 + * #define SHELL_GET_TICK() ... //> 获取系统时间(ms) + * 可选宏: + * #define SHELL_WRITE_CAN_BLOCK() ... //> 判定写入是否可以阻塞 + * #define WAIT_A_MOMENT() ... //> 等待一段时间(可选,默认等待1ms) + * #define SHELL_ATOMIC_ENTER() ... //> 进入原子操作 + * #define SHELL_ATOMIC_EXIT() ... //> 退出原子操作 + * #define SHELL_UART_ADDR ... //> 取决于接收和发送宏的实现(可以不用串口) + */ + +// clang-format on + #include "cmsis_compiler.h" #include "usart.h" @@ -38,6 +54,8 @@ #if (RTOS_MODE == RTOS_NONE) #define WAIT_A_MOMENT() HAL_Delay(1) // 等待一段时间,外设跟不上内核填充的速度 #elif (RTOS_MODE == RTOS_FREERTOS) +#include "FreeRTOS.h" +#include "task.h" #define WAIT_A_MOMENT() vTaskDelay(1) #else #warning "请实现自己的等待函数" @@ -48,7 +66,8 @@ #define SHELL_ATOMIC_ENTER() __disable_irq() #define SHELL_ATOMIC_EXIT() __enable_irq() -#define SHELL_UART_ADDR (&huart2) +//> 默认使用串口1 +#define SHELL_UART_ADDR (&huart1) // clang-format off #if (PLATFORM_MODE == PLATFORM_MODE_DMA) @@ -61,7 +80,7 @@ extern HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); extern HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_IT(SHELL_UART_ADDR, (uint8_t *)buffer, len) - // 中断接收改成单个字节接收 + // 中断接收改成单个字节接收,接收回调调用port_rx_end(1);表示接收到一个字节 #define PLATFORM_RX_WRAP(buffer, len) HAL_UART_Receive_IT(SHELL_UART_ADDR, (uint8_t *)buffer, 1) #else #error "请实现自己的接收与发送函数对接" diff --git a/demo/easy_transplant/xprintf/src/xprintf.h b/demo/easy_transplant/xprintf/src/xprintf.h index 19f4feb..061db6d 100644 --- a/demo/easy_transplant/xprintf/src/xprintf.h +++ b/demo/easy_transplant/xprintf/src/xprintf.h @@ -18,8 +18,8 @@ extern "C" { #define XF_USE_LLI 1 /* 1: Enable long long integer in size prefix ll */ #define XF_USE_FP 1 /* 1: Enable support for floating point in type e and f */ #define XF_DPC '.' /* Decimal separator for floating point */ -#define XF_USE_INPUT 1 /* 1: Enable input functions */ -#define XF_INPUT_ECHO 1 /* 1: Echo back input chars in xgets function */ +#define XF_USE_INPUT 0 /* 1: Enable input functions */ +#define XF_INPUT_ECHO 0 /* 1: Echo back input chars in xgets function */ // clang-format on diff --git a/extensions/log/log.h b/extensions/log/log.h index 20f4e14..33611ab 100644 --- a/extensions/log/log.h +++ b/extensions/log/log.h @@ -21,7 +21,7 @@ extern "C" { #define SHELL_COMPANION_ID_LOG -2 -#define LOG_USING_LOCK 0 +#define LOG_USING_LOCK 1 #define LOG_BUFFER_SIZE 256 /**< log输出缓冲大小 */ #define LOG_USING_COLOR 1 /**< 是否使用颜色 */ #define LOG_MAX_NUMBER 5 /**< 允许注册的最大log对象数量 */ From 589c6e842cd3c8a73b53cc82ab2fda31e6cf9381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E9=9C=B8=E4=B8=80=E6=96=B9-=5F-?= <59137524+fool-cat@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:26:24 +0800 Subject: [PATCH 12/12] =?UTF-8?q?feat:=20=E2=9A=A1=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=83=A8=E5=88=86=E9=80=BB=E8=BE=91,=E4=BF=9D=E8=AF=81?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=9A=84=E5=AE=8C=E6=95=B4=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 优化写缓冲溢出处理逻辑,保证输出数据的完整性 2. 增加shell_write直接往缓冲区写入数据,方便输出原始数据 3. 取消shell_printf的尾随模式打印 4. 增加作者推荐的overlay方式修改配置文件 --- demo/easy_transplant/shell_all.c | 67 ++++--------------- demo/easy_transplant/shell_all.h | 7 +- demo/easy_transplant/shell_cfg_user.h | 6 +- .../stm32_HAL_adapt/stm32_HAL_adapt.h | 7 ++ 4 files changed, 31 insertions(+), 56 deletions(-) diff --git a/demo/easy_transplant/shell_all.c b/demo/easy_transplant/shell_all.c index dd22473..a87ca83 100644 --- a/demo/easy_transplant/shell_all.c +++ b/demo/easy_transplant/shell_all.c @@ -181,7 +181,14 @@ static short write_to_ringbuffer(char *data, unsigned short len) short total_written = 0; short ret = 0; - while (len > 0) + // 不可被阻塞,缓冲区还不能完全写入就直接丢掉,避免数据写入不完全 + if (!SHELL_WRITE_CAN_BLOCK() && ringbuffer_get_free(&rb_tx) < len) + { + WRITE_OVER_FLOW_HOOK((char *)data, len); + return 0; // 直接丢弃数据,不再写入 + } + + do { SHELL_ATOMIC_ENTER(); @@ -195,13 +202,6 @@ static short write_to_ringbuffer(char *data, unsigned short len) } else { - if (!SHELL_WRITE_CAN_BLOCK()) - { - total_written += ret; - WRITE_OVER_FLOW_HOOK((char *)data - total_written, total_written, len); - break; // 如果在中断中,直接退出,未写入的数据直接丢弃,避免长时间占用中断 - } - total_written += ret; data += ret; len -= ret; @@ -209,7 +209,7 @@ static short write_to_ringbuffer(char *data, unsigned short len) WAIT_A_MOMENT(); // 等待一段时间,避免频繁触发发送 } - } + } while (len <= 0); return total_written; } @@ -305,6 +305,11 @@ void letter_shell_task(void) #endif } +int shell_write(char *data, int len) +{ + return (int)(write_to_ringbuffer(data, len)); +} + #if USE_SHELL_PRINTF #include "./xprintf/src/xprintf.c" @@ -320,25 +325,11 @@ static inline void output_byte_buffer(int ch) int shell_printf(const char *format, ...) { - // int len = 0; - // char buf[SHELL_TX_BUFFER_SIZE]; - // va_list args; - // va_start(args, format); - // len = vsnprintf(buf, sizeof(buf), format, args); - // va_end(args); - int len = 0; Shell *shell = shellGetCurrent(); -#if SHELL_SUPPORT_END_LINE == 1 - - // shellWriteEndLine(&user_shell, buf, strlen(buf)); SHELL_LOCK(shell); - if (!shell->status.isActive) - { - shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_LINE]); - } _byte_count = 0; @@ -349,38 +340,8 @@ int shell_printf(const char *format, ...) len = _byte_count; - if (!shell->status.isActive) - { - shellWritePrompt(shell, 0); - if (shell->parser.length > 0) - { - shellWriteString(shell, shell->parser.buffer); - for (short i = 0; i < shell->parser.length - shell->parser.cursor; i++) - { - shellWriteByte(shell, '\b'); - } - } - } - SHELL_UNLOCK(shell); -#else - - SHELL_LOCK(shell); - - _byte_count = 0; - - va_list args; - va_start(args, format); - xvfprintf(output_byte_buffer, format, args); - va_end(args); - - len = _byte_count; - - SHELL_UNLOCK(shell); - -#endif - return len; } #endif diff --git a/demo/easy_transplant/shell_all.h b/demo/easy_transplant/shell_all.h index 70f9a7f..e93b7b9 100644 --- a/demo/easy_transplant/shell_all.h +++ b/demo/easy_transplant/shell_all.h @@ -31,7 +31,7 @@ // shell 写入溢出的时候可以调用钩子函数进行一些处理 #ifndef WRITE_OVER_FLOW_HOOK -#define WRITE_OVER_FLOW_HOOK(data, len_written, len_lose) (void)0 +#define WRITE_OVER_FLOW_HOOK(data, len) (void)0 #endif #if !defined(PLATFORM_TX_WRAP) || !defined(PLATFORM_RX_WRAP) @@ -87,9 +87,12 @@ extern "C" // shell任务 void letter_shell_task(void); + // shell写入函数,用于向shell写入数据,返回实际写入的字节数 + int shell_write(char *data, int len); + #define USE_SHELL_PRINTF 1 #if USE_SHELL_PRINTF - // shell尾随printf用于代替标准库的printf,shell_printf使用xprintf的格式化输出,以源码形式添加编译 + // 代替标准库的printf,shell_printf使用xprintf的格式化输出,以源码形式添加编译 int shell_printf(const char *format, ...); #define SHELL_PRINTF #endif diff --git a/demo/easy_transplant/shell_cfg_user.h b/demo/easy_transplant/shell_cfg_user.h index dd7df84..bc9344a 100644 --- a/demo/easy_transplant/shell_cfg_user.h +++ b/demo/easy_transplant/shell_cfg_user.h @@ -14,12 +14,16 @@ #include +#ifdef SHELL_CFG_USER +#include SHELL_CFG_USER +#endif + // clang-format off /** * @brief shell默认用户 */ -#define SHELL_DEFAULT_USER "letter_shell" +#define SHELL_DEFAULT_USER "letter" // /** // * @brief 是否使用shell伴生对象,开启后需要支持malloc和free接口 diff --git a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h index 352d934..ca5b07d 100644 --- a/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h +++ b/demo/easy_transplant/stm32_HAL_adapt/stm32_HAL_adapt.h @@ -82,6 +82,13 @@ #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit_IT(SHELL_UART_ADDR, (uint8_t *)buffer, len) // 中断接收改成单个字节接收,接收回调调用port_rx_end(1);表示接收到一个字节 #define PLATFORM_RX_WRAP(buffer, len) HAL_UART_Receive_IT(SHELL_UART_ADDR, (uint8_t *)buffer, 1) +#elif (PLATFORM_MODE == PLATFORM_MODE_POLL) +#warning "强烈不建议使用阻塞式API发送与接收,建议使用DMA或者中断方式" +#warning "It is not recommended to use blocking API for sending and receiving. It is recommended to use DMA or interrupt mode" + extern HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout); + extern HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); + #define PLATFORM_TX_WRAP(buffer, len) HAL_UART_Transmit(SHELL_UART_ADDR, (uint8_t *)buffer, len, 1000) + #define PLATFORM_RX_WRAP(buffer, len) HAL_UART_Receive(SHELL_UART_ADDR, (uint8_t *)buffer, len, 1000) #else #error "请实现自己的接收与发送函数对接" #error "please implement your own receive and send function docking"