具体过程参考这个网址:
https://bbs.elecfans.com/jishu_2504589_1_1.html
先看看效果:

还有一个shell的效果:

这里面还有很多可以游玩的,但是没有太多时间了,所以只把这个实现过程中遇到的小坑重现和解决一下。
相关配置的过程参考上面的链接,那个没什么问题。
移植的时候添加这些文件:

效果如图:
最后贴上完整的入口文件代码:
- #include "hal_data.h"
- #include "lwrb.h"
- #include
- #include "nr_micro_shell.h"
- /*******************************************************************************************************************//**
- * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
- * is called by main() when no RTOS is used.
- **********************************************************************************************************************/
- lwrb_t buff = {0};
- uint8_t buff_data[256];
- /* UART9 发送与接收完成标志(由中断回调置位) */
- static volatile int g_uart9_tx_complete = 0;
- static volatile int g_uart9_rx_complete = 0;
- /* UART9 回调函数(FSP 自动调用) */
- void uart9_callback(uart_callback_args_t * p_args)
- {
- switch (p_args->event)
- {
- case UART_EVENT_TX_COMPLETE:
- {
- /* 一帧发送完成 */
- g_uart9_tx_complete = 1;
- break;
- }
- case UART_EVENT_RX_COMPLETE:
- {
- /* 接收 DMA(或 FIFO)满/完成 */
- g_uart9_rx_complete = 1;
- break;
- }
- case UART_EVENT_RX_CHAR:
- {
- /* 收到单个字符(常用于普通 UART 接收) */
- lwrb_write(&buff, (uint8_t *)&p_args->data, 1);
- break;
- }
- default:
- {
- break;
- }
- }
- }
- /* 等待 UART9 发送完成(阻塞方式) */
- void uart9_wait_for_tx(void)
- {
- while (!g_uart9_tx_complete)
- {
- /* 等待发送完成 */
- }
- g_uart9_tx_complete = 0;
- }
- /* 等待 UART9 接收完成(通常用于 DMA 或多字节接收) */
- void uart9_wait_for_rx(void)
- {
- while (!g_uart9_rx_complete)
- {
- /* 等待接收完成 */
- }
- g_uart9_rx_complete = 0;
- }
- int fputc(int ch, FILE *f)
- {
- (void)f;
- /* 启动发送字符 */
- g_uart9.p_api->write(g_uart9.p_ctrl, (uint8_t const *const)&ch, 1);
- /* 等待发送完毕 */
- uart9_wait_for_tx();
- return ch;
- }
- /* 重写这个函数,重定向scanf (正确版本) */
- int fgetc(FILE *f)
- {
- uint8_t ch = 0;
-
- (void)f;
- /*
- * 核心逻辑: 不断地从环形缓冲区读取数据。
- * 如果缓冲区为空 (lwrb_read 返回 0),就继续循环等待。
- * 直到成功读取到一个字节。
- */
- while (lwrb_read(&buff, &ch, 1) == 0)
- {
- /* 你可以在这里加入一个短暂的延时或WFI指令来降低CPU占用率,
- 但在简单应用中,空循环也可以工作。*/
- // R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
- }
-
- /* 回显接收到的字符 */
- /* 注意:这里我们使用 printf,因为它已经被重定向到 uart9_wait_for_tx(),
- 这样可以避免与接收逻辑发生冲突。*/
- printf("%c", ch);
-
- /* 如果收到的是回车符,额外发送一个换行符,以适配终端显示 */
- if (ch == 'r')
- {
- printf("%c", 'n');
- }
-
- return (int)ch;
- }
- void hal_entry(void)
- {
- /* TODO: add your own code here */
-
- fsp_err_t err;
- uart_cfg_t user_uart_cfg; // 用于设置回调
- /* 1. 初始化环形缓冲区 */
- lwrb_init(&buff, buff_data, sizeof(buff_data));
- /* 2. 拷贝FSP生成的配置,并注册我们自己的回调函数 */
- memcpy(&user_uart_cfg, &g_uart9_cfg, sizeof(uart_cfg_t));
- user_uart_cfg.p_callback = uart9_callback;
- user_uart_cfg.rxi_ipl = 3; // 设置一个有效的中断优先级
- /* 3. 打开UART外设 */
- err = g_uart9.p_api->open(g_uart9.p_ctrl, &user_uart_cfg);
- if (FSP_SUCCESS != err)
- {
- // 错误处理
- while(1);
- }
-
- printf("eco-ra6e2!rn");
-
- shell_init();
-
- // uint32_t a, b;
-
- while (1)
- {
- // printf("Please enter two number:rn");
- //
- // /*
- // * scanf会反复调用我们新的fgetc函数。
- // * fgetc会从环形缓冲区中取字符。
- // * 环形缓冲区的数据由UART中断在后台自动填充。
- // * 这样,接收和处理就分离开来,不会再卡死了。
- // */
- // int result = scanf("%d%d", &a, &b);
- //
- // if (result == 2) // 确保成功读取了两个数字
- // {
- // printf("%d+%d=%drn", a, b, a + b);
- // }
- // else
- // {
- // printf("Invalid input. Please enter numbers.rn");
- // /* 清除输入缓冲区中所有无效的字符,直到遇到换行符 */
- // while(getchar() != 'n');
- // }
-
-
- uint8_t ch;
- if (lwrb_read(&buff, &ch, 1))
- {
- shell(ch);
- }
- }
- #if BSP_TZ_SECURE_BUILD
- /* Enter non-secure code */
- R_BSP_NonSecureEnter();
- #endif
- }
- #if BSP_TZ_SECURE_BUILD
- FSP_CPP_HEADER
- BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
- /* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
- BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
- {
- }
- FSP_CPP_FOOTER
- #endif
那么下面如果大家需要继续添加有颜色的log的话,参考网址里面的代码进行实现吧。