【国产MCU移植】HC32F460基于Keil MDK 移植 RT-Thread Nano

2023-10-18 01:48

本文主要是介绍【国产MCU移植】HC32F460基于Keil MDK 移植 RT-Thread Nano,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文由RT-Thread论坛用户@想当诸侯的小蚂蚁原创发布:https://club.rt-thread.org/ask/article/2966.html

软件

根据厂家demo重新新建工程,工程中包含了gpio、usart。

硬件:

gpio

/* GREEN_LED Port/Pin definition */
#define  GREEN_LED_PORT        (PortE)
#define  GREEN_LED_PIN         (Pin00)
/* RED_LED Port/Pin definition */
#define  RED_LED_PORT        (PortE)
#define  RED_LED_PIN         (Pin01)

usart4

/* USART RX Port/Pin definition */
#define USART_RX_PORT                   (PortC)
#define USART_RX_PIN                    (Pin07)
#define USART_RX_FUNC                   (Func_Usart4_Rx)
/* USART TX Port/Pin definition */
#define USART_TX_PORT                   (PortC)
#define USART_TX_PIN                    (Pin06)
#define USART_TX_FUNC                   (Func_Usart4_Tx)

添加 RT-Thread Nano 到工程

在 Manage Rum-Time Environment 内打开 RTOS 栏,勾选 kernal,点击 OK 后就将 RT-Thread 内核加入到工程中了。

QQ截图20210812114523.png

适配 RT-Thread Nano

中断与异常处理

需要删除工程里中断服务例程文件 hc32f460_interrupts.c中异常处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler(),这两个函数已由 RT-Thread 实现,避免在编译时产生重复定义。

微信截图_20210812134247.png

系统时钟配置

需要在 board.c 中实现 系统时钟配置(为 MCU、外设提供工作时钟)与 os tick 的配置 (为操作系统提供心跳 / 节拍)。

void SysTick_Handler(void)
{rt_os_tick_callback(); 
}

void rt_hw_board_init(void)函数中调用系统时钟

    SysClkConfig();    //系统时钟初始化SysTick_Init(RT_TICK_PER_SECOND);   //OS Tick 频率配置

void SysClkConfig(void)所在文件system_hc32f460.c

void SysClkConfig(void)
{stc_clk_sysclk_cfg_t    stcSysClkCfg;  //系统时钟stc_clk_xtal_cfg_t      stcXtalCfg;    //晶振配置stc_clk_mpll_cfg_t      stcMpllCfg;    //PLLstc_sram_config_t           stcSramConfig;MEM_ZERO_STRUCT(stcSysClkCfg);MEM_ZERO_STRUCT(stcXtalCfg);MEM_ZERO_STRUCT(stcMpllCfg);/* Set bus clk div.    分频 */stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;  // 100MHz  stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;  // 50MHzstcSysClkCfg.enPclk0Div = ClkSysclkDiv1;  // 100MHzstcSysClkCfg.enPclk1Div = ClkSysclkDiv2;  // 50MHzstcSysClkCfg.enPclk2Div = ClkSysclkDiv4;  // 25MHzstcSysClkCfg.enPclk3Div = ClkSysclkDiv4;  // 25MHzstcSysClkCfg.enPclk4Div = ClkSysclkDiv2;  // 50MHzCLK_SysClkConfig(&stcSysClkCfg);//时钟分频/* Switch system clock source to MPLL. *//* Use Xtal as MPLL source. */stcXtalCfg.enMode        = ClkXtalModeOsc;//XTAL模式选择位 stcXtalCfg.enDrv         = ClkXtalLowDrv;/*XTAL驱动能力选择   stcXtalCfg.enFastStartup = Enable;/*XTAL超高速驱动允许  CLK_XtalConfig(&stcXtalCfg);//CMU XTAL  配置寄存器CLK_XtalCmd(Enable);//开启CMU XTAL  while(Set != CLK_GetFlagStatus(ClkFlagXTALRdy)){;}/* MPLL config. */stcMpllCfg.pllmDiv = 1ul;//MPLL输入时钟分频系数stcMpllCfg.plln    =50ul;//MPLL倍频系数stcMpllCfg.PllpDiv = 4ul;stcMpllCfg.PllqDiv = 4ul;stcMpllCfg.PllrDiv = 4ul;CLK_SetPllSource(ClkPllSrcXTAL);//时钟源选择  XTALCLK_MpllConfig(&stcMpllCfg);//CMU MPLL 时钟分频配置/* flash read wait cycle setting */EFM_Unlock();EFM_SetLatency(5ul);EFM_Lock();/* sram init include read/write wait cycle setting */stcSramConfig.u8SramIdx = Sram12Idx | Sram3Idx | SramHsIdx | SramRetIdx;stcSramConfig.enSramRC = SramCycle2;stcSramConfig.enSramWC = SramCycle2;stcSramConfig.enSramEccMode = EccMode3;stcSramConfig.enSramEccOp = SramNmi;stcSramConfig.enSramPyOp = SramNmi;SRAM_Init(&stcSramConfig);		/* Enable MPLL. */CLK_MpllCmd(Enable);//用于开始停止MPLL。0:MPLL动作开始 1:MPLL停止/* Wait MPLL ready. */while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy)){;}/* Switch system clock source to MPLL. */CLK_SetSysClkSource(CLKSysSrcMPLL);//CMU  系统时钟源切换寄存器
}

en_result_t SysTick_Init(uint32_t u32Freq)所在文件hc32f460_utility.c

__WEAKDEF en_result_t SysTick_Init(uint32_t u32Freq)
{en_result_t enRet = Error;if ((0UL != u32Freq) && (u32Freq <= 1000UL)){m_u32TickStep = 1000UL / u32Freq;/* Configure the SysTick interrupt */if (0UL == SysTick_Config(SystemCoreClock / u32Freq)){enRet = Ok;}}return enRet;
}

内存堆初始化

系统内存堆的初始化在 board.c 中的 rt_hw_board_init() 函数中完成,内存堆功能是否使用取决于宏 RT_USING_HEAP 是否开启,RT-Thread Nano 默认不开启内存堆功能,这样可以保持一个较小的体积,不用为内存堆开辟空间。
开启系统 heap 将可以使用动态内存功能,如使用 rt_malloc、rt_free 以及各种系统动态创建对象的 API。若需要使用系统内存堆功能,则打开 RT_USING_HEAP 宏定义即可,此时内存堆初始化函数 rt_system_heap_init() 将被调用,如下所示:

微信图片_20210812152921.png

编写第一个应用

1.使用rt_thread_mdelay()函数

移植RT-Thread Nano之前跑马灯使用厂家库函数

微信截图_20210812155454.png

移植RT-Thread Nano之后跑马灯使用

微信截图_20210812155338.png

2.建立线程

微信截图_20210812162440.png

在 Nano 上添加 UART 控制台

在 RT-Thread Nano 上添加 UART 控制台打印功能后,就可以在代码中使用 RT-Thread 提供的打印函数 rt_kprintf() 进行信息打印,从而获取自定义的打印信息,方便定位代码 bug 或者获取系统当前运行状态等。实现控制台打印(需要确认 rtconfig.h 中已使能 RT_USING_CONSOLE 宏定义),需要完成基本的硬件初始化,以及对接一个系统输出字符的函数。

实现串口初始化

rtconfig.h中 Configuration Wizard->Console Configuration开启RT_USING_CONSOLE

微信截图_20210812163833.png

usart.c

int rt_Usart_Init(void)
{uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4;const stc_usart_uart_init_t stcInitCfg = {UsartIntClkCkOutput,UsartClkDiv_1,UsartDataBits8,UsartDataLsbFirst,UsartOneStopBit,UsartParityNone,UsartSampleBit8,UsartStartBitFallEdge,UsartRtsEnable,};/* Enable peripheral clock */PWC_Fcg1PeriphClockCmd(u32Fcg1Periph, Enable);/* Initialize USART IO */PORT_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_FUNC, Disable);PORT_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_FUNC, Disable);/* Initialize UART */while(Ok != USART_UART_Init(USART_CH, &stcInitCfg));/* Set baudrate */while(Ok !=  USART_SetBaudrate(USART_CH, USART_BAUDRATE));/*Enable RX && RX  function*/USART_FuncCmd(USART_CH, UsartRx, Enable);USART_FuncCmd(USART_CH, UsartTx, Enable);return 0;
}
INIT_BOARD_EXPORT(rt_Usart_Init);
实现 rt_hw_console_output

usart.c

void rt_hw_console_output(const char *str)
{rt_size_t i = 0, size = 0;char a = '\r';size = rt_strlen(str);for (i = 0; i < size; i++){if (*(str + i) == '\n'){while (Reset == USART_GetStatus(USART_CH, UsartTxEmpty)) {}; /* Warit Tx data register empty */USART_SendData(USART_CH,(uint16_t)a);}while (Reset == USART_GetStatus(USART_CH, UsartTxEmpty)){};  /* Warit Tx data register empty */USART_SendData(USART_CH,(*(str + i)));}
}

RT_WEAK修饰函数 board.c中rt_hw_console_output(const char *str),不然会报重定义。

RT_WEAK void rt_hw_console_output(const char *str)
{
//#error "TODO 3: Output the string 'str' through the uart."
}
验证结果

微信截图_20210812180303.png

##在 Nano 上添加 FinSH 组件(实现命令输入)
####添加FinSH组件
点击 Manage Run-Environment,勾选 shell,这将自动把 FinSH 组件的源码到工程

微信截图_20210812180550.png

rtconfig.h中 Configuration Wizard->Console Configuration开启RT_USING_CONSOLE

微信截图_20210812180817.png

实现rt_hw_console_getchar(void)函数

usart.c

char rt_hw_console_getchar(void)
{int ch = -1;if (Set == USART_GetStatus(USART_CH, UsartRxNoEmpty)){ch = USART_RecData(USART_CH);}return ch;
}
验证结果

finsh.gif

HC32F460移植RT-Thread Nano结束

在这里插入图片描述

近来芯片缺货大幕拉开,掀起新一轮国产替代浪潮。RT-Thread发起一场国产MCU移植贡献活动,邀请开发者们参加!
活动详情:国潮崛起!RT-Thread国产MCU移植贡献活动开启!

这篇关于【国产MCU移植】HC32F460基于Keil MDK 移植 RT-Thread Nano的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/229369

相关文章

MCU7.keil中build产生的hex文件解读

1.hex文件大致解读 闲来无事,查看了MCU6.用keil新建项目的hex文件 用FlexHex打开 给我的第一印象是:经过软件的解释之后,发现这些数据排列地十分整齐 :02000F0080FE71:03000000020003F8:0C000300787FE4F6D8FD75810702000F3D:00000001FF 把解释后的数据当作十六进制来观察 1.每一行数据

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

Thread如何划分为Warp?

1 .Thread如何划分为Warp? https://jielahou.com/code/cuda/thread-to-warp.html  Thread Index和Thread ID之间有什么关系呢?(线程架构参考这里:CUDA C++ Programming Guide (nvidia.com)open in new window) 1维的Thread Index,其Thread

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

RT-Thread(Nano版本)的快速移植(基于NUCLEO-F446RE)

目录 概述 1 RT-Thread 1.1 RT-Thread的版本  1.2 认识Nano版本 2 STM32F446U上移植RT-Thread  2.1 STM32Cube创建工程 2.2 移植RT-Thread 2.2.1 安装RT-Thread Packet  2.2.2 加载RT-Thread 2.2.3 匹配相关接口 2.2.3.1 初次编译代码  2.2.3.

PC/MCU/SoC使用的计算机架构(Architecture)

1. 冯·诺依曼结构 冯·诺依曼结构(Von Neumann Architecture)是计算机系统的经典架构,由数学家约翰·冯·诺依曼在1945年提出。它的核心思想是程序存储器和数据存储器共享同一存储设备,程序和数据以相同的方式存储和访问。冯·诺依曼架构的主要特点包括: 单一存储器:存储程序指令和数据在同一个存储器中。控制单元:通过程序计数器顺序执行指令。数据路径:通过一个共享的总线,将数据

目标检测-RT-DETR

RT-DETR (Real-Time Detection Transformer) 是一种结合了 Transformer 和实时目标检测的创新模型架构。它旨在解决现有目标检测模型在速度和精度之间的权衡问题,通过引入高效的 Transformer 模块和优化的检测头,提升了模型的实时性和准确性。RT-DETR 可以直接用于端到端目标检测,省去了锚框设计,并且在推理阶段具有较高的速度。 RT-DET

nano 和 vim对比

nano 和 vim 是两种流行的文本编辑器,各有优缺点和适用场景。以下是对这两种编辑器的详细对比: Nano 优点: 1.简单易用:nano 的界面和命令非常简单,易于新手上手。所有的命令都列在屏幕底部,不需要记住复杂的命令。 2. 直接编辑:打开文件后可以直接开始编辑,不需要进入插入模式。 3. 轻量便捷:通常预装在大多数Linux发行版上,启动速度快。 缺点: 1.功能有限:相比于vim

GTK中创建线程函数g_thread_new和g_thread_create的区别

使用GThread函数,需要引用glib.h头文件。 这两个接口的核心区别就是  g_thread_create 是旧的接口,现在已经不使用了,而g_thread_new是新的接口,建议使用。 g_thread_create: g_thread_create has been deprecated since version 2.32 and should not be used in n