CLion + STM32環境配置
遇到的問題描述:
> "moniton" command not supported by this target.
> You can't do that when your target is exec
> 上傳完成,但存在問題
> monitor reset
> "monitor" command not supported by this target.
GitHub鏈接
首先感謝偶像稚暉君
稚暉君大神配置Clion的教程:https://zhuanlan.zhihu.com/p/145801160
我在進行配置的時候遇到了一些問題,以下是我的修改版本:
前面的的可以參照稚暉君大神的配置也可以不安裝MinGW,直接使用STM32CubeCLT,這里面是STM官方給我們配置好的各種編譯環境
可以不安裝MinGW,直接使用STM32CubeCLT相對容易一些
可以不安裝MinGW,直接使用STM32CubeCLT相對容易一些
可以不安裝MinGW,直接使用STM32CubeCLT相對容易一些
我的環境
CLion 2024.1
OpenOCD-20240916-0.12.0
STM32CubeCLT_1.18.0
相關資源在source文件夾內
GitHub上傳大文件有點麻煩,給一個迅雷的下載鏈接:https://pan.xunlei.com/s/VOT6D5Qu-LTGNvuMcZoCLACRA1?pwd=iykg#
復制這段內容后打開迅雷,查看更方便
如果網盤下載的慢的話也可以直接去對應官網下載軟件
OpenOCD-20240916-0.12.0版本的下載鏈接:https://www.st.com/en/development-tools/stm32cubeclt.html
STM32CubeCLT_1.18.0版本的下載鏈接:https://sysprogs.com/getfile/2285/openocd-20240916.7z
Clion2024.1版本的下載鏈接:https://download.jetbrains.com/cpp/CLion-2024.1.6.exe
STM32CubeMX 下載鏈接:https://www.st.com/en/development-tools/stm32cubemx.html
我的配置相設置如下
編譯工具鏈
Cmake
嵌入式開發設置
運行調試配置
編譯錯誤問題
- 如果移動了工程文件夾的話,最好打開.ioc文件重新Generate一下再編譯,可以解決很多錯誤。
- 遇到任何CMake相關的報錯,一般是由于緩存沒有更新引起的,可以在CLion中選
Tools-CMake-Reset Cache and Reload Project
即可解決。
printf
重定向問題
步驟一:
在Keil里面為了使用printf
函數我們需要重定向fputc
函數:
int fputc (int ch, FILE *f)
{(void)HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);return ch;
}
其中的FILE
定義在stdio.h
頭文件中,所以需要在項目中包含這個頭文件,但是經過測試發現,Keil里面包含的是MDK\ARM\ARMCC\include
這個目錄下的stdio.h
,而在Clion中是不會鏈接到這個文件的。因此如果在Clion中也按之前的方法進行重定向,會發現printf
沒有任何輸出。
在Clion中鏈接的是GNU-Tools-ARM-Embedded\arm-none-eabi\include
里面的stdio.h
,如果仍然想使用printf
函數功能,則需要進行如下操作:
新建一個retarget.h
文件內容如下:
#ifndef __RETARGET_H__
#define __RETARGET_H__#include "main.h"
#include "usart.h"
#include <sys/stat.h>
#include <stdio.h>void RetargetInit(UART_HandleTypeDef *huart);int _isatty(int fd);int _write(int fd, char *ptr, int len);int _close(int fd);int _lseek(int fd, int ptr, int dir);int _read(int fd, char *ptr, int len);int _fstat(int fd, struct stat *st);#endif //#ifndef _RETARGET_H__
再新建一個retarget.c
文件內容如下:
#include <_ansi.h>
#include <_syslist.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/times.h>
#include "retarget.h"
#include <stdint.h>#if !defined(OS_USE_SEMIHOSTING)#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2UART_HandleTypeDef *gHuart;void RetargetInit(UART_HandleTypeDef *huart)
{gHuart = huart;/* Disable I/O buffering for STDOUT stream, so that* chars are sent out as soon as they are printed. */setvbuf(stdout, NULL, _IONBF, 0);
}int _isatty(int fd)
{if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)return 1;errno = EBADF;return 0;
}int _write(int fd, char *ptr, int len)
{HAL_StatusTypeDef hstatus;if (fd == STDOUT_FILENO || fd == STDERR_FILENO){hstatus = HAL_UART_Transmit(gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);if (hstatus == HAL_OK)return len;elsereturn EIO;}errno = EBADF;return -1;
}int _close(int fd)
{if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)return 0;errno = EBADF;return -1;
}int _lseek(int fd, int ptr, int dir)
{(void) fd;(void) ptr;(void) dir;errno = EBADF;return -1;
}int _read(int fd, char *ptr, int len)
{HAL_StatusTypeDef hstatus;if (fd == STDIN_FILENO){hstatus = HAL_UART_Receive(gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);if (hstatus == HAL_OK)return 1;elsereturn EIO;}errno = EBADF;return -1;
}int _fstat(int fd, struct stat *st)
{if (fd >= STDIN_FILENO && fd <= STDERR_FILENO){st->st_mode = S_IFCHR;return 0;}errno = EBADF;return 0;
}#endif //#if !defined(OS_USE_SEMIHOSTING)
添加這兩個文件到工程,更新CMake,編譯之后會發現,有幾個系統函數重復定義了,被重復定義的函數位于Src
目錄的syscalls.c
文件中,我們把里面重復的幾個函數刪掉即可。
如圖所示:
在main函數的初始化代碼中添加對頭文件的引用并注冊重定向的串口號:
#include "retarget.h"RetargetInit(&huart1);
然后就可以愉快地使用printf
和scanf
啦:
char buf[100];printf("\r\nYour name: ");
scanf("%s", buf);
printf("\r\nHello, %s!\r\n", buf);
步驟二:
上面的修改完成之后可能會發現無法正常讀取浮點數,這里修改CMakeList.txt,加入下述編譯選項
set(COMMON_FLAGS "-specs=nosys.specs -specs=nano.specs -u _printf_float -u _scanf_float")name: ");
scanf("%s", buf);
printf("\r\nHello, %s!\r\n", buf);
步驟二:
上面的修改完成之后可能會發現無法正常讀取浮點數,這里修改CMakeList.txt,加入下述編譯選項
set(COMMON_FLAGS "-specs=nosys.specs -specs=nano.specs -u _printf_float -u _scanf_float")