你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

使用xmake构建STM32程序

[复制链接]
anobodykey 发布时间:2018-5-6 15:24
本帖最后由 anobodykey 于 2018-5-15 14:03 编辑

主机环境:Windows 7 SP1

编译器版本:gcc-arm-none-eabi-7-2017-q4-major-win32

目标板:STM32F103C8T6单板

STM32库版本:STM32Cube_FW_F1_V1.6.0

XMAKE版本:2.1.9

之前一段时间一直在思索跨平台开发的问题,以前开发STM32用的是MDK开发环境,但该软件又只能在Windows平台使用,跨平台的集成开发环境有SW4STM32(支持windows、macos、linux),TureStudio(支持windows、linux),以及Embeded Studio(支持windows、macos、linux),最后的选择就是gcc了。其实SW4STM32和TureStudio也都是基于gcc的,两者基本类似,而Embeded Studio之前用过几次版本更新的也挺快的,就是现在要申请license才能编译,懒得弄了,刚好借此来学习一下gcc,网上大多数gcc历程都是gcc+eclipse+makefile的组合。之前申请了一块NXP的54608板卡,在SDK中有提到CMake,就去网上了解了一下,是一个挺好的工具,同时又知晓了另一个构建工具,即今天的主题-XMake,网址如下:http://xmake.io,有兴趣的可以去了解一下,xmake与cmake的区别是它不是生成工程文件为主,而是直接去编译,采用lua语言,支持三大平台,目前我也只是去官网学习了一下,还是处于一知半解的状态,因此用它来构建一下STM32来学习一下xmake和gcc,可谓是一举两得。


首先是安装xmake以及gcc工具链,并把它们添加到PATH中,如下:

1.JPG

接下来是编辑好我们的源码文件,由于只是学习,只需要很简单的功能即可,这里就以串口为例,进行简单的输出,拷贝UART_TwoBoards_ComPolling工程,命名为UART_Xmake,组织如下:

2.JPG

其中启动文件以及链接文件是从SW4STM32示例中拷贝出来的,主程序如下:

  1. /**
  2.   ******************************************************************************
  3.   * @file    UART/UART_TwoBoards_ComPolling/Src/main.c
  4.   * @author  MCD Application Team
  5.   * @version V1.5.0
  6.   * @date    14-April-2017
  7.   * @brief   This sample code shows how to use UART HAL API to transmit
  8.   *          and receive a data buffer with a communication process based on
  9.   *          polling transfer.
  10.   *          The communication is done using 2 Boards.
  11.   ******************************************************************************
  12.   * @attention
  13.   *
  14.   * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  15.   *
  16.   * Redistribution and use in source and binary forms, with or without modification,
  17.   * are permitted provided that the following conditions are met:
  18.   *   1. Redistributions of source code must retain the above copyright notice,
  19.   *      this list of conditions and the following disclaimer.
  20.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  21.   *      this list of conditions and the following disclaimer in the documentation
  22.   *      and/or other materials provided with the distribution.
  23.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  24.   *      may be used to endorse or promote products derived from this software
  25.   *      without specific prior written permission.
  26.   *
  27.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  31.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  33.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  34.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  35.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37.   *
  38.   ******************************************************************************
  39.   */

  40. /* Includes ------------------------------------------------------------------*/
  41. #include "main.h"

  42. /** @addtogroup STM32F1xx_HAL_Examples
  43.   * @{
  44.   */

  45. /** @addtogroup UART_TwoBoards_ComPolling
  46.   * @{
  47.   */

  48. /* Private typedef -----------------------------------------------------------*/
  49. /* Private define ------------------------------------------------------------*/
  50. //#define TRANSMITTER_BOARD

  51. /* Private macro -------------------------------------------------------------*/
  52. /* Private variables ---------------------------------------------------------*/
  53. /* UART handler declaration */
  54. UART_HandleTypeDef UartHandle;

  55. /* Buffer used for transmission */
  56. uint8_t aTxBuffer[] = " **** UART_Xmake sample ****";

  57. /* Private function prototypes -----------------------------------------------*/
  58. void SystemClock_Config(void);
  59. static void Error_Handler(void);

  60. /* Private functions ---------------------------------------------------------*/

  61. /**
  62.   * @brief  Main program
  63.   * @param  None
  64.   * @retval None
  65.   */
  66. int main(void)
  67. {
  68.   /* STM32F103xB HAL library initialization:
  69.        - Configure the Flash prefetch
  70.        - Systick timer is configured by default as source of time base, but user
  71.          can eventually implement his proper time base source (a general purpose
  72.          timer for example or other time source), keeping in mind that Time base
  73.          duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
  74.          handled in milliseconds basis.
  75.        - Set NVIC Group Priority to 4
  76.        - Low Level Initialization
  77.      */
  78.   HAL_Init();

  79.   /* Configure the system clock to 64 MHz */
  80.   SystemClock_Config();

  81.   /*##-1- Configure the UART peripheral ######################################*/
  82.   /* Put the USART peripheral in the Asynchronous mode (UART Mode) */
  83.   /* UART configured as follows:
  84.       - Word Length = 8 Bits
  85.       - Stop Bit = One Stop bit
  86.       - Parity = None
  87.       - BaudRate = 9600 baud
  88.       - Hardware flow control disabled (RTS and CTS signals) */
  89.   UartHandle.Instance        = USARTx;

  90.   UartHandle.Init.BaudRate     = 9600;
  91.   UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;
  92.   UartHandle.Init.StopBits     = UART_STOPBITS_1;
  93.   UartHandle.Init.Parity       = UART_PARITY_NONE;
  94.   UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
  95.   UartHandle.Init.Mode         = UART_MODE_TX_RX;
  96.   if(HAL_UART_DeInit(&UartHandle) != HAL_OK)
  97.   {
  98.     Error_Handler();
  99.   }  
  100.   if(HAL_UART_Init(&UartHandle) != HAL_OK)
  101.   {
  102.     Error_Handler();
  103.   }
  104.   
  105.   /*##-2- Start the transmission process #####################################*/  
  106.   /* While the UART in reception process, user can transmit data through
  107.      "aTxBuffer" buffer */
  108.   if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 5000)!= HAL_OK)
  109.   {
  110.     Error_Handler();   
  111.   }
  112.   /* Infinite loop */
  113.   while (1)
  114.   {
  115.   }
  116. }

  117. /**
  118.   * @brief  System Clock Configuration
  119.   *         The system Clock is configured as follow :
  120.   *            System Clock source            = PLL (HSI)
  121.   *            SYSCLK(Hz)                     = 64000000
  122.   *            HCLK(Hz)                       = 64000000
  123.   *            AHB Prescaler                  = 1
  124.   *            APB1 Prescaler                 = 2
  125.   *            APB2 Prescaler                 = 1
  126.   *            PLLMUL                         = 16
  127.   *            Flash Latency(WS)              = 2
  128.   * @param  None
  129.   * @retval None
  130.   */
  131. void SystemClock_Config(void)
  132. {
  133.   RCC_ClkInitTypeDef clkinitstruct = {0};
  134.   RCC_OscInitTypeDef oscinitstruct = {0};
  135.   
  136.   /* Configure PLL ------------------------------------------------------*/
  137.   /* PLL configuration: PLLCLK = (HSI / 2) * PLLMUL = (8 / 2) * 16 = 64 MHz */
  138.   /* PREDIV1 configuration: PREDIV1CLK = PLLCLK / HSEPredivValue = 64 / 1 = 64 MHz */
  139.   /* Enable HSI and activate PLL with HSi_DIV2 as source */
  140.   oscinitstruct.OscillatorType  = RCC_OSCILLATORTYPE_HSI;
  141.   oscinitstruct.HSEState        = RCC_HSE_OFF;
  142.   oscinitstruct.LSEState        = RCC_LSE_OFF;
  143.   oscinitstruct.HSIState        = RCC_HSI_ON;
  144.   oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  145.   oscinitstruct.HSEPredivValue    = RCC_HSE_PREDIV_DIV1;
  146.   oscinitstruct.PLL.PLLState    = RCC_PLL_ON;
  147.   oscinitstruct.PLL.PLLSource   = RCC_PLLSOURCE_HSI_DIV2;
  148.   oscinitstruct.PLL.PLLMUL      = RCC_PLL_MUL16;
  149.   if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK)
  150.   {
  151.     /* Initialization Error */
  152.     while(1);
  153.   }

  154.   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  155.      clocks dividers */
  156.   clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  157.   clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  158.   clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  159.   clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1;
  160.   clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2;  
  161.   if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK)
  162.   {
  163.     /* Initialization Error */
  164.     while(1);
  165.   }
  166. }

  167. /**
  168.   * @brief  UART error callbacks
  169.   * @param  UartHandle: UART handle
  170.   * @note   This example shows a simple way to report transfer error, and you can
  171.   *         add your own implementation.
  172.   * @retval None
  173.   */
  174. void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
  175. {
  176.     Error_Handler();
  177. }

  178. /**
  179.   * @brief  This function is executed in case of error occurrence.
  180.   * @param  None
  181.   * @retval None
  182.   */
  183. static void Error_Handler(void)
  184. {
  185.   while(1)
  186.   {
  187.     HAL_Delay(1000);
  188.   }
  189. }

  190. #ifdef  USE_FULL_ASSERT

  191. /**
  192.   * @brief  Reports the name of the source file and the source line number
  193.   *         where the assert_param error has occurred.
  194.   * @param  file: pointer to the source file name
  195.   * @param  line: assert_param error line source number
  196.   * @retval None
  197.   */
  198. void assert_failed(uint8_t* file, uint32_t line)
  199. {
  200.   /* User can add his own implementation to report the file name and line number,
  201.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  202.   /* Infinite loop */
  203.   while (1)
  204.   {
  205.   }
  206. }
  207. #endif


  208. /**
  209.   * @}
  210.   */

  211. /**
  212.   * @}
  213.   */

  214. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码

打开Powershell进入到该目录中,如下:

3.JPG

xmake构建程序需要一个名为xmake.lua的文件,该文件可以自动生成,输入xmake后会提示你找不到xmake.lua文件,输入y来生成该文件,或是从xmake安装目录下拷贝一个示例的xmake.lua文件,两种方式都可以。我使用的第一种方式,有了xmake.lua文件后我们就可以在上面添加一下配置信息来构建我们的STM32程序,关于xmake.lua的信息可以去官网上查看手册来了解它.


此外,我们还需要对xmake做一些配置,xmake是支持多平台的构建,包括windows、linux、macos、cross、android等,这里我们需要配置为cross即跨平台,输入xmake f --menu会弹出配置对话框,如下:

4.JPG

进入第一项Basic Configuration,配置平台、体系架构、以及目标类型,如下:

5.JPG

这里我们需要配置前6项,前5项配置很容易,做一些选择即可,接下来配置第6项,如下:

6.JPG

设置工具链前缀以及目录,后面还需要配置编译器以及连接器,如下:

8.JPG

7.JPG

配置完后保存退出,会发现当前目录下多了一个.xmake文件夹

9.JPG

其中xmake.conf就包含了刚才我们的配置信息:

捕获.JPG

其他文件的信息,可以多去官网查看,.xmake文件夹下的文件是xmake自动生成的,直接修改配置文件是不行的。


接下来就是更改我们的xmake.lua文件,该文件主要是添加源文件,设置头文件搜索路径、添加宏定义、以及设置编译和链接选项,该文件内容如下:

  1. -- the debug mode
  2. if is_mode("debug") then
  3.    
  4.     -- enable the debug symbols
  5.     set_symbols("debug")

  6.     -- disable optimization
  7.     set_optimize("none")
  8. end

  9. -- the release mode
  10. if is_mode("release") then

  11.     -- set the symbols visibility: hidden
  12.     set_symbols("hidden")

  13.     -- enable fastest optimization
  14.     set_optimize("fastest")

  15.     -- strip all symbols
  16.     set_strip("all")
  17. end
  18. -- define target
  19. target("UART_Xmake.elf")

  20.     -- set kind
  21.     set_kind("binary")

  22.     -- add files
  23.     add_files("startup_stm32f103xb.s")
  24.     add_files("Src/*.c")
  25.     add_files("../../../../../Drivers/BSP/STM32F1xx_Nucleo/stm32f1xx_nucleo.c")
  26.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c")
  27.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c")
  28.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c")
  29.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c")
  30.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c")
  31.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c")
  32.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c")
  33.     add_files("../../../../../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c")
  34.         
  35.     --add include search directories
  36.     add_includedirs("Inc")
  37.     add_includedirs("../../../../../Drivers/CMSIS/Device/ST/STM32F1xx/Include")
  38.     add_includedirs("../../../../../Drivers/CMSIS/Include")
  39.     add_includedirs("../../../../../Drivers/STM32F1xx_HAL_Driver/Inc")
  40.     add_includedirs("../../../../../Drivers/BSP/STM32F1xx_Nucleo")
  41.    
  42.     --add macro defination
  43.     add_defines("USE_HAL_DRIVER","STM32F103xB","USE_STM32F1xx_NUCLEO")
  44.    
  45.     -- set warning all as error
  46.     set_warnings("all", "error")
  47.    
  48.     -- set language: c99
  49.     set_languages("c99")
  50.         
  51.     add_cxflags("-mcpu=cortex-m3 -mthumb -mfloat-abi=soft --specs=nano.specs  -ffunction-sections -fdata-sections")
  52.     add_ldflags("-mcpu=cortex-m3 -mthumb -mfloat-abi=soft --specs=nosys.specs --specs=nano.specs -T"STM32F103RBTx_FLASH.ld" -Wl,--gc-sections")
  53.     after_build(function(target)
  54.         os.exec("arm-none-eabi-objcopy -O binary .\\build\\UART_Xmake.elf .\\build\\UART_Xmake.bin")
  55.     end)
  56. -- FAQ
  57. --
  58. -- You can enter the project directory firstly before building project.
  59. --   
  60. --   $ cd projectdir
  61. --
  62. -- 1. How to build project?
  63. --   
  64. --   $ xmake
  65. --
  66. -- 2. How to configure project?
  67. --
  68. --   $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
  69. --
  70. -- 3. Where is the build output directory?
  71. --
  72. --   The default output directory is `./build` and you can configure the output directory.
  73. --
  74. --   $ xmake f -o outputdir
  75. --   $ xmake
  76. --
  77. -- 4. How to run and debug target after building project?
  78. --
  79. --   $ xmake run [targetname]
  80. --   $ xmake run -d [targetname]
  81. --
  82. -- 5. How to install target to the system directory or other output directory?
  83. --
  84. --   $ xmake install
  85. --   $ xmake install -o installdir
  86. --
  87. -- 6. Add some frequently-used compilation flags in xmake.lua
  88. --
  89. -- @code
  90. --    -- add macro defination
  91. --    add_defines("NDEBUG", "_GNU_SOURCE=1")
  92. --
  93. --    -- set warning all as error
  94. --    set_warnings("all", "error")
  95. --
  96. --    -- set language: c99, c++11
  97. --    set_languages("c99", "cxx11")
  98. --
  99. --    -- set optimization: none, faster, fastest, smallest
  100. --    set_optimize("fastest")
  101. --   
  102. --    -- add include search directories
  103. --    add_includedirs("/usr/include", "/usr/local/include")
  104. --
  105. --    -- add link libraries and search directories
  106. --    add_links("tbox", "z", "pthread")
  107. --    add_linkdirs("/usr/local/lib", "/usr/lib")
  108. --
  109. --    -- add compilation and link flags
  110. --    add_cxflags("-stdnolib", "-fno-strict-aliasing")
  111. --    add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
  112. --
  113. -- @endcode
  114. --
  115. -- 7. If you want to known more usage about xmake, please see http://xmake.io/#/home
  116. --
  117.    
复制代码

至此,xmake配置就算完成了,在当前目录下输入xmake会自动编译该工程,最后会在build目录下生成UART_Xmake.bin文件,烧录该文件到目标板中运行,结果如下:

11.JPG

好了,使用xmake来构建STM32程序的示例就完成了。





评分

参与人数 1 ST金币 +2 收起 理由
MrJiu + 2

查看全部评分

收藏 2 评论11 发布时间:2018-5-6 15:24

举报

11个回答
anobodykey 回答时间:2018-5-6 15:26:13
自己顶一顶
pythonworld 回答时间:2018-5-6 16:35:08
谢谢分享,是不是还得会lua语言?
anobodykey 回答时间:2018-5-6 16:47:56
pythonworld 发表于 2018-5-6 16:35
谢谢分享,是不是还得会lua语言?

不需要的,除非你要扩展插件之类的
黑皮男 回答时间:2018-5-7 08:12:37
赞一个
MrJiu 回答时间:2018-5-7 09:34:48
确实不错!!!
butterflyspring 回答时间:2018-5-7 10:45:03
不错,这是个扫盲帖...赞!
andey 回答时间:2018-5-7 11:08:19
提示: 作者被禁止或删除 内容自动屏蔽
xiajintaord 回答时间:2018-5-7 11:47:01
感谢楼主的分享!在公司每天忙业务,解 bug ,没得机会沉下心思来研究这些细致的东西;
zjp1013 回答时间:2018-5-14 20:07:35
你好,按照你的方法我试了一下,有如下错误,请指点一下谢谢
[00%]: compiling.release Src\system_stm32f1xx.c
[20%]: compiling.release Src\stm32f1xx_hal_msp.c
[40%]: compiling.release Src\stm32f1xx_it.c
[60%]: compiling.release Src\main.c
error: arm-none-eabi-gcc: error: unrecognized command line option '-Qunused-arguments'
anobodykey 回答时间:2018-5-15 09:20:18
zjp1013 发表于 2018-5-14 20:07
你好,按照你的方法我试了一下,有如下错误,请指点一下谢谢
[00%]: compiling.release Src\system_stm32f1 ...

看名字是提示你命令行参数无法识别,你把这个参数去掉再重新编译下
jcx0324 回答时间:2018-5-15 09:34:47
又一种方案                  

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版