发新帖我要提问
123
返回列表
打印
[其他ST产品]

VSCode搭建STM32开发环境(极简自我搭建&懒人直接使用插件)

[复制链接]
楼主: 无法去污粉
手机看帖
扫描二维码
随时随地手机跟帖
41
无法去污粉|  楼主 | 2023-1-31 20:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
但是依葫芦画瓢这样改是不行的。为什么呢?参考了这篇文章后,知道了原来是因为底层实现也不一样,gcc还需要重写_write函数。

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

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

  return ch;
}

__attribute__((weak)) int _write(int file, char *ptr, int len)
{
   int DataIdx;
   for (DataIdx = 0; DataIdx < len; DataIdx++)
   {
      __io_putchar(*ptr++);
   }
   return len;
}

使用特权

评论回复
42
无法去污粉|  楼主 | 2023-1-31 20:03 | 只看该作者
如果存在中途也要用keil编译的可能,就把重写_write的部分也加上条件编译。

此外,由于keil新版编译器AC6基于clang,因此,宏定义里定义了__GNU__,所以如果使用AC6的话,仅靠__GNU__就无法区分了。需要同时判断是否定义了__GNU__和__clang__。

使用特权

评论回复
43
无法去污粉|  楼主 | 2023-1-31 20:03 | 只看该作者
再加上对scanf的重定向,最后是:
#if defined (__GNUC__) && !defined (__clang__)
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(void)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

GETCHAR_PROTOTYPE
{
  uint8_t ch;
  HAL_UART_Receive(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

#if defined (__GNUC__) && !defined (__clang__)
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
  int DataIdx;
  for (DataIdx = 0; DataIdx < len; DataIdx++)
    __io_putchar(*ptr++);
  return len;
}

__attribute__((weak)) int _read(int file, char *ptr, int len)
{
  int DataIdx;
  for (DataIdx = 0; DataIdx < len; DataIdx++)
    *ptr++ = __io_getchar();
  return len;
}
#endif

使用特权

评论回复
44
无法去污粉|  楼主 | 2023-1-31 20:05 | 只看该作者
此外,需要在Makefile里加上-u _printf_float和-u _scanf_float否则无法输入输出浮点数:
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

使用特权

评论回复
45
无法去污粉|  楼主 | 2023-1-31 20:05 | 只看该作者
引入其他库
用make进行编译时,make是根据Makefile里的内容寻找宏,头文件和哪些文件需要编译。而这个Makefile是STM32CubeMX根据选择的外设等自动生成的,因此,Makefile里显然只会包含HAL库或HAL的部分(取决于用户自己在生成工程时的选择),如果要引入自己写的驱动,就需要对Makefile进行改动。

使用特权

评论回复
46
无法去污粉|  楼主 | 2023-1-31 20:16 | 只看该作者
添加.c文件,在这个地方:

直接在后面按照格式添加.c文件在工程下的相对路径即可。

使用特权

评论回复
47
无法去污粉|  楼主 | 2023-1-31 20:17 | 只看该作者

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

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

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


使用特权

评论回复
48
无法去污粉|  楼主 | 2023-1-31 20:17 | 只看该作者
总结
做完上述准备工作后,一次开发的流程大致是这样:

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

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

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

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

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

愉快coding!

使用特权

评论回复
49
无法去污粉|  楼主 | 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)]

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


使用特权

评论回复
50
无法去污粉|  楼主 | 2023-1-31 20:17 | 只看该作者
.创建工程

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

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


使用特权

评论回复
51
无法去污粉|  楼主 | 2023-1-31 20:18 | 只看该作者

[color=var(--md-editor-text-color-active)](2)打开vscode,点击左下角ioT LINK插件的home

后,来到如图所示的界面:

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


使用特权

评论回复
52
无法去污粉|  楼主 | 2023-1-31 20:18 | 只看该作者

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

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

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


使用特权

评论回复
53
无法去污粉|  楼主 | 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)]

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


使用特权

评论回复
54
无法去污粉|  楼主 | 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)](如果要和我一样使用自己下载的工具路径的话,可以移步最后的“其他事项”部分,这里还是有一些坑的)


使用特权

评论回复
55
无法去污粉|  楼主 | 2023-1-31 20:19 | 只看该作者

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

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

[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)]


使用特权

评论回复
56
无法去污粉|  楼主 | 2023-1-31 20:19 | 只看该作者
其他事项(一些坑)
(1)方法二中使用自己下载的工具路径时,注意编译器路径要选择arm-none-eabi的路径且只选择到bin文件夹,不要包含arm-none-eabi-gcc.exe;调试器中的OpenOCD路径要选饿到openocd.exe,而且使用插件的浏览功能只能选择到文件夹,不能选择到openocd.exe这个程序,需要自己手打;工具链中的Make工具路径和GCC工具路径和OpenOCD路径同理都要选择到具体程序。

使用特权

评论回复
57
AProgrammer| | 2024-9-14 11:19 | 只看该作者
STM32CubeMX 必须下载这个吗? 使用标准库能开发吗? 本地之前用的keil的工程,想变成vscode来开发

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则