- ; PlatformIO Project Configuration File
- ;
- ; Build options: build flags, source filter
- ; Upload options: custom upload port, speed and extra flags
- ; Library options: dependencies, extra library storages
- ; Advanced options: extra scripting
- ;
- ; Please visit documentation for the other options and examples
- ; https://docs.platformio.org/page/projectconf.html
- [env:genericSTM32F103ZE]
- platform = ststm32
- board = genericSTM32F103ZE ;实际为 MM32F3273_MB039
- framework = cmsis
- upload_protocol = jlink ; 代码上传工具,
- debug_tool = jlink ; debug工具
- build_flags = ; Build options
- -Isrc
- -Isrc/CORE
- -Isrc/HARDWARE/LED
- -Isrc/MM32F327x_FWLib/inc
- -Isrc/SYSTEM/DELAY
- -Isrc/SYSTEM/SYS
- -Isrc/SYSTEM/UART
- -D STM32F10X_HD ; 定义全局宏
- -D USE_STDPERIPH_DRIVER
类似于 keil ,上面代码配置定义好了平台、板子、框架软件包、调试下载工具类型、用户头文件路径以及其它一些全局宏定义等等。
5. 需要知道,PIO 的集成编译器是依赖于 toolchain-gccarmnoneeabi 的,所以源码中的一些不适合 gcc 编译器的地方都得改正过来,最后编译即可,点击编译可以是通过下方的“√”,也可通过 PIO PROJECT TASKS 中的 Build Task 按键。
到这里已经很轻松地完成了 STM32F103 的示例工程导入,通过这一系列的操作,也已经熟悉了 PIO 的开发流程,那接下来就是要做替换了,由于使用的是 CMSIS 框架,与平台相关的外设驱动包改动不涉及框架支持包的重写,所以会稍微容易实现些。下面为替换步骤:
1. 通过查看 ststm32 平台包,熟悉整个 PIO 平台支持包的内容含义,明确要改写哪些文件
2. 由于开发板选择的是 genericSTM32F103ZE ,对应的文件为 genericSTM32F103ZE.json ,其中主要改写调试相关的选择为:
- "debug": {
- "jlink_device": "MM32F3273G9P",
- "openocd_target": "stm32f1x",
- "svd_path": "MM32F327x.svd"
- },
特别注意,core 、 extra_flags 、mcu 、variant 等几项选择不能改写,否则会影响其它支持包的适配,关于 name 和 vendor 这2项是可以修改的,这个会直接体现在 PIO 主页新建工程时候的 board 选项显示中。
3. 在 misc - svd 中需要添加 MM32F327x.svd ,该文件可以通过灵动微官方的 keil pack 中获取到,该文件描述了芯片的寄存器,在后面调试时可以对照参阅,如果不替换那么就会显示错误的寄存器数据。
4. 此外,还需要对依赖的包做内容修改替换,这里只涉及到“packages\framework-cmsis-stm32f1”这个包,需要将 Include 文件夹下与芯片相关的头文件全部替换掉,以及 Source - Templates 下的 system_stm32f1xx.c 需要更改内容为 system_mm32f3270.c 中的,名称不改,Source - Templates - gcc 中的 startup_stm32f103xe.s 需要更改为 startup_mm32f3270_gcc.s 中的内容,名称不改 ,Source - Templates - gcc - linker 中的 STM32F103XE_FLASH.ld 同样按照 mm32f3273g9p 去做修改。
- ////////////////////////////////////////////////////////////////////////////////
- /// [url=home.php?mod=space&uid=288409]@file[/url] SYSTEM_MM32.C
- /// [url=home.php?mod=space&uid=187600]@author[/url] AE TEAM
- /// [url=home.php?mod=space&uid=247401]@brief[/url] THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
- ////////////////////////////////////////////////////////////////////////////////
- /// @attention
- ///
- /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
- /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
- /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
- /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
- /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
- /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
- ///
- /// <H2><CENTER>© COPYRIGHT MINDMOTION </CENTER></H2>
- ////////////////////////////////////////////////////////////////////////////////
- // Define to prevent recursive inclusion
- #define _SYSTEM_MM32_C_
- // Files includes
- /// @addtogroup CMSIS
- /// @{
- #include "mm32_device.h"
- /// @}
- /// @}
- /// Uncomment the line corresponding to the desired System clock (SYSCLK)
- /// frequency (after reset the HSI is used as SYSCLK source)
- ///
- /// IMPORTANT NOTE:
- /// ==============
- /// 1. After each device reset the HSI is used as System clock source.
- ///
- /// 2. Please make sure that the selected System clock doesn't exceed y**ice's
- /// maximum frequency.
- ///
- /// 3. If none of the define below is enabled, the HSI is used as System clock
- /// source.
- ///
- /// 4. The System clock configuration functions provided based external crystal or HSE
- /// An external 8MHz crystal is used to drive the System clock.
- /// If you are using different crystal you have to modify HSE_VALUE in reg_common.h.
- // ### HSE_VALUE is defined in reg_common.h ###
- #ifndef HSE_VALUE
- #error "not define HSE_VALUE"
- #endif
- //#define SYSCLK_FREQ_XXMHz 96000000 //select [120000000,96000000,72000000,48000000,24000000]
- //#define SYSCLK_FREQ_HSE HSE_VALUE //use HSE_VALUE as system frequence
- #define SYSCLK_HSI_XXMHz 120000000 //select [120000000,96000000,72000000,48000000,24000000]
- //below message need to confirm Frequence at first, then comment these warning
- //#define DISABLE_FREQ_MACRO_CHECK
- #ifndef DISABLE_FREQ_MACRO_CHECK
- #if ((defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz)) && (defined(SYSCLK_HSI_XXMHz) || defined(SYSCLK_FREQ_XXMHz)) && (defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_HSI_XXMHz)))
- #error "define more than one Freq config"
- #elif (defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz))
- #if (defined(HSE_VALUE) && (HSE_VALUE == 8000000))
- #warning "current HSE = 8000000, if on board HSE freq is not equal to 8000000Hz, Please redefine HSE_VALUE value in reg_common.h #define HSE_VALUE"
- #undef HSE_VALUE
- #define HSE_VALUE 8000000
- #else
- #warning "on board HSE is not equal to 8000000Hz, Please double check"
- #endif
- #elif defined(SYSCLK_HSI_XXMHz)
- #warning "use PLL mode and PLL Source is HSI, Please double check"
- #else
- #warning "current HSI = 8000000Hz as SYSCLK"
- #endif
- #endif
- /// Uncomment the following line if you need to relocate your vector Table in
- /// Internal SRAM.
- ///#define VECT_TAB_SRAM
- #define VECT_TAB_OFFSET 0x0
- /// Vector Table base offset field.
- /// This value must be a multiple of 0x200.
- /// @}
- ///////////////////////////////////////////////////////////////
- ///Clock Definitions
- ///////////////////////////////////////////////////////////////
- #if defined SYSCLK_FREQ_HSE
- u32 SystemCoreClock = SYSCLK_FREQ_HSE;
- #elif defined SYSCLK_FREQ_XXMHz
- u32 SystemCoreClock = SYSCLK_FREQ_XXMHz;
- #elif defined SYSCLK_HSI_XXMHz
- u32 SystemCoreClock = SYSCLK_HSI_XXMHz;
- #else //HSI Selected as System Clock source
- u32 SystemCoreClock = HSI_VALUE;
- #endif
- /// @}
- static void SetSysClock(void);
- static void SetSysClockToAnyXX(void);
- /// @}
- /// [url=home.php?mod=space&uid=247401]@brief[/url] Setup the microcontroller system
- /// Initialize the Embedded Flash Interface, the PLL and update the
- /// SystemCoreClock variable.
- /// [url=home.php?mod=space&uid=536309]@NOTE[/url] This function should be used only after reset.
- /// @param None
- /// @retval None
- void SystemInit (void)
- {
- //Reset the RCC clock configuration to the default reset state(for debug purpose)
- //Set HSION bit
- RCC->CR |= (u32)0x00000001;
- //Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits
- RCC->CFGR &= (u32)0xF8FFC00C;
- //Reset HSEON, CSSON and PLLON bits
- RCC->CR &= (u32)0xFEF6FFFF;
- //Reset HSEBYP bit
- RCC->CR &= (u32)0xFFFBFFFF;
- //Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits
- RCC->CFGR &= (u32)0xFF3CFFFF;
- RCC->CR &= (u32)0x008FFFFF;
- //Disable all interrupts and clear pending bits
- RCC->CIR = 0x009F0000;
- //Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers
- //Configure the Flash Latency cycles and enable prefetch buffer
- SetSysClock();
- }
- /// @brief use to return the pllm&plln.
- /// @param pllclkSourceFrq : PLL source clock frquency;
- /// pllclkFrq : Target PLL clock frquency;
- /// plln : PLL factor PLLN
- /// pllm : PLL factor PLLM
- /// @retval amount of error
- u32 AutoCalPllFactor(u32 pllclkSourceFrq, u32 pllclkFrq, u8* plln, u8* pllm)
- {
- u32 n, m;
- u32 tempFrq;
- u32 minDiff = pllclkFrq;
- u8 flag = 0;
- for(m = 0; m < 4 ; m++) {
- for(n = 0; n < 64 ; n++) {
- tempFrq = pllclkSourceFrq * (n + 1) / (m + 1);
- tempFrq = (tempFrq > pllclkFrq) ? (tempFrq - pllclkFrq) : (pllclkFrq - tempFrq) ;
- if(minDiff > tempFrq) {
- minDiff = tempFrq;
- *plln = n;
- *pllm = m;
- }
- if(minDiff == 0) {
- flag = 1;
- break;
- }
- }
- if(flag != 0) {
- break;
- }
- }
- return minDiff;
- }
- static void DELAY_xUs(u32 count)
- {
- u32 temp;
- SysTick->CTRL = 0x0; //disable systick function
- SysTick->LOAD = count * 8; //time count for 1us with HSI as SYSCLK
- SysTick->VAL = 0x00; //clear counter
- SysTick->CTRL = 0x5; //start discrease with Polling
- do {
- temp = SysTick->CTRL;
- } while((temp & 0x01) && !(temp & (1 << 16))); //wait time count done
- SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //Close Counter
- SysTick->VAL = 0X00; //clear counter
- }
- /// @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
- /// @param None
- /// @retval None
- static void SetSysClock(void)
- {
- CACHE->CCR &= ~(0x3 << 3);
- CACHE->CCR |= 1;
- while((CACHE->SR & 0x3) != 2);
- SetSysClockToAnyXX();
- }
- u32 GetCurrentSysClockFreq(void)
- {
- u32 result;
- u32 clock, mul, div;
- switch (RCC->CFGR & RCC_CFGR_SWS) {
- case RCC_CFGR_SWS_LSI:
- result = LSI_VALUE;
- break;
- case RCC_CFGR_SWS_HSE:
- result = HSE_VALUE;
- break;
- case RCC_CFGR_SWS_PLL:
- clock = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC) ? (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLXTPRE) ? (HSE_VALUE >> 1) : HSE_VALUE)
- : HSI_VALUE_PLL_ON;
- mul = ((RCC->PLLCFGR & (u32)RCC_PLLCFGR_PLL_DN) >> RCC_PLLCFGR_PLL_DN_Pos) + 1;
- div = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL_DP) >> RCC_PLLCFGR_PLL_DP_Pos) + 1;
- result = clock * mul / div;
- break;
- default:
- result = HSI_VALUE;
- break;
- }
- return result;
- }
- /// @brief Sets System clock frequency to XXMHz and configure HCLK, PCLK2
- /// and PCLK1 prescalers.
- /// [url=home.php?mod=space&uid=536309]@NOTE[/url] This function should be used only after reset.
- /// @param None
- /// @retval None
- static void SetSysClockToAnyXX(void)
- {
- __IO u32 temp;
- #if defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz)
- __IO u32 StartUpCounter = 0, HSEStatus = 0;
- #endif
- #if defined(SYSCLK_FREQ_XXMHz) || defined(SYSCLK_HSI_XXMHz)
- __IO u32 tn, tm;
- u8 plln, pllm;
- #endif
-
- #if defined SYSCLK_FREQ_HSE
- SystemCoreClock = SYSCLK_FREQ_HSE;
- #elif defined SYSCLK_FREQ_XXMHz
- SystemCoreClock = SYSCLK_FREQ_XXMHz;
- #elif defined SYSCLK_HSI_XXMHz
- SystemCoreClock = SYSCLK_HSI_XXMHz;
- #else //HSI Selected as System Clock source
- SystemCoreClock = HSI_VALUE;
- #endif
-
- RCC->CR |= RCC_CR_HSION;
- while(!(RCC->CR & RCC_CR_HSIRDY));
- #if defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz)
- //PLL SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------
- //Enable HSE
- RCC->CR |= ((u32)RCC_CR_HSEON);
- #endif
- DELAY_xUs(5);
- if(SystemCoreClock > 96000000) {
- RCC->APB1ENR |= RCC_APB1ENR_PWR;
- PWR->CR &= ~(3 << 14);
- PWR->CR |= 2 << 14;
- }
- else if(SystemCoreClock > 48000000) {
- RCC->APB1ENR |= RCC_APB1ENR_PWR;
- PWR->CR &= ~(3 << 14);
- PWR->CR |= 1 << 14;
- }
- else {
- RCC->APB1ENR |= RCC_APB1ENR_PWR;
- PWR->CR &= ~(3 << 14);
- PWR->CR |= 0 << 14;
- }
- #if defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz)
- //Wait till HSE is ready and if Time out is reached exit
- while(1) {
- HSEStatus = RCC->CR & RCC_CR_HSERDY;
- if(HSEStatus != 0)
- break;
- StartUpCounter++;
- if(StartUpCounter >= (10 * HSE_STARTUP_TIMEOUT))
- return;
- }
- if ((RCC->CR & RCC_CR_HSERDY) == RESET) {
- //If HSE fails to start-up, the application will have wrong clock
- //configuration. User can add here some code to deal with this error
- HSEStatus = (u32)0x00;
- return;
- }
- HSEStatus = (u32)0x01;
- DELAY_xUs(5);
- #endif
- #if defined(SYSCLK_FREQ_XXMHz)
- SystemCoreClock = SYSCLK_FREQ_XXMHz;
- #elif defined(SYSCLK_FREQ_HSE)
- SystemCoreClock = HSE_VALUE;
- #elif defined(SYSCLK_HSI_XXMHz)
- SystemCoreClock = SYSCLK_HSI_XXMHz;
- #else
- SystemCoreClock = HSI_VALUE;
- #endif
- //Enable Prefetch Buffer
- FLASH->ACR |= FLASH_ACR_PRFTBE;
- //Flash 0 wait state ,bit0~2
- FLASH->ACR &= ~FLASH_ACR_LATENCY;
- temp = (SystemCoreClock - 1) / 24000000;
- FLASH->ACR |= (temp & FLASH_ACR_LATENCY);
-
- RCC->CFGR &= (~RCC_CFGR_HPRE) & ( ~RCC_CFGR_PPRE1) & (~RCC_CFGR_PPRE2);
- //HCLK = AHB = FCLK = SYSCLK divided by 4
- RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV4;
- //PCLK2 = APB2 = HCLK divided by 1, APB2 is high APB CLK
- RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
- if(SystemCoreClock > 72000000) {
- //PCLK1 = APB1 = HCLK divided by 4, APB1 is low APB CLK
- RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV4;
- }
- else if(SystemCoreClock > 36000000) {
- //PCLK1 = APB1 = HCLK divided by 2, APB1 is low APB CLK
- RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV2;
- }
-
- #if defined(SYSCLK_FREQ_XXMHz) || defined(SYSCLK_HSI_XXMHz)
-
- #if defined(SYSCLK_FREQ_XXMHz)
- AutoCalPllFactor(HSE_VALUE, SystemCoreClock, &plln, &pllm);
- RCC->PLLCFGR &= ~((u32) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE);
- RCC->PLLCFGR |= (u32) RCC_PLLCFGR_PLLSRC;
- #endif
- #if defined(SYSCLK_HSI_XXMHz)
- AutoCalPllFactor(HSI_VALUE_PLL_ON, SystemCoreClock, &plln, &pllm);
- RCC->PLLCFGR &= ~((u32) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE);
- RCC->PLLCFGR &= ~((u32) RCC_PLLCFGR_PLLSRC);
- #endif
- tm = (((u32)pllm) & 0x07);
- tn = (((u32)plln) & 0x7F);
- RCC->APB1ENR |= RCC_APB1ENR_PWR;
- RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
- RCC->PLLCFGR |= ((tn << RCC_PLLCFGR_PLL_DN_Pos) | (tm << RCC_PLLCFGR_PLL_DP_Pos));
- //Enable PLL
- RCC->CR |= RCC_CR_PLLON;
- //Wait till PLL is ready
- while((RCC->CR & RCC_CR_PLLRDY) == 0) {
- __ASM ("nop") ;//__NOP();
- }
- //Select PLL as system clock source
- RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
- RCC->CFGR |= (u32)RCC_CFGR_SW_PLL;
- //Wait till PLL is used as system clock source
- while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)RCC_CFGR_SWS_PLL) {
- __ASM ("nop") ;//__NOP();
- }
- #elif defined(SYSCLK_FREQ_HSE)
- RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
- RCC->CFGR |= (u32)RCC_CFGR_SW_HSE;
- while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)RCC_CFGR_SWS_HSE) {
- __ASM ("nop") ;//__NOP();
- }
- #else
- RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
- RCC->CFGR |= (u32)0;
- while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0) {
- __ASM ("nop") ;//__NOP();
- }
- #endif
- DELAY_xUs(1);
- // set HCLK = AHB = FCLK = SYSCLK divided by 2
- RCC->CFGR &= (~(RCC_CFGR_PPRE_0));
- DELAY_xUs(1);
- // set HCLK = AHB = FCLK = SYSCLK divided by 1
- RCC->CFGR &= (~(RCC_CFGR_PPRE_3));
- DELAY_xUs(1);
- if(GetCurrentSysClockFreq()!=SystemCoreClock){
- //set SystemCoreClock fail
- RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
- RCC->CFGR |= (u32)0;
- while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0) {
- __ASM ("nop") ;//__NOP();
- }
- SystemCoreClock = HSI_VALUE;
- //while(1){};
- }
- }
- /// @}
- /// @}
- /// @}
- /**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * [url=home.php?mod=space&uid=288409]@file[/url] startup_mm32f3273g9p.s
- * [url=home.php?mod=space&uid=187600]@author[/url] MCD Application Team
- * @brief MM32F3273G9PDevices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Configure external SRAM mounted on MM32F3273G9P EVAL board
- * to be used as data memory (optional, to be enabled by user)
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2017 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
- .global g_pfnVectors
- .global Default_Handler
- /* start address for the initialization values of the .data section.
- defined in linker script */
- .word _sidata
- /* start address for the .data section. defined in linker script */
- .word _sdata
- /* end address for the .data section. defined in linker script */
- .word _edata
- /* start address for the .bss section. defined in linker script */
- .word _sbss
- /* end address for the .bss section. defined in linker script */
- .word _ebss
- .equ BootRAM, 0xF1E0F85F
- /**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
- */
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
- Reset_Handler:
- /* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
- CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
- LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
- /* Zero fill the bss segment. */
- FillZerobss:
- movs r3, #0
- str r3, [r2], #4
- LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
- /* Call the clock system intitialization function.*/
- bl SystemInit
- /* Call static constructors */
- bl __libc_init_array
- /* Call the application's entry point.*/
- bl main
- bx lr
- .size Reset_Handler, .-Reset_Handler
- /**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
- */
- .section .text.Default_Handler,"ax",%progbits
- Default_Handler:
- Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
- /******************************************************************************
- *
- * The minimal vector table for a Cortex M3. Note that the proper constructs
- * must be placed on this to ensure that it ends up at physical address
- * 0x0000.0000.
- *
- ******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
- g_pfnVectors:
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_CRS_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word FlashCache_IRQHandler
- .word 0
- .word CAN1_RX_IRQHandler
- .word 0
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_IRQHandler
- .word TIM1_UP_IRQHandler
- .word TIM1_TRG_COM_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_IRQHandler
- .word 0
- .word I2C2_IRQHandler
- .word 0
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word UART1_IRQHandler
- .word UART2_IRQHandler
- .word UART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTCAlarm_IRQHandler
- .word OTG_FS_WKUP_IRQHandler
- .word TIM8_BRK_IRQHandler
- .word TIM8_UP_IRQHandler
- .word TIM8_TRG_COM_IRQHandler
- .word TIM8_CC_IRQHandler
- .word ADC3_IRQHandler
- .word 0
- .word SDIO_IRQHandler
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_IRQHandler
- .word DMA2_Channel5_IRQHandler
- .word ETH_IRQHandler
- .word 0
- .word 0
- .word COMP1_2_IRQHandler
- .word 0
- .word 0
- .word OTG_FS_IRQHandler
- .word 0
- .word 0
- .word 0
- .word UART6_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word UART7_IRQHandler
- .word UART8_IRQHandler
- .word BootRAM
- /*******************************************************************************
- *
- * Provide weak aliases for each Exception handler to the Default_Handler.
- * As they are weak aliases, any function with the same name will override
- * this definition.
- *
- *******************************************************************************/
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
- .weak RCC_CRS_IRQHandler
- .thumb_set RCC_CRS_IRQHandler,Default_Handler
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
- .weak FlashCache_IRQHandler
- .thumb_set FlashCache_IRQHandler,Default_Handler
- .weak CAN1_RX_IRQHandler
- .thumb_set CAN1_RX_IRQHandler,Default_Handler
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
- .weak TIM1_BRK_IRQHandler
- .thumb_set TIM1_BRK_IRQHandler,Default_Handler
- .weak TIM1_UP_IRQHandler
- .thumb_set TIM1_UP_IRQHandler,Default_Handler
- .weak TIM1_TRG_COM_IRQHandler
- .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
- .weak I2C1_IRQHandler
- .thumb_set I2C1_IRQHandler,Default_Handler
- .weak I2C2_IRQHandler
- .thumb_set I2C2_IRQHandler,Default_Handler
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
- .weak UART1_IRQHandler
- .thumb_set UART1_IRQHandler,Default_Handler
- .weak UART2_IRQHandler
- .thumb_set UART2_IRQHandler,Default_Handler
- .weak UART3_IRQHandler
- .thumb_set UART3_IRQHandler,Default_Handler
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
- .weak RTCAlarm_IRQHandler
- .thumb_set RTCAlarm_IRQHandler,Default_Handler
- .weak OTG_FS_WKUP_IRQHandler
- .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
- .weak TIM8_BRK_IRQHandler
- .thumb_set TIM8_BRK_IRQHandler,Default_Handler
- .weak TIM8_UP_IRQHandler
- .thumb_set TIM8_UP_IRQHandler,Default_Handler
- .weak TIM8_TRG_COM_IRQHandler
- .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
- .weak TIM8_CC_IRQHandler
- .thumb_set TIM8_CC_IRQHandler,Default_Handler
- .weak ADC3_IRQHandler
- .thumb_set ADC3_IRQHandler,Default_Handler
- .weak SDIO_IRQHandler
- .thumb_set SDIO_IRQHandler,Default_Handler
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
- .weak TIM6_IRQHandler
- .thumb_set TIM6_IRQHandler,Default_Handler
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
- .weak DMA2_Channel4_IRQHandler
- .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
- .weak DMA2_Channel5_IRQHandler
- .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
- .weak ETH_IRQHandler
- .thumb_set ETH_IRQHandler,Default_Handler
- .weak COMP1_2_IRQHandler
- .thumb_set COMP1_2_IRQHandler,Default_Handler
- .weak OTG_FS_IRQHandler
- .thumb_set OTG_FS_IRQHandler,Default_Handler
- .weak UART6_IRQHandler
- .thumb_set UART6_IRQHandler,Default_Handler
- .weak UART7_IRQHandler
- .thumb_set UART7_IRQHandler,Default_Handler
- .weak UART8_IRQHandler
- .thumb_set UART8_IRQHandler,Default_Handler
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
- /*
- *****************************************************************************
- **
- ** File : MM32F3273G9P_FLASH.ld
- **
- ** Abstract : Linker script for MM32F3273G9P Device with
- ** 512KByte FLASH, 128Byte RAM
- **
- ** Set heap size, stack size and stack location according
- ** to application requirements.
- **
- ** Set memory bank area and size if external memory is used.
- **
- ** Target : MM32F3273G9P
- **
- **
- ** Distribution: The file is distributed as is, without any warranty
- ** of any kind.
- **
- ** (c)Copyright Ac6.
- ** You may use this file as-is or modify it according to the needs of your
- ** project. Distribution of this file (unmodified or modified) is not
- ** permitted. Ac6 permit registered System Workbench for MCU users the
- ** rights to distribute the assembled, compiled & linked contents of this
- ** file as part of an application binary file, provided that it is built
- ** using the System Workbench for MCU toolchain.
- **
- *****************************************************************************
- */
- /* Entry Point */
- ENTRY(Reset_Handler)
- /* Highest address of the user mode stack */
- _estack = 0x2001FFFF; /* end of RAM */
- /* Generate a link error if heap and stack don't fit into RAM */
- _Min_Heap_Size = 0x800; /* required amount of heap */
- _Min_Stack_Size = 0x800; /* required amount of stack */
- /* Specify the memory areas */
- MEMORY
- {
- FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
- RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
- }
- /* Define output sections */
- SECTIONS
- {
- /* The startup code goes first into FLASH */
- .isr_vector :
- {
- . = ALIGN(4);
- KEEP(*(.isr_vector)) /* Startup code */
- . = ALIGN(4);
- } >FLASH
- /* The program code and other data goes into FLASH */
- .text :
- {
- . = ALIGN(4);
- *(.text) /* .text sections (code) */
- *(.text*) /* .text* sections (code) */
- *(.glue_7) /* glue arm to thumb code */
- *(.glue_7t) /* glue thumb to arm code */
- *(.eh_frame)
- KEEP (*(.init))
- KEEP (*(.fini))
- . = ALIGN(4);
- _etext = .; /* define a global symbols at end of code */
- } >FLASH
- /* Constant data goes into FLASH */
- .rodata :
- {
- . = ALIGN(4);
- *(.rodata) /* .rodata sections (constants, strings, etc.) */
- *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
- . = ALIGN(4);
- } >FLASH
- .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
- .ARM : {
- __exidx_start = .;
- *(.ARM.exidx*)
- __exidx_end = .;
- } >FLASH
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array*))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- } >FLASH
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array*))
- PROVIDE_HIDDEN (__init_array_end = .);
- } >FLASH
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(SORT(.fini_array.*)))
- KEEP (*(.fini_array*))
- PROVIDE_HIDDEN (__fini_array_end = .);
- } >FLASH
- /* used by the startup to initialize data */
- _sidata = LOADADDR(.data);
- /* Initialized data sections goes into RAM, load LMA copy after code */
- .data :
- {
- . = ALIGN(4);
- _sdata = .; /* create a global symbol at data start */
- *(.data) /* .data sections */
- *(.data*) /* .data* sections */
- . = ALIGN(4);
- _edata = .; /* define a global symbol at data end */
- } >RAM AT> FLASH
-
- /* Uninitialized data section */
- . = ALIGN(4);
- .bss :
- {
- /* This is used by the startup in order to initialize the .bss secion */
- _sbss = .; /* define a global symbol at bss start */
- __bss_start__ = _sbss;
- *(.bss)
- *(.bss*)
- *(COMMON)
- . = ALIGN(4);
- _ebss = .; /* define a global symbol at bss end */
- __bss_end__ = _ebss;
- } >RAM
- /* User_heap_stack section, used to check that there is enough RAM left */
- ._user_heap_stack :
- {
- . = ALIGN(8);
- PROVIDE ( end = . );
- PROVIDE ( _end = . );
- . = . + _Min_Heap_Size;
- . = . + _Min_Stack_Size;
- . = ALIGN(8);
- } >RAM
-
- /* Remove information from the standard libraries */
- /DISCARD/ :
- {
- libc.a ( * )
- libm.a ( * )
- libgcc.a ( * )
- }
- .ARM.attributes 0 : { *(.ARM.attributes) }
- }
5. 更改完后,需要对 src 文件夹下的文件做替换,从 MM32F3270 官方的闪灯例程中找到对应文件替换过来,为了保险起见,将以上几个文件也包含到目录中(也是后面调试时才发现一定要添加进来的,不然编译通过但是无法正常运行,未包含启动文件),并且将 uart.c 的retarget 修改好适配 gcc 编译器
6. 至此已经完成了替代,可以进行 build 编译、upload 下载以及使用 Cortex-Debug 调试工程了
下载调试使用到 j-link 驱动包,由于该包也是通过依赖而新下载而来的,所以需要将灵动微的设备添加到驱动包中,这样才可以正常下载和调试。可以看到,调试环境很方便,还能看到反编译的汇编代码以及寄存器实时更新窗口,赞!
三、后续待完成的集成要点
由于是从 ST 改写而来的集成,并未通过 PIO 官方 package 注册获得 MM32 本身的平台认证,所以后续是需要制作平台支持包以及板子支持包的,而且还得适配好 Arduino 、 SPL 、 mbed os 等几大主流框架,加上适配好 CMSIS DAP/openocd/ Serial 调试或者下载工具支持包。所以说,其实还有很多支持包需要官方做好,我们用户才能拿来就用,更加方便地进行 PIO 开发。
附件内容包含了我这次修改的支持包,以及调试运行的示例闪灯工程,大家可以拿去试着搭建起自己的环境,跑跑看了!
四、参考链接
PlatformIO 玩转单片机开发 https://www.zhihu.com/column/c_1094956718374633472
如何新增自己的 PIO 开发平台 https://docs.platformio.org/en/latest/platforms/creating_platform.html
GD32 的开源 git 仓 https://github.com/CommunityGD32Cores/gd32-pio-projects
ststm32.zip
(887.81 KB, 下载次数: 7)
framework-cmsis-stm32f1.zip
(1.23 MB, 下载次数: 8)
mm32f3273_pio_demo.zip
(287.11 KB, 下载次数: 9)
MM32_JLINK_pack.zip
(292.49 KB, 下载次数: 7)