[其他ST产品] rt-thread nano移植到新唐M031

[复制链接]
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:45 | 显示全部楼层 |阅读模式
习惯在rtos下写代码回不去祼机下大循环前后台标志位的写法,几K内存也跑个RTOS,参照论坛一篇rt-thread nano移植的帖子,也做了一次rt-thread nano的适配到M031LE3AE芯片。finsh串口为UART1的PB6、PB7,芯片时钟为内部RC 48MHz。

一、在keil MDK安装相应的组件包,并配置加入工程中
777136442af9d23aca.png


评论

———————————————— 版权声明:本文为CSDN博主「纵向深耕」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/dmjkun/article/details/123852266  发表于 2023-4-21 23:45
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:46 | 显示全部楼层
二、加入新M0的硬件驱动库并加入头文件 路径

338326442afc12f46e.png
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:46 | 显示全部楼层
三、配置rtconfig.h文件

119796442afcf529dc.png

 楼主| 花间一壶酒sd 发表于 2023-4-21 23:46 | 显示全部楼层
四、修改board.c及finsh_port.c文件完成BSP硬件对接
修改RT_HEAP_SIZE为合适的堆大小,不然没法编译

把retarget.c文件的HardFault_Handler函数注释掉,由rt-thread nano的HardFault_Handler接管

625566442afe0ec7c3.png
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:47 | 显示全部楼层
修改system_M031Serials.c的系统时钟为__HIRC

  1. uint32_t SystemCoreClock  = __HIRC;              /*!< System Clock Frequency (Core Clock) */
  2. uint32_t CyclesPerUs      = (__HIRC / 1000000);  /*!< Cycles per micro second             */
  3. uint32_t PllClock         = __HIRC;              /*!< PLL Output Clock Frequency          */
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:47 | 显示全部楼层
依次按照#error设定的4个部分配置时钟和硬件初始化,串口初始化,串口输出,串口输入。
时钟初始化,复制SYS_Init(); 并在其中完善滴答定时器的启动与配置。
打开board.c添加系统初始化代码
  1. void SYS_Init(void)
  2. {
  3.     /*---------------------------------------------------------------------------------------------------------*/
  4.     /* Init System Clock                                                                                       */
  5.     /*---------------------------------------------------------------------------------------------------------*/

  6.     /* Unlock protected registers */
  7.     SYS_UnlockReg();

  8.     /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
  9.     PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

  10.     /* Enable HIRC clock (Internal RC 48 MHz) */
  11.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  12.     /* Wait for HIRC clock ready */
  13.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

  14.     /* Set core clock as 51MHz from PLL */
  15.     CLK_SetCoreClock(FREQ_48MHZ);

  16.     /* System Tick Configuration */
  17.     CLK_EnableSysTick(CLK_CLKSEL0_STCLKSEL_HCLK,SystemCoreClock / RT_TICK_PER_SECOND);

  18.     /* Enable UART clock */
  19.     CLK_EnableModuleClock(UART1_MODULE);

  20.     /* Select UART clock source from HIRC */
  21.     CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_HIRC, CLK_CLKDIV0_UART1(1));         

  22.     /* Update System Core Clock */

  23.     /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */

  24.     SystemCoreClockUpdate();

  25.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  26.     SYS->GPB_MFPL = (SYS->GPB_MFPL & ~(SYS_GPB_MFPL_PB6MFP_Msk | SYS_GPB_MFPL_PB7MFP_Msk))    |       \

  27.                     (SYS_GPB_MFPL_PB7MFP_UART1_TXD | SYS_GPB_MFPL_PB6MFP_UART1_RXD);

  28.     /* Lock protected registers */
  29.     SYS_LockReg();
  30. }
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:47 | 显示全部楼层
滴答定时器中断的内容:

/* systick 中断服务例程 */
  1. void SysTick_Handler(void)
  2. {
  3.         rt_os_tick_callback();
  4. }
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:48 | 显示全部楼层
其中内部的回调函数,rtt的board.c已经帮我们完成,只需要添加以上代码段即可,也可修改回调函数的名字为中断入口。

将系统初始化代码填入#error "TODO 1: OS Tick Configuration."后面,并注释掉该行,确保编译时候不再报错提示该位置。

串口初始化,按如下代码进行初始化
  1. static int uart_init(void)
  2. {
  3. //#error "TODO 2: Enable the hardware uart and config baudrate."

  4.     /* Reset UART1 */
  5.     SYS_ResetModule(UART1_RST);
  6.    
  7.     /* Configure UART1 and set UART1 baud rate */

  8.     UART_Open(UART1, 115200);
  9.    
  10.     return 0;
  11. }

 楼主| 花间一壶酒sd 发表于 2023-4-21 23:48 | 显示全部楼层
串口输出功能
串口打印函数是调用rt-thread nano的rt_kprintf函数,
  1. voidrt_hw_console_output(const char *str)
  2. {
  3.         //#error "TODO 3: Output the string 'str' through the uart."
  4.         UART_Write(UART1,(uint8_t *)str,rt_strlen(str));        
  5. }
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:48 | 显示全部楼层
串口输入功能

串口输入功能的配置在finsh_port.c
  1. RT_WEAK char rt_hw_console_getchar(void)
  2. {
  3.     /* Note: the initial value of ch must < 0 */
  4.     int ch = -1;
  5. //#error "TODO 4: Read a char from the uart and assign it to 'ch'."
  6.         if((UART1->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0)
  7.         {
  8.                 return (UART1->DAT);
  9.         }
  10.         return ch;
  11. }
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:49 | 显示全部楼层
完整board.c文件
  1. /*
  2. * Copyright (c) 2006-2019, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date           Author       Notes
  8. * 2021-05-24                  the first version
  9. */

  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <NuMicro.h>

  13. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
  14. /*
  15. * Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
  16. * the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
  17. */
  18. #define RT_HEAP_SIZE (12*1024)
  19. static rt_uint8_t rt_heap[RT_HEAP_SIZE];

  20. RT_WEAK void *rt_heap_begin_get(void)
  21. {
  22.     return rt_heap;
  23. }

  24. RT_WEAK void *rt_heap_end_get(void)
  25. {
  26.     return rt_heap + RT_HEAP_SIZE;
  27. }
  28. #endif

  29. void rt_os_tick_callback(void)
  30. {
  31.     rt_interrupt_enter();
  32.    
  33.     rt_tick_increase();

  34.     rt_interrupt_leave();
  35. }

  36. void SysTick_Handler(void)
  37. {
  38.     rt_os_tick_callback();
  39. }

  40. void SYS_Init(void)
  41. {
  42.     /*---------------------------------------------------------------------------------------------------------*/
  43.     /* Init System Clock                                                                                       */
  44.     /*---------------------------------------------------------------------------------------------------------*/
  45.     /* Unlock protected registers */
  46.     SYS_UnlockReg();

  47.     /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
  48.     PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);
  49.     /* Enable HIRC clock (Internal RC 48 MHz) */
  50.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
  51.     /* Wait for HIRC clock ready */
  52.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
  53.     /* Set core clock as 51MHz from PLL */
  54.     CLK_SetCoreClock(FREQ_51MHZ);
  55.         /* System Tick Configuration */

  56.         CLK_EnableSysTick(CLK_CLKSEL0_STCLKSEL_HCLK,SystemCoreClock / RT_TICK_PER_SECOND);
  57.     /* Enable UART clock */
  58.     CLK_EnableModuleClock(UART0_MODULE);
  59.     /* Select UART clock source from HIRC */
  60.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));
  61.     /* Update System Core Clock */
  62.     /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
  63.     SystemCoreClockUpdate();
  64.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  65.     SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk))    |       \

  66.                     (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

  67.     /* Lock protected registers */
  68.     SYS_LockReg();
  69. }

  70. /**
  71. * This function will initial your board.
  72. */
  73. void rt_hw_board_init(void)
  74. {
  75. //#error "TODO 1: OS Tick Configuration."
  76.     /*
  77.      * TODO 1: OS Tick Configuration
  78.      * Enable the hardware timer and call the rt_os_tick_callback function
  79.      * periodically with the frequency RT_TICK_PER_SECOND.
  80.      */

  81.     /* Call components board initial (use INIT_BOARD_EXPORT()) */
  82. #ifdef RT_USING_COMPONENTS_INIT
  83.     rt_components_board_init();
  84. #endif

  85. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
  86.     rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
  87. #endif
  88. }

  89. #ifdef RT_USING_CONSOLE

  90. static int uart_init(void)
  91. {
  92. //#error "TODO 2: Enable the hardware uart and config baudrate."
  93.     SYS_ResetModule(UART0_RST);
  94.     /* Configure UART0 and set UART0 baud rate */
  95.     UART_Open(UART0, 115200);
  96.     return 0;
  97. }
  98. INIT_BOARD_EXPORT(uart_init);

  99. void rt_hw_console_output(const char *str)
  100. {
  101. //#error "TODO 3: Output the string 'str' through the uart."
  102.     UART_Write(UART0,(uint8_t *)str,rt_strlen(str));        
  103. }
  104. #endif
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:49 | 显示全部楼层
五、测试代码
  1. #include "stdio.h"
  2. #include <NuMicro.h>
  3. #include <rtthread.h>

  4. //配置优先级,栈大小,时间片,设置不对没法运行的。

  5. #define THREAD_PRIORITY         5

  6. #define THREAD_STACK_SIZE       256

  7. #define THREAD_TIMESLICE        10

  8. void led(void *parameter)
  9. {
  10.     rt_kprintf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
  11.     rt_kprintf("+-------------------------------------------------+\n");
  12.     rt_kprintf("|    PB14(Output)  Sample Code     |\n");
  13.     rt_kprintf("+-------------------------------------------------+\n\n");
  14.     rt_kprintf("Hello RTT_NANO\n");

  15.     while(1)

  16.     {

  17.         PB14=0;
  18.         rt_thread_mdelay(2000);
  19.         rt_kprintf("\nLED1 is ON\n");
  20.         PB14=1;
  21.         rt_thread_mdelay(2000);
  22.         rt_kprintf("\nLED1 is OFF\n");      
  23.     }
  24. }

  25. /* 导出到 msh 命令列表中 */

  26. MSH_CMD_EXPORT(led, RT-Thread first led sample);

  27. void led2(void *parameter)
  28. {
  29.     rt_kprintf("Hello RTT_NANO\n");

  30.     while(1)
  31.     {
  32.         PB14=0;
  33.         rt_thread_mdelay(3000);
  34.         rt_kprintf("\nLED2 is ON\n");
  35.         PB14=1;
  36.         rt_thread_mdelay(3000);
  37.         rt_kprintf("\nLED2 is OFF\n");         
  38.     }
  39. }

  40. MSH_CMD_EXPORT(led2, RT-Thread second led sample);

  41. int led_sample(void)
  42. {
  43.     static rt_thread_t tid = RT_NULL;
  44.     static rt_thread_t tid2 = RT_NULL;

  45.         /* 创建线程1 */

  46.     tid = rt_thread_create("thread1",

  47.                             led, RT_NULL,

  48.                             THREAD_STACK_SIZE,

  49.                             THREAD_PRIORITY, THREAD_TIMESLICE);

  50.    

  51.     if (tid != RT_NULL)      

  52.         rt_thread_startup(tid);

  53.         /* 创建线程2 */

  54.     tid2 = rt_thread_create("thread2",

  55.                             led2, RT_NULL,

  56.                             THREAD_STACK_SIZE,

  57.                             THREAD_PRIORITY, THREAD_TIMESLICE);

  58.    

  59.     if (tid2 != RT_NULL)      

  60.         rt_thread_startup(tid2);               

  61.                 //该例子共用PB14端口,所以一并在创建线程时候初始化为输出模式

  62.     GPIO_SetMode(PB, BIT14, GPIO_MODE_OUTPUT);               

  63.     return 0;
  64. }

  65. MSH_CMD_EXPORT(led_sample, RT-Thread sample);

  66. /*---------------------------------------------------------------------------------------------------------*/

  67. /*  Main Function                                                                                          */

  68. /*---------------------------------------------------------------------------------------------------------*/
  69. int32_t main(void)

  70. {
  71.     led_sample();

  72.     return 0;

  73. }
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:50 | 显示全部楼层
六、rt-thread nano对新塘M0的适配还是很简单的,新建工程->添加组件->添加驱动库->屏蔽hard_fault_handler函数->按照错误提示修改系统时钟驱动接口->测试
在secureCRT打印不会换行还没找原因
356526442b0a7df9a1.png
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:50 | 显示全部楼层
只能在SSCOM下先用着
903916442b0b42a075.png
 楼主| 花间一壶酒sd 发表于 2023-4-21 23:50 | 显示全部楼层
完整工程下载连接:https://download.csdn.net/download/dmjkun/85059255
Pulitzer 发表于 2024-6-6 07:06 | 显示全部楼层

STM32芯片中有多个工作时钟源的外设很常见
童雨竹 发表于 2024-6-6 09:02 | 显示全部楼层
童雨竹 发表于 2024-6-6 09:02 | 显示全部楼层

CPU借助于APB总线访问相关寄存器达到对I2C1工作模块的控制
Wordsworth 发表于 2024-6-6 10:05 | 显示全部楼层

ART2固定使用PCLK时钟,只有开启和关闭的问题,不存在其它时钟源选择
Clyde011 发表于 2024-6-6 11:08 | 显示全部楼层

一部分是I2C1的工作模块,另外一部分是其控制模块
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

1217

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部

99

主题

1217

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部