基于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、建造者模式
哲学思想: 建造者模式的哲学思想是将复杂对象的创建过程分解成多个简单的步骤,并将这些步骤分别封装在一个独立的建造者类中。然后,我们可以使用一个指挥者类来控制建造者的调用顺序,以便在每个步骤完成后正确地构建复杂对象。 …...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...