瑞萨单片机论坛
直播中

尹向旭

8年用户 456经验值
擅长:可编程逻辑,嵌入式技术
私信 关注
[经验]

【瑞萨RA6E2】+复现uart测试和shell移植


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

先看看效果:

还有一个shell的效果:

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

效果如图:
最后贴上完整的入口文件代码:
  1. #include "hal_data.h"
  2. #include "lwrb.h"
  3. #include
  4. #include "nr_micro_shell.h"
  5. /*******************************************************************************************************************//**
  6. * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
  7. * is called by main() when no RTOS is used.
  8. **********************************************************************************************************************/
  9. lwrb_t buff = {0};
  10. uint8_t buff_data[256];
  11. /* UART9 发送与接收完成标志(由中断回调置位) */
  12. static volatile int g_uart9_tx_complete = 0;
  13. static volatile int g_uart9_rx_complete = 0;
  14. /* UART9 回调函数(FSP 自动调用) */
  15. void uart9_callback(uart_callback_args_t * p_args)
  16. {
  17.     switch (p_args->event)
  18.     {
  19.         case UART_EVENT_TX_COMPLETE:
  20.         {
  21.             /* 一帧发送完成 */
  22.             g_uart9_tx_complete = 1;
  23.             break;
  24.         }
  25.         case UART_EVENT_RX_COMPLETE:
  26.         {
  27.             /* 接收 DMA(或 FIFO)满/完成 */
  28.             g_uart9_rx_complete = 1;
  29.             break;
  30.         }
  31.         case UART_EVENT_RX_CHAR:
  32.         {
  33.             /* 收到单个字符(常用于普通 UART 接收) */
  34.             lwrb_write(&buff, (uint8_t *)&p_args->data, 1);
  35.             break;
  36.         }
  37.         default:
  38.         {
  39.             break;
  40.         }
  41.     }
  42. }
  43. /* 等待 UART9 发送完成(阻塞方式) */
  44. void uart9_wait_for_tx(void)
  45. {
  46.     while (!g_uart9_tx_complete)
  47.     {
  48.         /* 等待发送完成 */
  49.     }
  50.     g_uart9_tx_complete = 0;
  51. }
  52. /* 等待 UART9 接收完成(通常用于 DMA 或多字节接收) */
  53. void uart9_wait_for_rx(void)
  54. {
  55.     while (!g_uart9_rx_complete)
  56.     {
  57.         /* 等待接收完成 */
  58.     }
  59.     g_uart9_rx_complete = 0;
  60. }
  61. int fputc(int ch, FILE *f)
  62. {
  63.     (void)f;
  64.     /* 启动发送字符 */
  65.     g_uart9.p_api->write(g_uart9.p_ctrl, (uint8_t const *const)&ch, 1);
  66.     /* 等待发送完毕 */
  67.     uart9_wait_for_tx();
  68.     return ch;
  69. }
  70. /* 重写这个函数,重定向scanf (正确版本) */
  71. int fgetc(FILE *f)
  72. {
  73.     uint8_t ch = 0;
  74.    
  75.     (void)f;
  76.     /*
  77.      * 核心逻辑: 不断地从环形缓冲区读取数据。
  78.      * 如果缓冲区为空 (lwrb_read 返回 0),就继续循环等待。
  79.      * 直到成功读取到一个字节。
  80.      */
  81.     while (lwrb_read(&buff, &ch, 1) == 0)
  82.     {
  83.         /* 你可以在这里加入一个短暂的延时或WFI指令来降低CPU占用率,
  84.            但在简单应用中,空循环也可以工作。*/
  85.         // R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
  86.     }
  87.    
  88.     /* 回显接收到的字符 */
  89.     /* 注意:这里我们使用 printf,因为它已经被重定向到 uart9_wait_for_tx(),
  90.        这样可以避免与接收逻辑发生冲突。*/
  91.     printf("%c", ch);
  92.    
  93.     /* 如果收到的是回车符,额外发送一个换行符,以适配终端显示 */
  94.     if (ch == 'r')
  95.     {
  96.         printf("%c", 'n');
  97.     }
  98.    
  99.     return (int)ch;
  100. }
  101. void hal_entry(void)
  102. {
  103.     /* TODO: add your own code here */
  104.        
  105.             fsp_err_t err;
  106.     uart_cfg_t user_uart_cfg; // 用于设置回调
  107.     /* 1. 初始化环形缓冲区 */
  108.     lwrb_init(&buff, buff_data, sizeof(buff_data));
  109.     /* 2. 拷贝FSP生成的配置,并注册我们自己的回调函数 */
  110.     memcpy(&user_uart_cfg, &g_uart9_cfg, sizeof(uart_cfg_t));
  111.     user_uart_cfg.p_callback = uart9_callback;
  112.     user_uart_cfg.rxi_ipl = 3; // 设置一个有效的中断优先级
  113.     /* 3. 打开UART外设 */
  114.     err = g_uart9.p_api->open(g_uart9.p_ctrl, &user_uart_cfg);
  115.     if (FSP_SUCCESS != err)
  116.     {
  117.         // 错误处理
  118.         while(1);
  119.     }
  120.    
  121.     printf("eco-ra6e2!rn");
  122.                
  123.                 shell_init();
  124.    
  125. //    uint32_t a, b;
  126.    
  127.     while (1)
  128.     {
  129. //        printf("Please enter two number:rn");
  130. //        
  131. //        /*
  132. //         * scanf会反复调用我们新的fgetc函数。
  133. //         * fgetc会从环形缓冲区中取字符。
  134. //         * 环形缓冲区的数据由UART中断在后台自动填充。
  135. //         * 这样,接收和处理就分离开来,不会再卡死了。
  136. //         */
  137. //        int result = scanf("%d%d", &a, &b);
  138. //        
  139. //        if (result == 2) // 确保成功读取了两个数字
  140. //        {
  141. //            printf("%d+%d=%drn", a, b, a + b);
  142. //        }
  143. //        else
  144. //        {
  145. //            printf("Invalid input. Please enter numbers.rn");
  146. //            /* 清除输入缓冲区中所有无效的字符,直到遇到换行符 */
  147. //            while(getchar() != 'n');
  148. //        }
  149.                                
  150.                                
  151.                                   uint8_t ch;
  152.              if (lwrb_read(&buff, &ch, 1))
  153.              {
  154.               shell(ch);
  155.              }
  156.     }
  157. #if BSP_TZ_SECURE_BUILD
  158.     /* Enter non-secure code */
  159.     R_BSP_NonSecureEnter();
  160. #endif
  161. }
  162. #if BSP_TZ_SECURE_BUILD
  163. FSP_CPP_HEADER
  164. BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
  165. /* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
  166. BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
  167. {
  168. }
  169. FSP_CPP_FOOTER
  170. #endif
那么下面如果大家需要继续添加有颜色的log的话,参考网址里面的代码进行实现吧。


更多回帖

发帖
×
20
完善资料,
赚取积分