首先Clion有多好用就不用我多说了吧,用它来进行stm32开发真的用了之后就回不去了
一、环境准备
win10
stm32cubeMX
Clion
OpenOCD
MinGW
arm-none-eabi-gcc
我的硬件是stm32f103+cmsis-dap
安装:
stm32cubeMX直接在这下载:https://www.st.com/en/development-tools/stm32cubemx.html安装就行
Clion:https://www.jetbrains.com/clion/,ps:教育邮箱注册可以免费
OpenOCD:https://gnutoolchains.com/arm-eabi/openocd/解压之后记得路径
MinGW:https://osdn.net/projects/mingw/releases/,下面的全勾,然后系统的环境变量Path里面添加bin文件架的路径完成之后进入cmd输入gcc -v有一大串显示就是成功
arm-none-eabi-gcc:https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads,下载解压系统的环境变量Path里面添加bin文件架的路径完成之后进入cmd输入arm-none-eabi-gcc -v有一大串显示就是成功
二、Clion配置
添加编译环境如下:
添加OpenOCD和stm32cubemx路径:
三、新建工程
打开Clion新建工程选择STM32CubeMX就行
点击Open with STM32CubeMX
STM32CubeMX的配置就不多讲了,Toolchain / IDE要选择SW4STM32,点击GENERATE CODE就会添加到Clion项目
OpenOCD配置文件:
点击Edit Configurations,在Board config file:可以点Assist选择推荐的配置文件,点击Copy to Project & Use后可以自己再修改
我的硬件是stm32f103,使用cmsis-dap调试器:
# st_my_F1_cmsis-dap.cfg
# CMSIS-DAP
adapter driver cmsis-dap
# 使用 swd 调试接口
transport select swd
# FLASH大小0x20000为128k
set FLASH_SIZE 0x20000
adapter speed 10000
# 目标芯片设定为 STM32F1 系列
source [find target/stm32f1x.cfg]
#reset_config reset
四、FreeRTOS移植
首先准备好FreeRTOS源码,添加Source文件到Clion项目,其中portable文件中要选择\GCC\ARM_CM3
然后再CMakelists添加对应头文件和.c文件
最后说一下printf,scanf函数的重定向的方法
新建一个retarget.h
#ifndef _RETARGET_H__
#define _RETARGET_H__
#include "stm32f1xx_hal.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 2
UART_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;
else
return 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;
else
return 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;
}
编译的时候会报错,根据错误提示把syscalls.c文件这重定义的函数删除就行了。注:这里使用了知乎大佬稚晖君提供的方法