本文转载于极术社区
作者:曾是一颗薏米
前言
近期,笔者有幸获得灵动微 MM32F5265 开发板的体验资格。MM32F5260 搭载了 arm china "Star-MC1 内核"处理器,拥有高性能,主打家电和工业等高可靠性应用领域。 总结一下,有以下亮点:
本土团队打造,完全自主可控,采用全国产化供应链;
基于 Armv8-M 架构,带有 L1 I-Cache & D-Cache,对比市面主流的 M3/M4,有 20%性能提升;
通过 I-Cache 实现对 flash 的零延迟访问,拥有零延迟 AHB 总线矩阵,支持多并发总线;
拥有信号间互联矩阵,可对多个事件进行逻辑组合,可实现较为复杂的功能;
移植
本次 rt-thread 的移植参考了 “Rice 我叫加饭?” 的博文:https://aijishu.com/a/1060000000347637 参考代码: https://gitee.com/RiceChen0/mm32f5270_rtt(感谢原作者的付出) 这里我重点说一下不一样的地方:
1.打印重定向到虚拟串口
虽然 Mini-F5265-OB 开发板上没有板载 CH340,但这也不影响交互功能,官方提供了一种新的途径:通过板载的 MM32-LINK-OB 的虚拟串口来实现串口的交互。 简述实现的流程:
PC 通过 USB 连接板载的 MM32-LINK-OB;
板载的 MM32-LINK-OB 将 USB 数据转发成 SWD 接口信号和串口的 tx/rx 信号;
最终信号达到 Mini-F5265-OB 开发板,实现串口的交互和程序的烧写功能;
板载的 MM32-LINK-OB,连接如下图所示:
Mini-F5265-OB 开发板,连接如下图所示:
因此,移植的第一步就是要用上虚拟串口。
通过查看上述的原理图可知虚拟串口用到 uart3。
修改 drv_uart.h,添加 uart3 支持:
#if defined(BSP_USING_UART3) #ifndef UART3_CONFIG #define UART3_CONFIG { .name = "uart3", .rx_gpiox = GPIOC, .rx_rcc_clock = RCC_AHBPeriph_GPIOC, .rx_pin = GPIO_Pin_11, .rx_gpio_af = GPIO_AF_7, .tx_gpiox = GPIOB, .tx_rcc_clock = RCC_AHBPeriph_GPIOC, .tx_pin = GPIO_Pin_10, .tx_gpio_af = GPIO_AF_7, .uart_rcc_clock = RCC_APB1Periph_UART3, .uartx = UART3, .irq_type = UART3_IRQn, } #endif /* UART3_CONFIG */ #endif /* BSP_USING_UART3 */
修改 drv_uart.c,uart3 使用的 PC10 和 PC11 需要初始化:
static int rt_hw_uart_gpio_init(struct mm32_uart_config *cfg) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART3, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_7); GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_7); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOC, &GPIO_InitStruct); return RT_EOK; }修改 drv_uart.c,实现 mm32_uart_ops(由于篇幅原因,这里仅截取关键部分)
static rt_err_t mm32_control(struct rt_serial_device *serial, int cmd, void *arg) { struct mm32_uart *uart; rt_ubase_t ctrl_arg = (rt_ubase_t)arg; RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct mm32_uart, serial); switch (cmd) { case RT_DEVICE_CTRL_SET_INT: { UART_ITConfig(uart->config->uartx, UART_IT_RX, ENABLE); NVIC_EnableIRQ(uart->config->irq_type); break; } case RT_DEVICE_CTRL_CLR_INT: { UART_ITConfig(uart->config->uartx, UART_IT_RX, DISABLE); NVIC_DisableIRQ(uart->config->irq_type); break; } } return 0; } static int mm32_putc(struct rt_serial_device *serial, char c) { struct mm32_uart *uart; RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct mm32_uart, serial); UART_SendData(uart->config->uartx, (uint8_t)(c)); while (RESET == UART_GetFlagStatus(uart->config->uartx, UART_FLAG_TXC)) {}; return 1; } static int mm32_getc(struct rt_serial_device *serial) { struct mm32_uart *uart; int ch = -1; RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct mm32_uart, serial); if(UART_GetFlagStatus(uart->config->uartx, UART_FLAG_RXAVL)) { ch = UART_ReceiveData(uart->config->uartx); return ch; } return -1; } static void uart_isr(struct rt_serial_device *serial) { struct mm32_uart *uart; RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct mm32_uart, serial); if(SET == UART_GetFlagStatus(uart->config->uartx, UART_IT_RX)) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } } void UART3_IRQHandler(void) { rt_interrupt_enter(); uart_isr(&(uart_obj[UART3_INDEX].serial)); rt_interrupt_leave(); }
2.添加 hal 库等文件
从官方的提供的例程资料中找到 HAL_Lib 文件夹,将里面的头文件和源文件拷贝工程的 libraries/drivers 目录里面。
修改 libraries/drivers 的 mm32f5260.h,定义“USE_STDPERIPH_DRIVER”的宏。(注意官方提供的默认没有定义该宏,需要定义后才会编译标准外设驱动库)
在 libraries/drivers 目录创建 hal_common.h,并在里面包含"hal_conf.h",目的是在外面可以调到 hal 层的函数接口。
将官方提供的 core_starmc1.h 拷贝到工程的 libraries/libraries/CMSIS/Include 目录下,替换原来的 core_star.h。
将官方提供的 source 文件夹里面的文件整理到 libraries 和 mdk 目录。
注:以上仅列出关键部分,其余详见代码仓库。
3.实现 systisk
跟以往不同的是:本次使用的 SDK 里面已经实现了对系统时钟的初始化(system_mm32f5260.c),我们仅需实现 systisk 即可,代码如下:
void SysTick_Init(void) { uint32_t reload = 0; SysTick->CTRL &= (uint32_t)0xFFFFFFFB; reload = CLOCK_SYSTICK_FREQ/RT_TICK_PER_SECOND; reload--; SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; SysTick->LOAD = reload; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; } void SysTick_Handler(void) { /* enter interrupt */ rt_interrupt_enter(); rt_tick_increase(); /* leave interrupt */ rt_interrupt_leave(); } void rt_hw_board_init() { SysTick_Init(); SystemClock_Config(); #if defined(RT_USING_HEAP) rt_system_heap_init(HEAP_BEGIN, (void *)HEAP_END); #endif #ifdef RT_USING_SERIAL extern int rt_hw_uart_init(void); rt_hw_uart_init(); #endif #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE) rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif }
移植效果
到此为止,基本上已经完成了移植工作。
编译,烧写,可以到 rt-thread 的打印:
查看开发板可看到 LED2 隔 500ms 闪烁一次。
总结
本次移植过程修改的地方不多,主要是因为 SDK 变动而做的修改。在此,可以看到灵动微在维护 hal 库做出的努力。毕竟 hal 层兼容性越强,可以吸收更多潜在用户,节省用户熟悉 SDK 的时间,这也是国产芯片替代的必经之路。
最后,感谢灵动微和极术社区提供的平台,也祝愿国产芯片越来越好。
仓库代码: https://gitee.com/sakura96888/mm32f5260_rtt
转自 | 极术社区
全部0条评论
快来发表一下你的评论吧 !