- #include "main.h"
- #include "platform.h"
- void InitLED(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOC, &GPIO_InitStruct);
- GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);
- }
- int main(void)
- {
- PLATFORM_Init();
- InitLED();
- while (1)
- {
- GPIO_WriteBit(GPIOC, GPIO_Pin_13, (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13) == Bit_RESET) ? Bit_SET : Bit_RESET);
- SysTick_DelayMS(200);
- }
- }
platform.c & platform.h
- #include "platform.h"
- #include "SEGGER_RTT.h"
- volatile uint32_t SysTick_DelayTick = 0;
- void PLATFORM_InitSysTick(void)
- {
- RCC_ClocksTypeDef RCC_Clocks;
- RCC_GetClocksFreq(&RCC_Clocks);
- if (SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000))
- {
- while (1)
- {
- }
- }
- NVIC_SetPriority(SysTick_IRQn, 0x0);
- }
- void SysTick_DelayMS(uint32_t Tick)
- {
- SysTick_DelayTick = Tick;
- while (SysTick_DelayTick)
- {
- }
- }
- void PLATFORM_InitConsole(void)
- {
- SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
- }
- int fputc(int ch, FILE *f)
- {
- SEGGER_RTT_PutCharSkip(0, (char)ch);
- return (ch);
- }
- void PLATFORM_PrintInfo(void)
- {
- RCC_ClocksTypeDef RCC_Clocks;
- printf("\r\n");
- printf("\r\nMCU : MM32F3273G6P");
- printf("\r\n");
- switch (RCC->CFGR & RCC_CFGR_SWS)
- {
- case 0x00:
- printf("\r\nHSI used as system clock source");
- break;
- case 0x04:
- printf("\r\nHSE used as system clock source");
- break;
- case 0x08:
- if (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC)
- {
- printf("\r\nPLL (clocked by HSE) used as system clock source");
- }
- else
- {
- printf("\r\nPLL (clocked by HSI) used as system clock source");
- }
- break;
- case 0x0C:
- printf("\r\nLSI used as system clock source");
- break;
- default:
- break;
- }
- RCC_GetClocksFreq(&RCC_Clocks);
- printf("\r\n");
- printf("\r\nSYSCLK Frequency : %7.3f MHz", (double)RCC_Clocks.SYSCLK_Frequency / (double)1000000.0);
- printf("\r\nHCLK Frequency : %7.3f MHz", (double)RCC_Clocks.HCLK_Frequency / (double)1000000.0);
- printf("\r\nPCLK1 Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK1_Frequency / (double)1000000.0);
- printf("\r\nPCLK2 Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK2_Frequency / (double)1000000.0);
- printf("\r\n");
- }
- void PLATFORM_Init(void)
- {
- PLATFORM_InitSysTick();
- PLATFORM_InitConsole();
- PLATFORM_PrintInfo();
- }
- #ifndef __PLATFORM_H
- #define __PLATFORM_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <stdio.h>
- #include "hal_conf.h"
- void PLATFORM_Init(void);
- void SysTick_DelayMS(uint32_t Tick);
- #ifdef __cplusplus
- }
- #endif
- #endif
mm32f3270_it.c
- #include "mm32f3270_it.h"
- extern volatile uint32_t SysTick_DelayTick;
- void NMI_Handler(void)
- {
- while (1)
- {
- }
- }
- void HardFault_Handler(void)
- {
- while (1)
- {
- }
- }
- void MemManage_Handler(void)
- {
- while (1)
- {
- }
- }
- void BusFault_Handler(void)
- {
- while (1)
- {
- }
- }
- void UsageFault_Handler(void)
- {
- while (1)
- {
- }
- }
- void SVCall_Handler(void)
- {
- }
- void DebugMon_Handler(void)
- {
- }
- void PendSV_Handler(void)
- {
- }
- void SysTick_Handler(void)
- {
- if (SysTick_DelayTick)
- {
- SysTick_DelayTick--;
- }
- }
基础工程附件:
MM32F3270_BASE.zip
(6.82 MB, 下载次数: 7)
3.移植RTX5实时操作系统
3.1.在基础工程的工具栏点击Manage Run-Time Environment图标
3.2.在弹出的Manage Run-Time Environment窗口中,勾选CMSIS->RTOS2(API)->Keil RTX5,Variant列选择Souce(源码形式)
3.3.点击Manage Run-Time Environment窗口中左下角的Resolve按钮,通过这个按钮解决所有的依赖关系警告,最后点击OK
3.4.我们看到当前工程中之前已经添加了STARTUP中的system_mm32f327x.c和startup_mm32f327x_keil.s这两个文件,在刚刚又自动添加了Device以及这两个文件,这时就重复了,所以我们右击Device,点击Options for Component Class 'Device',在弹出的窗口中,将Include in Target build这个选项勾选去掉
3.5.在CMSIS组中,打开RTX_Config.h文件,使用Configuration Wizard模式进行配置,如下所示
3.6.在mm32f3270_it.c和mm32f3270_it.h中注释掉与SVCall_Handler、PendSV_Handler、以及SysTick_Handler相关的部分,如下所示:
- #include "mm32f3270_it.h"
- //extern volatile uint32_t SysTick_DelayTick;
- void NMI_Handler(void)
- {
- while (1)
- {
- }
- }
- void HardFault_Handler(void)
- {
- while (1)
- {
- }
- }
- void MemManage_Handler(void)
- {
- while (1)
- {
- }
- }
- void BusFault_Handler(void)
- {
- while (1)
- {
- }
- }
- void UsageFault_Handler(void)
- {
- while (1)
- {
- }
- }
- //void SVCall_Handler(void)
- //{
- //}
- void DebugMon_Handler(void)
- {
- }
- //void PendSV_Handler(void)
- //{
- //}
- //void SysTick_Handler(void)
- //{
- // if (SysTick_DelayTick)
- // {
- // SysTick_DelayTick--;
- // }
- //}
- #ifndef __MM32F3270_IT_H
- #define __MM32F3270_IT_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include "hal_conf.h"
- void NMI_Handler(void);
- void HardFault_Handler(void);
- void MemManage_Handler(void);
- void BusFault_Handler(void);
- void UsageFault_Handler(void);
- //void SVCall_Handler(void);
- void DebugMon_Handler(void);
- //void PendSV_Handler(void);
- //void SysTick_Handler(void);
- #ifdef __cplusplus
- }
- #endif
- #endif
3.7.在platform.c和platform.h中注释掉与SysTick相关的部分,如下所示:
- #include "platform.h"
- #include "SEGGER_RTT.h"
- //volatile uint32_t SysTick_DelayTick = 0;
- //void PLATFORM_InitSysTick(void)
- //{
- // RCC_ClocksTypeDef RCC_Clocks;
- // RCC_GetClocksFreq(&RCC_Clocks);
- // if (SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000))
- // {
- // while (1)
- // {
- // }
- // }
- // NVIC_SetPriority(SysTick_IRQn, 0x0);
- //}
- //void SysTick_DelayMS(uint32_t Tick)
- //{
- // SysTick_DelayTick = Tick;
- // while (SysTick_DelayTick)
- // {
- // }
- //}
- void PLATFORM_InitConsole(void)
- {
- SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
- }
- int fputc(int ch, FILE *f)
- {
- SEGGER_RTT_PutCharSkip(0, (char)ch);
- return (ch);
- }
- void PLATFORM_PrintInfo(void)
- {
- RCC_ClocksTypeDef RCC_Clocks;
- printf("\r\n");
- printf("\r\nMCU : MM32F3273G6P");
- printf("\r\n");
- switch (RCC->CFGR & RCC_CFGR_SWS)
- {
- case 0x00:
- printf("\r\nHSI used as system clock source");
- break;
- case 0x04:
- printf("\r\nHSE used as system clock source");
- break;
- case 0x08:
- if (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC)
- {
- printf("\r\nPLL (clocked by HSE) used as system clock source");
- }
- else
- {
- printf("\r\nPLL (clocked by HSI) used as system clock source");
- }
- break;
- case 0x0C:
- printf("\r\nLSI used as system clock source");
- break;
- default:
- break;
- }
- RCC_GetClocksFreq(&RCC_Clocks);
- printf("\r\n");
- printf("\r\nSYSCLK Frequency : %7.3f MHz", (double)RCC_Clocks.SYSCLK_Frequency / (double)1000000.0);
- printf("\r\nHCLK Frequency : %7.3f MHz", (double)RCC_Clocks.HCLK_Frequency / (double)1000000.0);
- printf("\r\nPCLK1 Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK1_Frequency / (double)1000000.0);
- printf("\r\nPCLK2 Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK2_Frequency / (double)1000000.0);
- printf("\r\n");
- }
- void PLATFORM_Init(void)
- {
- // PLATFORM_InitSysTick();
- PLATFORM_InitConsole();
- PLATFORM_PrintInfo();
- }
- #ifndef __PLATFORM_H
- #define __PLATFORM_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <stdio.h>
- #include "hal_conf.h"
- void PLATFORM_Init(void);
- //void SysTick_DelayMS(uint32_t Tick);
- #ifdef __cplusplus
- }
- #endif
- #endif
3.8.修改main.c文件,添加RTX5部分功能,实现LED每间隔200ms闪烁一下,如下所示:
- #include "main.h"
- #include "platform.h"
- #include "cmsis_os2.h"
- void InitLED(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOC, &GPIO_InitStruct);
- GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);
- }
- const osThreadAttr_t osThreadAttr_Start =
- {
- .name = "Start",
- .attr_bits = osThreadDetached,
- .priority = osPriorityHigh4,
- .stack_size = 2048,
- };
- osThreadId_t osThreadId_Start = NULL;
- const osThreadAttr_t osThreadAttr_LED =
- {
- .name = "LED",
- .attr_bits = osThreadDetached,
- .priority = osPriorityHigh2,
- .stack_size = 512,
- };
- osThreadId_t osThreadId_LED = NULL;
- void osThreadFunc_LED(void *argument)
- {
- InitLED();
- while (1)
- {
- GPIO_WriteBit(GPIOC, GPIO_Pin_13, (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13) == Bit_RESET) ? Bit_SET : Bit_RESET);
- osDelay(200);
- }
- }
- void osThreadFunc_Start(void *argument)
- {
- osThreadId_LED = osThreadNew(osThreadFunc_LED, NULL, &osThreadAttr_LED);
- while (1)
- {
- osDelay(1);
- }
- }
- int main(void)
- {
- PLATFORM_Init();
- osKernelInitialize();
- osThreadId_Start = osThreadNew(osThreadFunc_Start, NULL, &osThreadAttr_Start);
- osKernelStart();
- while (1)
- {
- }
- }
3.9.到此基于MM32F3270系列MCU的RTX5实时操作系统移植就完成了,接下来,我们来编译、下载、运行,查看是否正常……
4.调试过程
4.1.编译时,我们发现了2个Error,提示如下:
解决办法:在RTE_Componets.h文件中添加SystemCoreClock外部变量的调用声明,如下所示,再进行编译就没有报错了。
4.2.下载 & 调试
将编译无误的程序下载到MM32F3270芯片中去运行,结果发现LED灯并没有如预期的在闪烁……我们进行在线Debug,在全速运行后,进行暂停,这时发现程序一直停在了SVCall_Handler中断处理中;但是这个中断应该是被RTX5实时系统自行实现并调用的中断,怎么会出现空跑的情况呢?
解决办法:我们退出调试状态,在CMSIS分组中,查看irq_armv7m.S这个文件,发现RTX5的SVC中断名为SVC_Handler,与startup_mm32f327x_keil.s文件中定义的SVCall_Handler并不一致,所以我先同步一个中断函数的命名,将startup_mm32f327x_keil.s文件中的SVCall_Handler出现的地方都修改为SVC_Handler
4.3.对修改后的工程进行重新编译,并下载到芯片中运行,这个时候板载的LED每间隔200ms就会切换一次显示状态了,到此基于MM32F3270移植的RTX5实时操作系统就完成了,工程附件如下
RTX5工程文件:
MM32F3270_RTX5.zip
(7.42 MB, 下载次数: 10)