[其他ST产品] VSCode搭建STM32开发环境(极简自我搭建&懒人直接使用插件)

[复制链接]
8585|56
 楼主| 无法去污粉 发表于 2023-1-31 20:03 | 显示全部楼层
但是依葫芦画瓢这样改是不行的。为什么呢?参考了这篇文章后,知道了原来是因为底层实现也不一样,gcc还需要重写_write函数。

初步总结:
  1. #ifdef __GNUC__
  2.   /* With GCC, small printf (option LD Linker->Libraries->Small printf
  3.      set to 'Yes') calls __io_putchar() */
  4.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  5. #else
  6.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  7. #endif /* __GNUC__ */

  8. PUTCHAR_PROTOTYPE
  9. {
  10.   /* Place your implementation of fputc here */
  11.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  12.   HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);

  13.   return ch;
  14. }

  15. __attribute__((weak)) int _write(int file, char *ptr, int len)
  16. {
  17.    int DataIdx;
  18.    for (DataIdx = 0; DataIdx < len; DataIdx++)
  19.    {
  20.       __io_putchar(*ptr++);
  21.    }
  22.    return len;
  23. }
 楼主| 无法去污粉 发表于 2023-1-31 20:03 | 显示全部楼层
如果存在中途也要用keil编译的可能,就把重写_write的部分也加上条件编译。

此外,由于keil新版编译器AC6基于clang,因此,宏定义里定义了__GNU__,所以如果使用AC6的话,仅靠__GNU__就无法区分了。需要同时判断是否定义了__GNU__和__clang__。
 楼主| 无法去污粉 发表于 2023-1-31 20:03 | 显示全部楼层
再加上对scanf的重定向,最后是:
  1. #if defined (__GNUC__) && !defined (__clang__)
  2. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  3. #define GETCHAR_PROTOTYPE int __io_getchar(void)
  4. #else
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  6. #define GETCHAR_PROTOTYPE int fgetc(FILE *f)
  7. #endif

  8. PUTCHAR_PROTOTYPE
  9. {
  10.   HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  11.   return ch;
  12. }

  13. GETCHAR_PROTOTYPE
  14. {
  15.   uint8_t ch;
  16.   HAL_UART_Receive(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  17.   return ch;
  18. }

  19. #if defined (__GNUC__) && !defined (__clang__)
  20. __attribute__((weak)) int _write(int file, char *ptr, int len)
  21. {
  22.   int DataIdx;
  23.   for (DataIdx = 0; DataIdx < len; DataIdx++)
  24.     __io_putchar(*ptr++);
  25.   return len;
  26. }

  27. __attribute__((weak)) int _read(int file, char *ptr, int len)
  28. {
  29.   int DataIdx;
  30.   for (DataIdx = 0; DataIdx < len; DataIdx++)
  31.     *ptr++ = __io_getchar();
  32.   return len;
  33. }
  34. #endif
 楼主| 无法去污粉 发表于 2023-1-31 20:05 | 显示全部楼层
此外,需要在Makefile里加上-u _printf_float和-u _scanf_float否则无法输入输出浮点数:
  1. LDFLAGS = $(MCU) -u _printf_float -u _scanf_float -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
 楼主| 无法去污粉 发表于 2023-1-31 20:05 | 显示全部楼层
引入其他库
用make进行编译时,make是根据Makefile里的内容寻找宏,头文件和哪些文件需要编译。而这个Makefile是STM32CubeMX根据选择的外设等自动生成的,因此,Makefile里显然只会包含HAL库或HAL的部分(取决于用户自己在生成工程时的选择),如果要引入自己写的驱动,就需要对Makefile进行改动。
 楼主| 无法去污粉 发表于 2023-1-31 20:16 | 显示全部楼层
添加.c文件,在这个地方:
7371063d9069c74665.png
直接在后面按照格式添加.c文件在工程下的相对路径即可。
 楼主| 无法去污粉 发表于 2023-1-31 20:17 | 显示全部楼层

[color=var(--md-editor-text-color-active)]添加头文件,在这个地方:

[color=var(--md-editor-text-color-active)] watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAYmVuX2JsYWNr,size_20,color_FFFFFF,t_70,g_se,x_16.jpg

[color=var(--md-editor-text-color-active)]同理,写上头文件在工程下的相对路径就行,别忘了前面的-I。


 楼主| 无法去污粉 发表于 2023-1-31 20:17 | 显示全部楼层
总结
做完上述准备工作后,一次开发的流程大致是这样:

STM32CubeMX创建工程,generate code时选Makefile->

把写好的.vscode文件夹复制到工程目录下->

vscode打开文件夹后,修改c_cpp_properties.json里芯片型号的宏定义以及task.json和launch.json里的文件名->

如需使用第三方库,修改Makefile->

如需使用串口重定向,复制相关代码,如需打印浮点数,修改Makefile对应位置->

愉快coding!
 楼主| 无法去污粉 发表于 2023-1-31 20:17 | 显示全部楼层
方法二:直接使用插件ioT Link1.准备工具

[color=var(--md-editor-text-color-active)](1)VSCode

[color=var(--md-editor-text-color-active)](2)STM32CubeMX

[color=var(--md-editor-text-color-active)](3)vscode内下载插件ioT Link,如图:

[color=var(--md-editor-text-color-active)] watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Jlbl9ibGFjaw==,size_16,color_FFFFFF,t_70.jpg

[color=var(--md-editor-text-color-active)]安装好之后应该可以看到左下角有这样一栏: 20201123224752982.png


 楼主| 无法去污粉 发表于 2023-1-31 20:17 | 显示全部楼层
.创建工程

[color=var(--md-editor-text-color-active)](1)首先用STM32CubeMX创建工程,还是一样的,具体配置不叙述,注意生成时选择Makefile。

[color=var(--md-editor-text-color-active)] watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Jlbl9ibGFjaw==,size_16,color_FFFFFF,t_70.jpg


 楼主| 无法去污粉 发表于 2023-1-31 20:18 | 显示全部楼层

[color=var(--md-editor-text-color-active)](2)打开vscode,点击左下角ioT LINK插件的home 20201123225111308.png 后,来到如图所示的界面:

[color=var(--md-editor-text-color-active)] watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Jlbl9ibGFjaw==,size_16,color_FFFFFF,t_70.jpg


 楼主| 无法去污粉 发表于 2023-1-31 20:18 | 显示全部楼层

[color=var(--md-editor-text-color-active)](3)点击“导入GCC工程”并选择刚才创建的工程的路径:

[color=var(--md-editor-text-color-active)] watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Jlbl9ibGFjaw==,size_16,color_FFFFFF,t_70.jpg

[color=var(--md-editor-text-color-active)]工程目录选择刚才生成的工程目录,Makefile会自动选择不用管,硬件平台选择自己的板子就好(没有的话就随便选一个,问题不大)。


 楼主| 无法去污粉 发表于 2023-1-31 20:18 | 显示全部楼层

[color=var(--md-editor-text-color-active)](4)再次点击home,然后点击IoT Link设置,选择“调试器”。

[color=var(--md-editor-text-color-active)](i)如果选择JLink的话,根据板子选择就好,此处不多赘述

[color=var(--md-editor-text-color-active)](ii)如果选择OpenOCD的话要注意OpenOCD参数的设置,格式为:-f ./interface/{调试器}.cfg -f ./target/{目标器件}.cfg。例如这里我用的是stm32f103,stlink,参数配置如下:

[color=var(--md-editor-text-color-active)] 20201123234159880.png

[color=var(--md-editor-text-color-active)]       这里-f参数是指定配置文件,openocd的目录中有很多写好的配置文件,其中interface文件夹对应调试器,target文件夹对应目标器件。


 楼主| 无法去污粉 发表于 2023-1-31 20:18 | 显示全部楼层

[color=var(--md-editor-text-color-active)](注意这里OpenOCD路径自动填上了${system_default},因为IoT Link这个插件自带gcc,make,openocd这些工具,可以看到其他工具的路径也被自动添上                     了${system_default},当然这里也可以选择方法一中自己下载的工具的路径。比如我就因为强迫症把插件自带的这些工具都删了,转而用自己下载的,这样也方便日后管理和更新)

[color=var(--md-editor-text-color-active)](如果要和我一样使用自己下载的工具路径的话,可以移步最后的“其他事项”部分,这里还是有一些坑的)


 楼主| 无法去污粉 发表于 2023-1-31 20:19 | 显示全部楼层

[color=var(--md-editor-text-color-active)]点击左下角的按钮进行编译和烧录:

[color=var(--md-editor-text-color-active)] 20201123231215525.png

[color=var(--md-editor-text-color-active)]Build即编译,Rebuild即重新编译,Download即烧录,Serial是内置的串口助手,Home就是更改IoT Link的设置。

[color=var(--md-editor-text-color-active)]按F5可以进行调试:

[color=var(--md-editor-text-color-active)] watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Jlbl9ibGFjaw==,size_16,color_FFFFFF,t_70.jpg


 楼主| 无法去污粉 发表于 2023-1-31 20:19 | 显示全部楼层
其他事项(一些坑)
(1)方法二中使用自己下载的工具路径时,注意编译器路径要选择arm-none-eabi的路径且只选择到bin文件夹,不要包含arm-none-eabi-gcc.exe;调试器中的OpenOCD路径要选饿到openocd.exe,而且使用插件的浏览功能只能选择到文件夹,不能选择到openocd.exe这个程序,需要自己手打;工具链中的Make工具路径和GCC工具路径和OpenOCD路径同理都要选择到具体程序。
AProgrammer 发表于 2024-9-14 11:19 | 显示全部楼层
STM32CubeMX 必须下载这个吗? 使用标准库能开发吗? 本地之前用的keil的工程,想变成vscode来开发
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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