基于Clion开发(stm32移植FreeRTOS+LVGL)
嵌入式单片机开发中,通常使用 Keil IAR 或 芯片厂商提供的IDE,这类IDE界面风格还停留在十几年前XP风,代码编辑实在让人难受,所以很多时候笔者都是采用VSCode编辑,然后再用这类IDE下载调试使用,另外像keil 和 IAR 几万块价格也让很多人劝退(使用盗版,未收到律师函忽略)。那么有价格便宜,界面编辑优秀,又能跨平台的IDE吗?这里推荐VSCode(免费)和本章介绍的Clion
Clion环境搭建网上已经有很多文章出了教程,这里不做过多描述,本章主要介绍借助Clion平台开发某款芯片的流程。
配置CLion用于STM32开发【优雅の嵌入式开发】 - 知乎 (zhihu.com)
前期准备(文章末尾提供源码)
软件环境:
- Windows 10
- STM32CubeMX ------ ST官方代码生成工具(辅助使用,后期熟悉可脱离该工具)
- Clion-2022.3.2
- MinGW ------ 编译器套件
- OpenOCD ------ 调试工具
- arm-none-eabi-gcc -------- 交叉编译工具链
- 调试器驱动(具体看用的哪种调试器)
硬件环境:
- STM32L475VET6(正点原子潘多拉开发板)
- ST-Link (J-link /dap 都可以)
工程移植搭建
1.工程初步生成
这里有两种方式:借助STM32CubeMX,快速生成;自行下载库从零搭建。
推荐使用CubeMX,因为会生成CMakeLists.txt文件,不用自己一个一个写,当然后期形成模板,完全可以脱离CubeMX

2.CMakeLists.txt 修改(CMake部分提前说明如何修改,后面移植就不提了)
伴随着工程文件添加,需要在CMakeLists.txt 中添加需要编译的文件信息,类似于Keil IAR工作空间中添加文件。
实际添加起来会比以往的IDE便捷很多

3.FreeRTOS移植
FreeRTOS - Free RTOS Source Code Downloads, the official FreeRTOS zip file release download
这里笔者使用的是V10.3.0版本,修改FreeRTOSConfig.h文件和SysTick_Handler函数
//根据需要确定系统堆大小
#define configTOTAL_HEAP_SIZE ((size_t)(16 * 1024))
//lvgl需要使用,这里打开
#define configUSE_TICK_HOOK 1//屏蔽 xPortSysTickHandler
//#define xPortSysTickHandler SysTick_Handler/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{extern void xPortSysTickHandler(void);if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED){xPortSysTickHandler();}
}
4.lvgl移植
LVGL - Light and Versatile Embedded Graphics Library
mirrors / lvgl / lvgl · GitCode
复制一份lv_conf_template.h 命名为 lv_conf.h,开启宏

因为使用的开发板屏幕分辨率是:240*240 若做整个屏幕16bit刷新,那需要的缓存是:115200字节,显然在RAM只有128K的单片机上使用是不现实的,针对RAM较小的单片机只能做部分缓冲,如下操作:
/******************************************************************************** Definitions******************************************************************************/
#define LCD_WIDTH 240
#define LCD_HEIGHT 240
#define LCD_FB_BYTE_PER_PIXEL 2/* The virtual buffer for DBI panel, it should be ~1/10 screen size. */
#define LCD_VIRTUAL_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT / 10)/******************************************************************************** Variables******************************************************************************/
static uint8_t s_frameBuffer[2][LCD_VIRTUAL_BUF_SIZE * LCD_FB_BYTE_PER_PIXEL];void lv_port_disp_init(void)
{static lv_disp_draw_buf_t disp_buf;lv_disp_draw_buf_init(&disp_buf, s_frameBuffer[0], NULL, LCD_VIRTUAL_BUF_SIZE); //s_frameBuffer[1]/*-------------------------* Initialize your display* -----------------------*/xSYS_ST7789_Init();/*-----------------------------------* Register the display in LittlevGL*----------------------------------*/static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/lv_disp_drv_init(&disp_drv); /*Basic initialization*//*Set the resolution of the display*/disp_drv.hor_res = LCD_WIDTH;disp_drv.ver_res = LCD_HEIGHT;/*Used to copy the buffer's content to the display*/disp_drv.flush_cb = DEMO_FlushDisplay;/*Set a display buffer*/disp_drv.draw_buf = &disp_buf;/* Partial refresh */disp_drv.full_refresh = 1;/*Finally register the driver*/lv_disp_drv_register(&disp_drv);
}static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{lv_coord_t x1 = area->x1;lv_coord_t y1 = area->y1;lv_coord_t x2 = area->x2;lv_coord_t y2 = area->y2;uint32_t size = (x2 - x1 + 1) * (y2 - y1 + 1) * 2;//LCD_Fill(x1,y1,x2,y2,color_p);LCD_Address_Set(x1,y1,x2,y2);xSYS_LCD_Fill((uint8_t*)color_p,size);lv_disp_flush_ready(disp_drv);
}
除此之外添加如下代码:
void vApplicationTickHook(void)
{if (s_lvgl_initialized){lv_tick_inc(1);}
}void xGUI_MainTask(void *pvParameters)
{lv_port_pre_init();lv_init();lv_port_disp_init(); //显示初始化s_lvgl_initialized = true;pMainWidget = lv_scr_act(); //主体 Widget 创建lv_timer_create(lv_timer_user_callback,500,NULL);while(1){ lv_task_handler(); //lvgl 任务处理函数vTaskDelay(5);}
}static void lv_timer_user_callback(lv_timer_t * timer)
{static uint32_t colorCnt;lv_obj_set_style_bg_color(pMainWidget, lv_palette_main((lv_palette_t)colorCnt),LV_PART_MAIN);colorCnt++;colorCnt = colorCnt%12;
}
5.其他注意事项
每次添加了文件,需要刷新CMake再执行编译,否则会移植报错(原因是CMake Cache需要刷新)

6.输出结果

STM32L475-Clion: clion搭建stm32工程 (gitee.com)
CSDN源码下载地址:STM32_Clion_RTOS_LVGL
相关文章:
基于Clion开发(stm32移植FreeRTOS+LVGL)
嵌入式单片机开发中,通常使用 Keil IAR 或 芯片厂商提供的IDE,这类IDE界面风格还停留在十几年前XP风,代码编辑实在让人难受,所以很多时候笔者都是采用VSCode编辑,然后再用这类IDE下载调试使用,另外像keil 和…...
Python | 蓝桥杯进阶第三卷——动态规划
欢迎交流学习~~ 专栏: 蓝桥杯Python组刷题日寄 蓝桥杯进阶系列: 🏆 Python | 蓝桥杯进阶第一卷——字符串 🔎 Python | 蓝桥杯进阶第二卷——贪心 💝 Python | 蓝桥杯进阶第三卷——动态规划 ✈️ Python | 蓝桥杯进阶…...
蓝桥杯31天真题冲刺|题解报告|第二十九天
大家好,我是snippet,今天是我们刷题的第二十九天,今天主打打比赛,牛客AcWing力扣,今天的牛客是真的有趣,下面是我今天AcWing周赛的题解 目录 一、热身计算 题目链接:4944. 热身计算 - AcWing题…...
[Rust GUI]fltk-rs的helloworld
1、安装VSCode 下载安装VSCode 安装VSCode扩展 rust-analyzer或rust-analyzer(CN) 2、安装Microsoft C 生成工具 访问微软官网下载生成工具,勾选使用 C 的桌面开发之后会自动勾选5个项目 取消勾选以下项目 用于 Windows 的 C CMake 工具 测试工具核心功能 - 生成…...
蓝桥杯真题05
重新排序 问题描述 给定一个数组 A 和一些查询 Li,Ri 求数组中第 Li 至第 Ri个元素之和。 小蓝觉得这个问题很无聊, 于是他想重新排列一下数组, 使得最终每个查询结果的和尽可能地大。小蓝想知道相比原数组, 所有查询结果的总和最多可以增加多少? 输入格式 输入第一行包含…...
PMP那些事儿,备考小白看过来
一、PMP是什么? PMP指的是项目管理专业人士资格认证。它是由美国项目管理协会(Project Management Institute(PMI)发起的,严格评估项目管理人员知识技能是否具有高品质的资格认证考试。 其目的是为了给项目管理人员提供统一的行业标准。目前࿰…...
【数据分析实战】基于python对酒店预订需求进行分析
文章目录📚引言📖数据加载以及基本观察📑缺失值观察及处理🔖缺失值观察以及可视化🔖缺失值处理📖用户数据探索📑什么时间预定酒店将会更经济实惠?📑哪个月份的酒店预订是…...
【新2023Q2模拟题JAVA】华为OD机试 - 数组的中心位置
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:数组的中心位置 题目 给你一…...
Vue的props组件详解
const props defineProps({name: String, }); String 是在 defineProps() 函数中用来声明 name prop 的类型,表示 name 必须是字符串类型。如果父组件没有传入 name 或传入的 name 不是字符串类型,那么就会产生类型验证错误。 defineProps() 函数支持…...
抽烟行为识别预警系统 yolov5
抽烟行为识别预警系统基于yolov5网络模型智能分析技术,抽烟行为识别预警算法通过监测现场人员抽烟行为自动存档进行报警提示。我们选择当下YOLO卷积神经网络YOLOv5来进行抽烟识别检测。6月9日,Ultralytics公司开源了YOLOv5,离上一次YOLOv4发布…...
【0基础学爬虫】爬虫基础之文件存储
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章,为实现从易到难全方位覆盖,特设【0基础学…...
airflow源码分析-任务调度器实现分析
Airflow源码分析-任务调度器实现分析 概述 本文介绍Airflow执行器的总体实现流程。通过函数调用的方式说明了Airflow scheduler的实现原理,对整个调度过程的源码进行了分析。 通过本文,可以基本把握住Airflow的调度器的运行原理主线。 启动调度器 可…...
一文学会数组的reduce()和reduceRight()
reduce()方法和reduceRight()方法依次处理数组的每个成员,最终累计为一个值。 它们的差别是,reduce()是从左到右处理,reduceRight()则是从右到左,其他完全一样。 [1, 2, 3, 4, 5].reduce(function (a, b) {console.log(a, b);ret…...
登录校验-Filter
上一篇介绍完了基础应用和细节,现在来完成登录校验功能基本流程: 要进入后台管理系统,必须完成登录操作,此时就需要访问登录接口Login。登录成功服务端会生成一个JWT令牌,并且返回给前端,前端会将JWT令牌存…...
C C++ Java python 分别写出不同表白girlfriend的爱心动态代码实现
C `` #include <stdio.h> #include <stdlib.h> #include <windows.h> void heart_animation() {int i, j, k; for (i = 1; i <= 6; i++) {for (j = -3; j <= 3; j++) {for (k = -4; k <= 4; k++) {if (abs(j) + abs(k) < i * 2) {printf(“I”)…...
ThreeJS-投影、投影模糊(十七)
无投影: 完整的代码: <template> <div id"three_div"></div> </template> <script> import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/Or…...
蓝桥杯赛前冲刺-枚举暴力和排序专题1(包含历年蓝桥杯真题和AC代码)
目录 连号区间数(第四届蓝桥杯省赛CB组,第四届蓝桥杯省赛JAVAB组) 递增三元组(第九届蓝桥杯省赛CB组,第九届蓝桥杯省赛JAVAB组) 特别数的和(第十届蓝桥杯省赛CB组,第十届蓝桥杯省赛JAVAB组) 错误票据&a…...
Github库中的Languages显示与修改
目录 前言 【.gitattributes】文件 修改GitHub语言 前言 上传一个项目到GitHub时,发现显示的语言并非是自己项目所示的语言,这样的情况是经常发生的,为了能到达自己所需快速检索,或者是外部访问者能很好的搜索我们的项目&#…...
RocketMQ消息高可靠详解
文章目录 消息同步策略殊途同归同步基于offset而不是消息本身刷盘策略RocketMQ broker服务端以组为单位提供服务的,拥有着一样的brokerName则认为是一个组。其中brokerId=0的就是master,大于0的则为slave。 消息同步策略 master和slave都可以提供读服务,但是只有master允许…...
【python设计模式】4、建造者模式
哲学思想: 建造者模式的哲学思想是将复杂对象的创建过程分解成多个简单的步骤,并将这些步骤分别封装在一个独立的建造者类中。然后,我们可以使用一个指挥者类来控制建造者的调用顺序,以便在每个步骤完成后正确地构建复杂对象。 …...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
二叉树-144.二叉树的前序遍历-力扣(LeetCode)
一、题目解析 对于递归方法的前序遍历十分简单,但对于一位合格的程序猿而言,需要掌握将递归转化为非递归的能力,毕竟递归调用的时候会调用大量的栈帧,存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧,而非…...
