目录
说在前面
Clion结合CubeMX以Makefile编译和构建STM32
新建目录和文件
串口打印问题解决,重定向fptuc失效.
说在前面
有稚晖君的一文,结果可能就让你对嵌入式开发更加易于上手。这是工具上的革新带给你的,这也是一个好的IDE带给开发人员不一样的优雅体验。
配置CLion用于STM32开发【优雅の嵌入式开发】 - 知乎 (zhihu.com)
先说说Keil,keil有强大的编译器,但其编辑器万年不变,对于开发人员的代码编写不能起到一个及时反馈的作用。比如说,一个报错在修改后,还得等过几十秒,Keil的编辑器才消除警告。但是,Keil集成编译和调试(软硬件仿真)。是一个真正意义上的开发工具。
以前我用过VSCODE+KeilAssistant 来开发STM32,相当于用vscode做编辑器,编译,下载和调试仿真都还是离不开Keil。
奈何CUBEMX更新了,这使得cubemx不能生成SW4STM32,除非一直用老的版本.
直入主题
Clion结合CubeMX以Makefile编译和构建STM32
具体步骤参考.(带图步骤参考)
http://t.csdn.cn/CZW6o
注意点:
查看openocd是否添加到系统的环境变量
openocd -v
查看mingw 是否安装
gcc -v
查看Clion下的配置成功
debugger 选择GDB
上图的stm32G431.cfg的内容(STM32G431是控制器的芯片类型)
定义烧录器的类型,比如DAPLINK ,FlashSize根据芯片来选择。
# choose st-link/j-link/dap-link etc.
source [find interface/cmsis-dap.cfg]
transport select swd
# 0x10000 = 64K Flash Size
# 0x80000 = 512K Flash Size
set FLASH_SIZE 0x20000
source [find target/stm32g4x.cfg]
# download speed = 10MHz
adapter speed 10000
#reset_config none
新建目录和文件
每新建源文件需要添加到makefile文件中,新加的头文件目录也给出。
makefile添加新增得源文件
makefile中添加头文件目录
串口打印问题解决,重定向fptuc失效.
这里用稚晖君的方法:
retarget.c
//
// Created by PHILICS on 2023/5/20.
//
//
// Created by PHILICS on 2023/4/18.
//
#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;
}
#endif //#if !defined(OS_USE_SEMIHOSTING)
retarget.h
#ifndef _RETARGET_H__
#define _RETARGET_H__
#include "stm32g4xx_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__
在设备初始中调用
RetargetInit(&huart1);