返回列表 发新帖我要提问本帖赏金: 100.00元(功能说明)

[MM32生态] 在 VS-Code 中还能怎么玩单片机?用 PlatformIO 试试

[复制链接]
 楼主| yang377156216 发表于 2022-6-28 21:40 | 显示全部楼层 |阅读模式
<
本帖最后由 yang377156216 于 2022-6-29 09:10 编辑
#申请原创#  @21小跑堂


整体概览
物联网 IOT 的概念已经炒了很多年了,抛开产品及其本身用到的技术而言,在单片机开发领域它会涉及到开发环境、硬件平台、编程框架以及操作系统等等几大方面。国内各大厂家争先也出了自己的物联网操作系统,比如:华为鸿蒙(liteos)、阿里 AliOS Things、腾讯 TinyOS 、RT-Thread OS 等等,至于框架以及操作系统相结合的代表作有 ZLG 的 AMetal + AWorks ,还有 ARM 官方的 mbed os 框架平台现在也是越来越流行了。提到开源硬件平台,基本都能提到 arduino、NodeMCU 、ESP32 和树莓派这几个,基于这些平台有太多极客、黑客们各种好玩的东西了。说到这里,想必大家就会自然发问:那玩转这些东西是不是得要有一个统一的集成开发环境呢?好在 PlatformIO 这个工具软件在合适的时候诞生了,它几乎包含了以上提到的所有内容,就是这么牛的存在。那今天就一起来揭开 PlatformIO 的面纱,在这个集成环境中使用 MM32F3273G9P MB-039 开发板来做开发调试。以下几部分为本次分享的要点:
  • PlatformIO 简介
  • 将 MM32F3273G9P 集成到 VS-Code PlatformIO 中
  • 后续待完成的集成要点
  • 参考链接
  • 附件内容


一、PlatformIO 简介
PlatformIO https://docs.platformio.org/en/latest/what-is-platformio.html)是一个用于物联网开发的开源生态系统。它提供跨平台的开发环境和统一的调试器,是一个跨平台的代码构建工具和库管理工具,支持远程单元测试和固件更新等等功能,还支持像 Arduino 和 MBED 这样的开源框架及硬件平台,可以抛开 Arduino IDE 和 ARM mbed ide 了它是独立于电脑平台运行的,只依赖于 python,所以在 macOS、linux 和 windows 上都能完美适配,也就是说 PlatformIO 的工程从一个电脑很容易迁移到另一个电脑,只需要拷贝再使用 PlatformIO 就能完美打开,不管团队中的成员使用什么操作系统 PlatformIO 可以让工程共享变得异常简单。 此外, PlatformIO 不仅可以在笔记本和台式机上运行,同样可以运行在没有显示桌面的服务器。使用它作开发时工作流程可以简化,首先用户在 “platformio.ini” (工程配置文件) 中指定开发平台(开发板),接着根据配置文件中的开发板(一个工程可以配置多个开发板),PlatformIO 会自动下载并安装对应的交叉编译链工具以及调试工具.,最后用户编写代码,PlatformIO 来保证所有指定开发板的编译、调试和上传工作即可完成所有开发工作。
熟悉 VS-Code 的伙伴们更加习惯以 PlatformIO 插件的形式做集成,VS-Code + PlatformIO 的环境有以下一些特性:
  • PIO 统一的调试器,可以零配置的对支持硬件调试的的嵌入式开发板进行调试工作,调试器支持很多的架构和开发平台
  • 跨平台的代码构建系统对系统软件没有额外的依赖: 600+ 嵌入式开发板, 30+ 开发平台, 15+ 框架
  • C/C++ 智能代码补全,语法检查,快速重构以及代码跳转满足快速专业的开发需求
  • VSCode 提供多工程和文件管理的支持和统一而流畅的使用体验,并且支持多种色彩主题,总有您喜欢和适合您的
  • 内建的终端支持 PlatformIO Core 命令行工具,并且支持强大的串口调试器
  • 除了支持大约 600+ 个开发板和市面上流行的支持跨平台的 30 个硬件平台,同时,PlatformIO 还提供大量的开发库,目前超过了 6000 个,为了方便新手入门开发,他们也同样提供代码例程
  • 可以通过命令行形态存在,也可以嵌入到其它主流的编辑环境中
  • 获得过 2015/16 IOT 年度最佳开发软件和工具奖  提名


platformio 简介.png

那是不是就可以愉快地在灵动微 MCU 上耍起来了呢?可能没那么简单。 下面讲讲适配过程。


二、将 MM32F3273G9P 集成到 VS-Code PlatformIO 中
在开发板和平台页未找到关于灵动微的任何信息,顺便再看了一下,国产 MCU 厂家中也只有 GD32 的是已经适配好了的,不愧为国产 32位 MCU 中的 NO.1 ,另外也看到很多 STM32 的板子。在熟悉一个新鲜东西的时候,往往是需要从易到难的这么一个适应过程,不然就容易从入门到放弃了,所以我选择先搭建好 STM32F103ZET6 这颗芯片的闪灯工程,熟悉好了整个过程后再去适配灵动微的。下面为详细步骤:
1. 在 VS-Code 插件中搜索 PlatformIO ,下载安装,有时候需要添加到可信任工作区中并且重启 VS-Code 。完成安装后,可以先熟悉一遍软件中每个按键/Tab页的含义,另外需要注意,前提是需要确保安装好了 Python 环境。
2. 在 PIO 的主页点击 New Project 新建一个工程,输入自己的工程名称并且选择好对应的开发板以及开发框架,这里选择 genericSTM32F103ZE 开发板和 CMSIS 框架,然后 Finish ,第一次加载需要下载配套的工具包(编译器、tool、CMSIS 框架包等等),等待全部下载好即可出现空白工程目录,我的依赖包下载路径自动选择为 “C:\Users\yang3\.platformio\packages”,新建的工程路径默认选择为了“C:\Users\yang3\Documents\PlatformIO\Projects
pio 新建工程.png
3. 将原子的模板闪灯例程中的一些源文件拷贝到新建的空白工程下的 src 文件夹中,主要有 CORE、HARDWARE、STM32F10x_FWLib、SYSTEM 、main.c、
stm32f10x.h 、stm32f10x_conf.h 、stm32f10x_it.c 、stm32f10x_it.h 、system_stm32f10x.c 、system_stm32f10x.h 这些文件和文件夹,完成复制后整个工程目录结构如下:
stm32f103ze pio 结构目录.png
4. 改写 PIO 的工程配置文件 platformio.ini ,该文件位于根目录下,改写的代码如下:
  1. ; PlatformIO Project Configuration File
  2. ;
  3. ;   Build options: build flags, source filter
  4. ;   Upload options: custom upload port, speed and extra flags
  5. ;   Library options: dependencies, extra library storages
  6. ;   Advanced options: extra scripting
  7. ;
  8. ; Please visit documentation for the other options and examples
  9. ; https://docs.platformio.org/page/projectconf.html

  10. [env:genericSTM32F103ZE]
  11. platform = ststm32
  12. board = genericSTM32F103ZE  ;实际为 MM32F3273_MB039
  13. framework = cmsis

  14. upload_protocol = jlink     ; 代码上传工具,
  15. debug_tool  = jlink         ; debug工具
  16. build_flags =               ; Build options
  17.     -Isrc
  18.     -Isrc/CORE
  19.     -Isrc/HARDWARE/LED
  20.     -Isrc/MM32F327x_FWLib/inc
  21.     -Isrc/SYSTEM/DELAY
  22.     -Isrc/SYSTEM/SYS
  23.     -Isrc/SYSTEM/UART

  24.     -D STM32F10X_HD         ; 定义全局宏
  25.     -D USE_STDPERIPH_DRIVER
类似于 keil ,上面代码配置定义好了平台、板子、框架软件包、调试下载工具类型、用户头文件路径以及其它一些全局宏定义等等。
5. 需要知道,PIO 的集成编译器是依赖于 toolchain-gccarmnoneeabi 的,所以源码中的一些不适合 gcc 编译器的地方都得改正过来,最后编译即可,点击编译可以是通过下方的“√”,也可通过 PIO PROJECT TASKS 中的 Build Task 按键。
stm32f103ze pio ok.png
到这里已经很轻松地完成了 STM32F103 的示例工程导入,通过这一系列的操作,也已经熟悉了 PIO 的开发流程,那接下来就是要做替换了,由于使用的是 CMSIS 框架,与平台相关的外设驱动包改动不涉及框架支持包的重写,所以会稍微容易实现些。下面为替换步骤:
1. 通过查看 ststm32 平台包,熟悉整个 PIO 平台支持包的内容含义,明确要改写哪些文件
stm32  pio 平台包说明.png
2. 由于开发板选择的是 genericSTM32F103ZE ,对应的文件为 genericSTM32F103ZE.json ,其中主要改写调试相关的选择为:
  1. "debug": {
  2.     "jlink_device": "MM32F3273G9P",
  3.     "openocd_target": "stm32f1x",
  4.     "svd_path": "MM32F327x.svd"
  5.   },
特别注意,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 去做修改。
mm32f3270 pio include.png
  1. ////////////////////////////////////////////////////////////////////////////////
  2. /// [url=home.php?mod=space&uid=288409]@file[/url]     SYSTEM_MM32.C
  3. /// [url=home.php?mod=space&uid=187600]@author[/url]   AE TEAM
  4. /// [url=home.php?mod=space&uid=247401]@brief[/url]    THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
  5. ////////////////////////////////////////////////////////////////////////////////
  6. /// @attention
  7. ///
  8. /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
  9. /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
  10. /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
  11. /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
  12. /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
  13. /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
  14. ///
  15. /// <H2><CENTER>© COPYRIGHT MINDMOTION </CENTER></H2>
  16. ////////////////////////////////////////////////////////////////////////////////

  17. // Define to prevent recursive inclusion
  18. #define _SYSTEM_MM32_C_

  19. // Files includes

  20. /// @addtogroup CMSIS
  21. /// @{

  22. #include "mm32_device.h"


  23. /// @}



  24. /// @}


  25. /// Uncomment the line corresponding to the desired System clock (SYSCLK)
  26. /// frequency (after reset the HSI is used as SYSCLK source)
  27. ///
  28. /// IMPORTANT NOTE:
  29. /// ==============
  30. /// 1. After each device reset the HSI is used as System clock source.
  31. ///
  32. /// 2. Please make sure that the selected System clock doesn't exceed y**ice's
  33. /// maximum frequency.
  34. ///
  35. /// 3. If none of the define below is enabled, the HSI is used as System clock
  36. /// source.
  37. ///
  38. /// 4. The System clock configuration functions provided based external crystal or HSE
  39. /// An external 8MHz crystal is used to drive the System clock.
  40. /// If you are using different crystal you have to modify HSE_VALUE in reg_common.h.


  41. // ### HSE_VALUE is defined in reg_common.h ###
  42. #ifndef HSE_VALUE
  43. #error "not define HSE_VALUE"
  44. #endif

  45. //#define SYSCLK_FREQ_XXMHz                96000000                               //select [120000000,96000000,72000000,48000000,24000000]
  46. //#define SYSCLK_FREQ_HSE                 HSE_VALUE                               //use HSE_VALUE as system frequence
  47. #define SYSCLK_HSI_XXMHz                 120000000                               //select [120000000,96000000,72000000,48000000,24000000]

  48. //below message need to confirm Frequence  at first, then comment these warning
  49. //#define DISABLE_FREQ_MACRO_CHECK
  50. #ifndef DISABLE_FREQ_MACRO_CHECK
  51. #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)))

  52. #error "define more than one Freq config"

  53. #elif (defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz))

  54. #if (defined(HSE_VALUE) && (HSE_VALUE == 8000000))
  55. #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"
  56. #undef HSE_VALUE
  57. #define HSE_VALUE   8000000
  58. #else
  59. #warning "on board HSE is not equal to 8000000Hz, Please double check"
  60. #endif

  61. #elif defined(SYSCLK_HSI_XXMHz)
  62. #warning "use PLL mode and PLL Source is HSI, Please double check"
  63. #else
  64. #warning "current HSI = 8000000Hz as SYSCLK"

  65. #endif
  66. #endif




  67. /// Uncomment the following line if you need to relocate your vector Table in
  68. /// Internal SRAM.
  69. ///#define VECT_TAB_SRAM
  70. #define VECT_TAB_OFFSET  0x0
  71. /// Vector Table base offset field.
  72. /// This value must be a multiple of 0x200.


  73. /// @}




  74. ///////////////////////////////////////////////////////////////
  75. ///Clock Definitions
  76. ///////////////////////////////////////////////////////////////
  77. #if defined SYSCLK_FREQ_HSE
  78. u32 SystemCoreClock         = SYSCLK_FREQ_HSE;
  79. #elif defined SYSCLK_FREQ_XXMHz
  80. u32 SystemCoreClock         = SYSCLK_FREQ_XXMHz;
  81. #elif defined SYSCLK_HSI_XXMHz
  82. u32 SystemCoreClock         = SYSCLK_HSI_XXMHz;
  83. #else //HSI Selected as System Clock source
  84. u32 SystemCoreClock         = HSI_VALUE;
  85. #endif



  86. /// @}


  87. static void SetSysClock(void);
  88. static void SetSysClockToAnyXX(void);



  89. /// @}



  90. /// [url=home.php?mod=space&uid=247401]@brief[/url]  Setup the microcontroller system
  91. ///         Initialize the Embedded Flash Interface, the PLL and update the
  92. ///         SystemCoreClock variable.
  93. /// [url=home.php?mod=space&uid=536309]@NOTE[/url]   This function should be used only after reset.
  94. /// @param  None
  95. /// @retval None

  96. void SystemInit (void)
  97. {
  98.     //Reset the RCC clock configuration to the default reset state(for debug purpose)
  99.     //Set HSION bit
  100.     RCC->CR |= (u32)0x00000001;

  101.     //Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits
  102.     RCC->CFGR &= (u32)0xF8FFC00C;

  103.     //Reset HSEON, CSSON and PLLON bits
  104.     RCC->CR &= (u32)0xFEF6FFFF;

  105.     //Reset HSEBYP bit
  106.     RCC->CR &= (u32)0xFFFBFFFF;

  107.     //Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits
  108.     RCC->CFGR &= (u32)0xFF3CFFFF;
  109.     RCC->CR &= (u32)0x008FFFFF;

  110.     //Disable all interrupts and clear pending bits
  111.     RCC->CIR = 0x009F0000;
  112.     //Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers
  113.     //Configure the Flash Latency cycles and enable prefetch buffer
  114.     SetSysClock();
  115. }


  116. /// @brief  use to return the pllm&plln.
  117. /// @param  pllclkSourceFrq : PLL source clock frquency;
  118. ///         pllclkFrq : Target PLL clock frquency;
  119. ///         plln : PLL factor PLLN
  120. ///         pllm : PLL factor PLLM
  121. /// @retval amount of error
  122. u32 AutoCalPllFactor(u32 pllclkSourceFrq, u32 pllclkFrq, u8* plln, u8* pllm)
  123. {
  124.     u32 n, m;
  125.     u32 tempFrq;
  126.     u32 minDiff = pllclkFrq;
  127.     u8  flag = 0;
  128.     for(m = 0; m < 4 ; m++) {
  129.         for(n = 0; n < 64 ; n++) {
  130.             tempFrq =  pllclkSourceFrq * (n + 1) / (m + 1);
  131.             tempFrq = (tempFrq >  pllclkFrq) ? (tempFrq - pllclkFrq) : (pllclkFrq - tempFrq) ;

  132.             if(minDiff > tempFrq) {
  133.                 minDiff =  tempFrq;
  134.                 *plln = n;
  135.                 *pllm = m;
  136.             }
  137.             if(minDiff == 0) {
  138.                 flag = 1;
  139.                 break;
  140.             }
  141.         }
  142.         if(flag != 0) {
  143.             break;
  144.         }
  145.     }
  146.     return  minDiff;
  147. }

  148. static void DELAY_xUs(u32 count)
  149. {
  150.     u32 temp;
  151.     SysTick->CTRL = 0x0;                                                        //disable systick function
  152.     SysTick->LOAD = count * 8;                                                  //time count for 1us with HSI as SYSCLK
  153.     SysTick->VAL = 0x00;                                                        //clear counter
  154.     SysTick->CTRL = 0x5;                                                        //start discrease with Polling
  155.     do {
  156.         temp = SysTick->CTRL;
  157.     } while((temp & 0x01) && !(temp & (1 << 16)));                              //wait time count done
  158.     SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;                                  //Close Counter
  159.     SysTick->VAL = 0X00;                                                        //clear counter
  160. }

  161. /// @brief  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
  162. /// @param  None
  163. /// @retval None

  164. static void SetSysClock(void)
  165. {
  166.     CACHE->CCR &= ~(0x3 << 3);
  167.     CACHE->CCR |= 1;
  168.     while((CACHE->SR & 0x3) != 2);
  169.     SetSysClockToAnyXX();
  170. }

  171. u32 GetCurrentSysClockFreq(void)
  172. {
  173.     u32 result;
  174.     u32 clock, mul, div;
  175.     switch (RCC->CFGR & RCC_CFGR_SWS) {
  176.         case RCC_CFGR_SWS_LSI:
  177.             result = LSI_VALUE;
  178.             break;

  179.         case RCC_CFGR_SWS_HSE:
  180.             result = HSE_VALUE;
  181.             break;

  182.         case RCC_CFGR_SWS_PLL:
  183.             clock = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC) ? (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLXTPRE) ? (HSE_VALUE >> 1) : HSE_VALUE)
  184.                     : HSI_VALUE_PLL_ON;
  185.             mul = ((RCC->PLLCFGR & (u32)RCC_PLLCFGR_PLL_DN) >> RCC_PLLCFGR_PLL_DN_Pos) + 1;
  186.             div = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL_DP) >> RCC_PLLCFGR_PLL_DP_Pos) + 1;

  187.             result = clock * mul / div;
  188.             break;
  189.         default:
  190.             result =  HSI_VALUE;
  191.             break;
  192.     }
  193.     return result;
  194. }


  195. /// @brief  Sets System clock frequency to XXMHz and configure HCLK, PCLK2
  196. ///         and PCLK1 prescalers.
  197. /// [url=home.php?mod=space&uid=536309]@NOTE[/url]   This function should be used only after reset.
  198. /// @param  None
  199. /// @retval None
  200. static void SetSysClockToAnyXX(void)
  201. {
  202.     __IO u32 temp;
  203. #if defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz)
  204.     __IO u32 StartUpCounter = 0, HSEStatus = 0;
  205. #endif
  206. #if defined(SYSCLK_FREQ_XXMHz) || defined(SYSCLK_HSI_XXMHz)
  207.     __IO u32 tn, tm;
  208.     u8 plln, pllm;
  209. #endif
  210.    
  211. #if defined SYSCLK_FREQ_HSE
  212.     SystemCoreClock         = SYSCLK_FREQ_HSE;
  213. #elif defined SYSCLK_FREQ_XXMHz
  214.     SystemCoreClock         = SYSCLK_FREQ_XXMHz;
  215. #elif defined SYSCLK_HSI_XXMHz
  216.     SystemCoreClock         = SYSCLK_HSI_XXMHz;
  217. #else //HSI Selected as System Clock source
  218.     SystemCoreClock         = HSI_VALUE;
  219. #endif
  220.    
  221.     RCC->CR |= RCC_CR_HSION;
  222.     while(!(RCC->CR & RCC_CR_HSIRDY));
  223. #if defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz)
  224.     //PLL SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------
  225.     //Enable HSE
  226.     RCC->CR |= ((u32)RCC_CR_HSEON);


  227. #endif
  228.     DELAY_xUs(5);
  229.     if(SystemCoreClock > 96000000) {
  230.         RCC->APB1ENR |= RCC_APB1ENR_PWR;
  231.         PWR->CR &= ~(3 << 14);
  232.         PWR->CR |= 2 << 14;
  233.     }
  234.     else if(SystemCoreClock > 48000000) {
  235.         RCC->APB1ENR |= RCC_APB1ENR_PWR;
  236.         PWR->CR &= ~(3 << 14);
  237.         PWR->CR |= 1 << 14;
  238.     }
  239.     else {
  240.         RCC->APB1ENR |= RCC_APB1ENR_PWR;
  241.         PWR->CR &= ~(3 << 14);
  242.         PWR->CR |= 0 << 14;
  243.     }
  244. #if defined(SYSCLK_FREQ_HSE) || defined(SYSCLK_FREQ_XXMHz)
  245.     //Wait till HSE is ready and if Time out is reached exit
  246.     while(1) {
  247.         HSEStatus = RCC->CR & RCC_CR_HSERDY;
  248.         if(HSEStatus != 0)
  249.             break;
  250.         StartUpCounter++;
  251.         if(StartUpCounter >= (10 * HSE_STARTUP_TIMEOUT))
  252.             return;
  253.     }

  254.     if ((RCC->CR & RCC_CR_HSERDY) == RESET) {
  255.         //If HSE fails to start-up, the application will have wrong clock
  256.         //configuration. User can add here some code to deal with this error
  257.         HSEStatus = (u32)0x00;
  258.         return;
  259.     }

  260.     HSEStatus = (u32)0x01;
  261.     DELAY_xUs(5);
  262. #endif
  263. #if defined(SYSCLK_FREQ_XXMHz)
  264.     SystemCoreClock         = SYSCLK_FREQ_XXMHz;
  265. #elif defined(SYSCLK_FREQ_HSE)
  266.     SystemCoreClock         = HSE_VALUE;
  267. #elif defined(SYSCLK_HSI_XXMHz)
  268.     SystemCoreClock         = SYSCLK_HSI_XXMHz;
  269. #else
  270.     SystemCoreClock         = HSI_VALUE;
  271. #endif

  272.     //Enable Prefetch Buffer
  273.     FLASH->ACR |= FLASH_ACR_PRFTBE;
  274.     //Flash 0 wait state ,bit0~2
  275.     FLASH->ACR &= ~FLASH_ACR_LATENCY;
  276.     temp = (SystemCoreClock - 1) / 24000000;
  277.     FLASH->ACR |= (temp & FLASH_ACR_LATENCY);
  278.    
  279.     RCC->CFGR &= (~RCC_CFGR_HPRE) & ( ~RCC_CFGR_PPRE1) & (~RCC_CFGR_PPRE2);
  280.     //HCLK = AHB = FCLK = SYSCLK divided by 4
  281.     RCC->CFGR |= (u32)RCC_CFGR_HPRE_DIV4;
  282.     //PCLK2 = APB2 = HCLK divided by 1, APB2 is high APB CLK
  283.     RCC->CFGR |= (u32)RCC_CFGR_PPRE2_DIV1;
  284.     if(SystemCoreClock > 72000000) {
  285.         //PCLK1 = APB1 = HCLK divided by 4, APB1 is low APB CLK
  286.         RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV4;
  287.     }
  288.     else if(SystemCoreClock > 36000000) {
  289.         //PCLK1 = APB1 = HCLK divided by 2, APB1 is low APB CLK
  290.         RCC->CFGR |= (u32)RCC_CFGR_PPRE1_DIV2;
  291.     }
  292.    
  293. #if defined(SYSCLK_FREQ_XXMHz) || defined(SYSCLK_HSI_XXMHz)
  294.    
  295. #if defined(SYSCLK_FREQ_XXMHz)
  296.     AutoCalPllFactor(HSE_VALUE, SystemCoreClock, &plln, &pllm);
  297.     RCC->PLLCFGR &= ~((u32) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE);
  298.     RCC->PLLCFGR |= (u32) RCC_PLLCFGR_PLLSRC;
  299. #endif
  300. #if defined(SYSCLK_HSI_XXMHz)
  301.     AutoCalPllFactor(HSI_VALUE_PLL_ON, SystemCoreClock, &plln, &pllm);
  302.     RCC->PLLCFGR &= ~((u32) RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLXTPRE);
  303.     RCC->PLLCFGR &= ~((u32) RCC_PLLCFGR_PLLSRC);
  304. #endif
  305.     tm = (((u32)pllm) & 0x07);
  306.     tn = (((u32)plln) & 0x7F);

  307.     RCC->APB1ENR |= RCC_APB1ENR_PWR;
  308.     RCC->PLLCFGR &= (u32)((~RCC_PLLCFGR_PLL_DN) & (~RCC_PLLCFGR_PLL_DP));
  309.     RCC->PLLCFGR |= ((tn << RCC_PLLCFGR_PLL_DN_Pos) | (tm << RCC_PLLCFGR_PLL_DP_Pos));
  310.     //Enable PLL
  311.     RCC->CR |= RCC_CR_PLLON;
  312.     //Wait till PLL is ready
  313.     while((RCC->CR & RCC_CR_PLLRDY) == 0) {
  314.         __ASM ("nop") ;//__NOP();
  315.     }
  316.     //Select PLL as system clock source
  317.     RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
  318.     RCC->CFGR |= (u32)RCC_CFGR_SW_PLL;
  319.     //Wait till PLL is used as system clock source
  320.     while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)RCC_CFGR_SWS_PLL) {
  321.         __ASM ("nop") ;//__NOP();
  322.     }   
  323. #elif defined(SYSCLK_FREQ_HSE)
  324.     RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
  325.     RCC->CFGR |= (u32)RCC_CFGR_SW_HSE;
  326.     while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)RCC_CFGR_SWS_HSE) {
  327.         __ASM ("nop") ;//__NOP();
  328.     }
  329. #else
  330.     RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
  331.     RCC->CFGR |= (u32)0;
  332.     while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0) {
  333.         __ASM ("nop") ;//__NOP();
  334.     }
  335. #endif


  336.     DELAY_xUs(1);
  337.     // set HCLK = AHB = FCLK = SYSCLK divided by 2
  338.     RCC->CFGR &= (~(RCC_CFGR_PPRE_0));
  339.     DELAY_xUs(1);

  340.     // set HCLK = AHB = FCLK = SYSCLK divided by 1
  341.     RCC->CFGR &= (~(RCC_CFGR_PPRE_3));

  342.     DELAY_xUs(1);

  343.     if(GetCurrentSysClockFreq()!=SystemCoreClock){
  344.         //set SystemCoreClock fail
  345.         RCC->CFGR &= (u32)((u32)~(RCC_CFGR_SW));
  346.         RCC->CFGR |= (u32)0;
  347.         while ((RCC->CFGR & (u32)RCC_CFGR_SWS) != (u32)0) {
  348.             __ASM ("nop") ;//__NOP();
  349.         }
  350.         SystemCoreClock = HSI_VALUE;
  351.         //while(1){};
  352.     }
  353. }



  354. /// @}



  355. /// @}



  356. /// @}

  1. /**
  2.   *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
  3.   * [url=home.php?mod=space&uid=288409]@file[/url]      startup_mm32f3273g9p.s
  4.   * [url=home.php?mod=space&uid=187600]@author[/url]    MCD Application Team
  5.   * @brief     MM32F3273G9PDevices vector table for Atollic toolchain.
  6.   *            This module performs:
  7.   *                - Set the initial SP
  8.   *                - Set the initial PC == Reset_Handler,
  9.   *                - Set the vector table entries with the exceptions ISR address
  10.   *                - Configure the clock system   
  11.   *                - Configure external SRAM mounted on MM32F3273G9P EVAL board
  12.   *                  to be used as data memory (optional, to be enabled by user)
  13.   *                - Branches to main in the C library (which eventually
  14.   *                  calls main()).
  15.   *            After Reset the Cortex-M3 processor is in Thread mode,
  16.   *            priority is Privileged, and the Stack is set to Main.
  17.   ******************************************************************************
  18.   * @attention
  19.   *
  20.   * <h2><center>© Copyright (c) 2017 STMicroelectronics.
  21.   * All rights reserved.</center></h2>
  22.   *
  23.   * This software component is licensed by ST under BSD 3-Clause license,
  24.   * the "License"; You may not use this file except in compliance with the
  25.   * License. You may obtain a copy of the License at:
  26.   *                        opensource.org/licenses/BSD-3-Clause
  27.   *
  28.   ******************************************************************************
  29.   */

  30.   .syntax unified
  31.   .cpu cortex-m3
  32.   .fpu softvfp
  33.   .thumb

  34. .global g_pfnVectors
  35. .global Default_Handler

  36. /* start address for the initialization values of the .data section.
  37. defined in linker script */
  38. .word _sidata
  39. /* start address for the .data section. defined in linker script */
  40. .word _sdata
  41. /* end address for the .data section. defined in linker script */
  42. .word _edata
  43. /* start address for the .bss section. defined in linker script */
  44. .word _sbss
  45. /* end address for the .bss section. defined in linker script */
  46. .word _ebss

  47. .equ  BootRAM,        0xF1E0F85F
  48. /**
  49. * @brief  This is the code that gets called when the processor first
  50. *          starts execution following a reset event. Only the absolutely
  51. *          necessary set is performed, after which the application
  52. *          supplied main() routine is called.
  53. * @param  None
  54. * @retval : None
  55. */

  56.   .section .text.Reset_Handler
  57.   .weak Reset_Handler
  58.   .type Reset_Handler, %function
  59. Reset_Handler:

  60. /* Copy the data segment initializers from flash to SRAM */
  61.   movs r1, #0
  62.   b LoopCopyDataInit

  63. CopyDataInit:
  64.   ldr r3, =_sidata
  65.   ldr r3, [r3, r1]
  66.   str r3, [r0, r1]
  67.   adds r1, r1, #4

  68. LoopCopyDataInit:
  69.   ldr r0, =_sdata
  70.   ldr r3, =_edata
  71.   adds r2, r0, r1
  72.   cmp r2, r3
  73.   bcc CopyDataInit
  74.   ldr r2, =_sbss
  75.   b LoopFillZerobss
  76. /* Zero fill the bss segment. */
  77. FillZerobss:
  78.   movs r3, #0
  79.   str r3, [r2], #4

  80. LoopFillZerobss:
  81.   ldr r3, = _ebss
  82.   cmp r2, r3
  83.   bcc FillZerobss

  84. /* Call the clock system intitialization function.*/
  85.     bl  SystemInit
  86. /* Call static constructors */
  87.     bl __libc_init_array
  88. /* Call the application's entry point.*/
  89.   bl main
  90.   bx lr
  91. .size Reset_Handler, .-Reset_Handler

  92. /**
  93. * @brief  This is the code that gets called when the processor receives an
  94. *         unexpected interrupt.  This simply enters an infinite loop, preserving
  95. *         the system state for examination by a debugger.
  96. *
  97. * @param  None
  98. * @retval : None
  99. */
  100.     .section .text.Default_Handler,"ax",%progbits
  101. Default_Handler:
  102. Infinite_Loop:
  103.   b Infinite_Loop
  104.   .size Default_Handler, .-Default_Handler
  105. /******************************************************************************
  106. *
  107. * The minimal vector table for a Cortex M3.  Note that the proper constructs
  108. * must be placed on this to ensure that it ends up at physical address
  109. * 0x0000.0000.
  110. *
  111. ******************************************************************************/
  112.   .section .isr_vector,"a",%progbits
  113.   .type g_pfnVectors, %object
  114.   .size g_pfnVectors, .-g_pfnVectors


  115. g_pfnVectors:

  116.   .word _estack
  117.   .word Reset_Handler
  118.   .word NMI_Handler
  119.   .word HardFault_Handler
  120.   .word MemManage_Handler
  121.   .word BusFault_Handler
  122.   .word UsageFault_Handler
  123.   .word 0
  124.   .word 0
  125.   .word 0
  126.   .word 0
  127.   .word SVC_Handler
  128.   .word DebugMon_Handler
  129.   .word 0
  130.   .word PendSV_Handler
  131.   .word SysTick_Handler
  132.   .word WWDG_IRQHandler
  133.   .word PVD_IRQHandler
  134.   .word TAMPER_IRQHandler
  135.   .word RTC_IRQHandler
  136.   .word FLASH_IRQHandler
  137.   .word RCC_CRS_IRQHandler
  138.   .word EXTI0_IRQHandler
  139.   .word EXTI1_IRQHandler
  140.   .word EXTI2_IRQHandler
  141.   .word EXTI3_IRQHandler
  142.   .word EXTI4_IRQHandler
  143.   .word DMA1_Channel1_IRQHandler
  144.   .word DMA1_Channel2_IRQHandler
  145.   .word DMA1_Channel3_IRQHandler
  146.   .word DMA1_Channel4_IRQHandler
  147.   .word DMA1_Channel5_IRQHandler
  148.   .word DMA1_Channel6_IRQHandler
  149.   .word DMA1_Channel7_IRQHandler
  150.   .word ADC1_2_IRQHandler
  151.   .word FlashCache_IRQHandler
  152.   .word 0
  153.   .word CAN1_RX_IRQHandler
  154.   .word 0
  155.   .word EXTI9_5_IRQHandler
  156.   .word TIM1_BRK_IRQHandler
  157.   .word TIM1_UP_IRQHandler
  158.   .word TIM1_TRG_COM_IRQHandler
  159.   .word TIM1_CC_IRQHandler
  160.   .word TIM2_IRQHandler
  161.   .word TIM3_IRQHandler
  162.   .word TIM4_IRQHandler
  163.   .word I2C1_IRQHandler
  164.   .word 0
  165.   .word I2C2_IRQHandler
  166.   .word 0
  167.   .word SPI1_IRQHandler
  168.   .word SPI2_IRQHandler
  169.   .word UART1_IRQHandler
  170.   .word UART2_IRQHandler
  171.   .word UART3_IRQHandler
  172.   .word EXTI15_10_IRQHandler
  173.   .word RTCAlarm_IRQHandler
  174.   .word OTG_FS_WKUP_IRQHandler
  175.   .word TIM8_BRK_IRQHandler
  176.   .word TIM8_UP_IRQHandler
  177.   .word TIM8_TRG_COM_IRQHandler
  178.   .word TIM8_CC_IRQHandler
  179.   .word ADC3_IRQHandler
  180.   .word 0
  181.   .word SDIO_IRQHandler
  182.   .word TIM5_IRQHandler
  183.   .word SPI3_IRQHandler
  184.   .word UART4_IRQHandler
  185.   .word UART5_IRQHandler
  186.   .word TIM6_IRQHandler
  187.   .word TIM7_IRQHandler
  188.   .word DMA2_Channel1_IRQHandler
  189.   .word DMA2_Channel2_IRQHandler
  190.   .word DMA2_Channel3_IRQHandler
  191.   .word DMA2_Channel4_IRQHandler
  192.   .word DMA2_Channel5_IRQHandler
  193.   .word ETH_IRQHandler
  194.   .word 0
  195.   .word 0
  196.   .word COMP1_2_IRQHandler
  197.   .word 0
  198.   .word 0
  199.   .word OTG_FS_IRQHandler
  200.   .word 0
  201.   .word 0
  202.   .word 0
  203.   .word UART6_IRQHandler
  204.   .word 0
  205.   .word 0
  206.   .word 0
  207.   .word 0
  208.   .word 0
  209.   .word 0
  210.   .word 0
  211.   .word 0
  212.   .word 0
  213.   .word 0
  214.   .word UART7_IRQHandler
  215.   .word UART8_IRQHandler
  216.   .word BootRAM      

  217. /*******************************************************************************
  218. *
  219. * Provide weak aliases for each Exception handler to the Default_Handler.
  220. * As they are weak aliases, any function with the same name will override
  221. * this definition.
  222. *
  223. *******************************************************************************/

  224.   .weak NMI_Handler
  225.   .thumb_set NMI_Handler,Default_Handler

  226.   .weak HardFault_Handler
  227.   .thumb_set HardFault_Handler,Default_Handler

  228.   .weak MemManage_Handler
  229.   .thumb_set MemManage_Handler,Default_Handler

  230.   .weak BusFault_Handler
  231.   .thumb_set BusFault_Handler,Default_Handler

  232.   .weak UsageFault_Handler
  233.   .thumb_set UsageFault_Handler,Default_Handler

  234.   .weak SVC_Handler
  235.   .thumb_set SVC_Handler,Default_Handler

  236.   .weak DebugMon_Handler
  237.   .thumb_set DebugMon_Handler,Default_Handler

  238.   .weak PendSV_Handler
  239.   .thumb_set PendSV_Handler,Default_Handler

  240.   .weak SysTick_Handler
  241.   .thumb_set SysTick_Handler,Default_Handler

  242.   .weak WWDG_IRQHandler
  243.   .thumb_set WWDG_IRQHandler,Default_Handler

  244.   .weak PVD_IRQHandler
  245.   .thumb_set PVD_IRQHandler,Default_Handler

  246.   .weak TAMPER_IRQHandler
  247.   .thumb_set TAMPER_IRQHandler,Default_Handler

  248.   .weak RTC_IRQHandler
  249.   .thumb_set RTC_IRQHandler,Default_Handler

  250.   .weak FLASH_IRQHandler
  251.   .thumb_set FLASH_IRQHandler,Default_Handler

  252.   .weak RCC_CRS_IRQHandler
  253.   .thumb_set RCC_CRS_IRQHandler,Default_Handler

  254.   .weak EXTI0_IRQHandler
  255.   .thumb_set EXTI0_IRQHandler,Default_Handler

  256.   .weak EXTI1_IRQHandler
  257.   .thumb_set EXTI1_IRQHandler,Default_Handler

  258.   .weak EXTI2_IRQHandler
  259.   .thumb_set EXTI2_IRQHandler,Default_Handler

  260.   .weak EXTI3_IRQHandler
  261.   .thumb_set EXTI3_IRQHandler,Default_Handler

  262.   .weak EXTI4_IRQHandler
  263.   .thumb_set EXTI4_IRQHandler,Default_Handler

  264.   .weak DMA1_Channel1_IRQHandler
  265.   .thumb_set DMA1_Channel1_IRQHandler,Default_Handler

  266.   .weak DMA1_Channel2_IRQHandler
  267.   .thumb_set DMA1_Channel2_IRQHandler,Default_Handler

  268.   .weak DMA1_Channel3_IRQHandler
  269.   .thumb_set DMA1_Channel3_IRQHandler,Default_Handler

  270.   .weak DMA1_Channel4_IRQHandler
  271.   .thumb_set DMA1_Channel4_IRQHandler,Default_Handler

  272.   .weak DMA1_Channel5_IRQHandler
  273.   .thumb_set DMA1_Channel5_IRQHandler,Default_Handler

  274.   .weak DMA1_Channel6_IRQHandler
  275.   .thumb_set DMA1_Channel6_IRQHandler,Default_Handler

  276.   .weak DMA1_Channel7_IRQHandler
  277.   .thumb_set DMA1_Channel7_IRQHandler,Default_Handler

  278.   .weak ADC1_2_IRQHandler
  279.   .thumb_set ADC1_2_IRQHandler,Default_Handler

  280.   .weak FlashCache_IRQHandler
  281.   .thumb_set FlashCache_IRQHandler,Default_Handler

  282.   .weak CAN1_RX_IRQHandler
  283.   .thumb_set CAN1_RX_IRQHandler,Default_Handler

  284.   .weak EXTI9_5_IRQHandler
  285.   .thumb_set EXTI9_5_IRQHandler,Default_Handler

  286.   .weak TIM1_BRK_IRQHandler
  287.   .thumb_set TIM1_BRK_IRQHandler,Default_Handler

  288.   .weak TIM1_UP_IRQHandler
  289.   .thumb_set TIM1_UP_IRQHandler,Default_Handler

  290.   .weak TIM1_TRG_COM_IRQHandler
  291.   .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler

  292.   .weak TIM1_CC_IRQHandler
  293.   .thumb_set TIM1_CC_IRQHandler,Default_Handler

  294.   .weak TIM2_IRQHandler
  295.   .thumb_set TIM2_IRQHandler,Default_Handler

  296.   .weak TIM3_IRQHandler
  297.   .thumb_set TIM3_IRQHandler,Default_Handler

  298.   .weak TIM4_IRQHandler
  299.   .thumb_set TIM4_IRQHandler,Default_Handler

  300.   .weak I2C1_IRQHandler
  301.   .thumb_set I2C1_IRQHandler,Default_Handler

  302.   .weak I2C2_IRQHandler
  303.   .thumb_set I2C2_IRQHandler,Default_Handler

  304.   .weak SPI1_IRQHandler
  305.   .thumb_set SPI1_IRQHandler,Default_Handler

  306.   .weak SPI2_IRQHandler
  307.   .thumb_set SPI2_IRQHandler,Default_Handler

  308.   .weak UART1_IRQHandler
  309.   .thumb_set UART1_IRQHandler,Default_Handler

  310.   .weak UART2_IRQHandler
  311.   .thumb_set UART2_IRQHandler,Default_Handler

  312.   .weak UART3_IRQHandler
  313.   .thumb_set UART3_IRQHandler,Default_Handler

  314.   .weak EXTI15_10_IRQHandler
  315.   .thumb_set EXTI15_10_IRQHandler,Default_Handler

  316.   .weak RTCAlarm_IRQHandler
  317.   .thumb_set RTCAlarm_IRQHandler,Default_Handler

  318.   .weak OTG_FS_WKUP_IRQHandler
  319.   .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler

  320.   .weak TIM8_BRK_IRQHandler
  321.   .thumb_set TIM8_BRK_IRQHandler,Default_Handler

  322.   .weak TIM8_UP_IRQHandler
  323.   .thumb_set TIM8_UP_IRQHandler,Default_Handler

  324.   .weak TIM8_TRG_COM_IRQHandler
  325.   .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler

  326.   .weak TIM8_CC_IRQHandler
  327.   .thumb_set TIM8_CC_IRQHandler,Default_Handler

  328.   .weak ADC3_IRQHandler
  329.   .thumb_set ADC3_IRQHandler,Default_Handler

  330.   .weak SDIO_IRQHandler
  331.   .thumb_set SDIO_IRQHandler,Default_Handler

  332.   .weak TIM5_IRQHandler
  333.   .thumb_set TIM5_IRQHandler,Default_Handler

  334.   .weak SPI3_IRQHandler
  335.   .thumb_set SPI3_IRQHandler,Default_Handler

  336.   .weak UART4_IRQHandler
  337.   .thumb_set UART4_IRQHandler,Default_Handler

  338.   .weak UART5_IRQHandler
  339.   .thumb_set UART5_IRQHandler,Default_Handler

  340.   .weak TIM6_IRQHandler
  341.   .thumb_set TIM6_IRQHandler,Default_Handler

  342.   .weak TIM7_IRQHandler
  343.   .thumb_set TIM7_IRQHandler,Default_Handler

  344.   .weak DMA2_Channel1_IRQHandler
  345.   .thumb_set DMA2_Channel1_IRQHandler,Default_Handler

  346.   .weak DMA2_Channel2_IRQHandler
  347.   .thumb_set DMA2_Channel2_IRQHandler,Default_Handler

  348.   .weak DMA2_Channel3_IRQHandler
  349.   .thumb_set DMA2_Channel3_IRQHandler,Default_Handler

  350.   .weak DMA2_Channel4_IRQHandler
  351.   .thumb_set DMA2_Channel4_IRQHandler,Default_Handler

  352.   .weak DMA2_Channel5_IRQHandler
  353.   .thumb_set DMA2_Channel5_IRQHandler,Default_Handler

  354.   .weak ETH_IRQHandler
  355.   .thumb_set ETH_IRQHandler,Default_Handler

  356.   .weak COMP1_2_IRQHandler
  357.   .thumb_set COMP1_2_IRQHandler,Default_Handler

  358.   .weak OTG_FS_IRQHandler
  359.   .thumb_set OTG_FS_IRQHandler,Default_Handler

  360.   .weak UART6_IRQHandler
  361.   .thumb_set UART6_IRQHandler,Default_Handler

  362.   .weak UART7_IRQHandler
  363.   .thumb_set UART7_IRQHandler,Default_Handler

  364.   .weak UART8_IRQHandler
  365.   .thumb_set UART8_IRQHandler,Default_Handler

  366. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1. /*
  2. *****************************************************************************
  3. **
  4. **  File        : MM32F3273G9P_FLASH.ld
  5. **
  6. **  Abstract    : Linker script for MM32F3273G9P Device with
  7. **                512KByte FLASH, 128Byte RAM
  8. **
  9. **                Set heap size, stack size and stack location according
  10. **                to application requirements.
  11. **
  12. **                Set memory bank area and size if external memory is used.
  13. **
  14. **  Target      : MM32F3273G9P
  15. **
  16. **
  17. **  Distribution: The file is distributed as is, without any warranty
  18. **                of any kind.
  19. **
  20. **  (c)Copyright Ac6.
  21. **  You may use this file as-is or modify it according to the needs of your
  22. **  project. Distribution of this file (unmodified or modified) is not
  23. **  permitted. Ac6 permit registered System Workbench for MCU users the
  24. **  rights to distribute the assembled, compiled & linked contents of this
  25. **  file as part of an application binary file, provided that it is built
  26. **  using the System Workbench for MCU toolchain.
  27. **
  28. *****************************************************************************
  29. */

  30. /* Entry Point */
  31. ENTRY(Reset_Handler)

  32. /* Highest address of the user mode stack */
  33. _estack = 0x2001FFFF;    /* end of RAM */

  34. /* Generate a link error if heap and stack don't fit into RAM */
  35. _Min_Heap_Size = 0x800;      /* required amount of heap  */
  36. _Min_Stack_Size = 0x800; /* required amount of stack */

  37. /* Specify the memory areas */
  38. MEMORY
  39. {
  40. FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
  41. RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
  42. }

  43. /* Define output sections */
  44. SECTIONS
  45. {
  46.   /* The startup code goes first into FLASH */
  47.   .isr_vector :
  48.   {
  49.     . = ALIGN(4);
  50.     KEEP(*(.isr_vector)) /* Startup code */
  51.     . = ALIGN(4);
  52.   } >FLASH

  53.   /* The program code and other data goes into FLASH */
  54.   .text :
  55.   {
  56.     . = ALIGN(4);
  57.     *(.text)           /* .text sections (code) */
  58.     *(.text*)          /* .text* sections (code) */
  59.     *(.glue_7)         /* glue arm to thumb code */
  60.     *(.glue_7t)        /* glue thumb to arm code */
  61.     *(.eh_frame)

  62.     KEEP (*(.init))
  63.     KEEP (*(.fini))

  64.     . = ALIGN(4);
  65.     _etext = .;        /* define a global symbols at end of code */
  66.   } >FLASH

  67.   /* Constant data goes into FLASH */
  68.   .rodata :
  69.   {
  70.     . = ALIGN(4);
  71.     *(.rodata)         /* .rodata sections (constants, strings, etc.) */
  72.     *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
  73.     . = ALIGN(4);
  74.   } >FLASH

  75.   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  76.   .ARM : {
  77.     __exidx_start = .;
  78.     *(.ARM.exidx*)
  79.     __exidx_end = .;
  80.   } >FLASH

  81.   .preinit_array     :
  82.   {
  83.     PROVIDE_HIDDEN (__preinit_array_start = .);
  84.     KEEP (*(.preinit_array*))
  85.     PROVIDE_HIDDEN (__preinit_array_end = .);
  86.   } >FLASH
  87.   .init_array :
  88.   {
  89.     PROVIDE_HIDDEN (__init_array_start = .);
  90.     KEEP (*(SORT(.init_array.*)))
  91.     KEEP (*(.init_array*))
  92.     PROVIDE_HIDDEN (__init_array_end = .);
  93.   } >FLASH
  94.   .fini_array :
  95.   {
  96.     PROVIDE_HIDDEN (__fini_array_start = .);
  97.     KEEP (*(SORT(.fini_array.*)))
  98.     KEEP (*(.fini_array*))
  99.     PROVIDE_HIDDEN (__fini_array_end = .);
  100.   } >FLASH

  101.   /* used by the startup to initialize data */
  102.   _sidata = LOADADDR(.data);

  103.   /* Initialized data sections goes into RAM, load LMA copy after code */
  104.   .data :
  105.   {
  106.     . = ALIGN(4);
  107.     _sdata = .;        /* create a global symbol at data start */
  108.     *(.data)           /* .data sections */
  109.     *(.data*)          /* .data* sections */

  110.     . = ALIGN(4);
  111.     _edata = .;        /* define a global symbol at data end */
  112.   } >RAM AT> FLASH

  113.   
  114.   /* Uninitialized data section */
  115.   . = ALIGN(4);
  116.   .bss :
  117.   {
  118.     /* This is used by the startup in order to initialize the .bss secion */
  119.     _sbss = .;         /* define a global symbol at bss start */
  120.     __bss_start__ = _sbss;
  121.     *(.bss)
  122.     *(.bss*)
  123.     *(COMMON)

  124.     . = ALIGN(4);
  125.     _ebss = .;         /* define a global symbol at bss end */
  126.     __bss_end__ = _ebss;
  127.   } >RAM

  128.   /* User_heap_stack section, used to check that there is enough RAM left */
  129.   ._user_heap_stack :
  130.   {
  131.     . = ALIGN(8);
  132.     PROVIDE ( end = . );
  133.     PROVIDE ( _end = . );
  134.     . = . + _Min_Heap_Size;
  135.     . = . + _Min_Stack_Size;
  136.     . = ALIGN(8);
  137.   } >RAM

  138.   

  139.   /* Remove information from the standard libraries */
  140.   /DISCARD/ :
  141.   {
  142.     libc.a ( * )
  143.     libm.a ( * )
  144.     libgcc.a ( * )
  145.   }

  146.   .ARM.attributes 0 : { *(.ARM.attributes) }
  147. }
5. 更改完后,需要对 src 文件夹下的文件做替换,从 MM32F3270 官方的闪灯例程中找到对应文件替换过来,为了保险起见,将以上几个文件也包含到目录中(也是后面调试时才发现一定要添加进来的,不然编译通过但是无法正常运行,未包含启动文件),并且将 uart.c 的retarget 修改好适配 gcc 编译器
stm32f103ze pio 结构目录_改版.png
6. 至此已经完成了替代,可以进行 build 编译、upload 下载以及使用 Cortex-Debug 调试工程了
mm32f3273 pio ok.png mm32f3273 pio upload ok.png mm32f3273 pio debug ok.png mm32f3270 debug asm 反编译.png
下载调试使用到 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)

打赏榜单

21小跑堂 打赏了 100.00 元 2022-07-04
理由:恭喜通过原创文章审核!请多多加油哦!

评论

以ST开发板为跳板,实现MM32开发板移植到VS-Code的PlatformIO 环境中,实现过程具有借鉴意义,但是由于官方适配问题,此方案还有挺长的路要走  发表于 2022-7-4 10:05
zwk34 发表于 2022-6-29 08:56 | 显示全部楼层
谢谢分享。
ACE丶打铁匠 发表于 2022-10-9 15:47 | 显示全部楼层
感谢分享
芯路例程 发表于 2022-10-13 17:05 | 显示全部楼层
PlatformIO之前也听过,一直没实际用过,看样子好像还不赖。
星辰大海不退缩 发表于 2022-10-14 08:33 | 显示全部楼层
PlatformIO 讲解的很详细,过程配置也非常清楚,后期有时间自己试一下,赞
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

239

帖子

13

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