龙芯+FreeRTOS+LVGL实战笔记(新)——04开启主任务

news/2024/9/19 22:46:24/ 标签: 笔记

        本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了改进和优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以前往本人在B站的视频合集(图2所示)观看所有演示视频,合集首个视频链接为:

图1 《龙芯+RT-Thread+LVGL实战笔记》专栏所有文章
图2 笔者在B站上的龙芯视频合集

        此外,关于专栏的收费,无非就是笔者想增加一些创作的动力。由于上个专栏受到了厂家关注并请求本人下架,但是已收费的资源不可下架,所以只能无奈的上调了价格(涨价了就无法降价)。而本专栏笔者不再顾忌,将维持该定价,希望朋友们理解和支持。  


        上一篇我们完成了最基本的移植工作,接下来就可以此基础上规划任务了,首当其冲的就是一个优先级最高的主任务,这个主任务能够保证整个系统最基本的运作。

一、工程文件和任务框架

        开撸代码之前,这里先根据样题的编排(图3所示),把工程文件和任务的整体脉络梳理在图4中。当然,这只是本人的规划思路,并不一定是最合理的,供各位借鉴和参考。后续的版本和代码都将依据图4的规划来推进。

图3 部分样题展示
图4 工程文件和任务的框架

二、准备工程和文件

        如图5所示,我们把上一次的整个工程复制另存一份,作为1.0的版本,并在 src 目录下新建两个文件:task_top.ctask_top.h。当然,别忘了把 .c 文件加入到工程中(.h文件可加可不加),如图6所示。

图5 准备新工程和新文件
图6 把 .c 文件加入到工程

三、编写源码

3.1 程序运行流程

        阅读源码之前,先说明一下程序运行的基本流程,请大家对照着图7来看:

  1. 首先,是一些列的初始化,包括 BSP 驱动、新增的硬件初始化以及 LVGL 初始化。
  2. 接着,就可以按照 FreeRTOS 常用的启动流程,来创建一个启动任务 start_task,即图中黄色背景部分,紧跟着就开始任务调度,随后的所有工作就可以交给 FreeRTOS 了。
  3. 然后,start_task 的使命是创建最核心的主任务 top_task,即图中蓝色背景部分,创建成功便全身而退。
  4. 最后,在 top_task 任务里,运行 LVGL 的任务处理器,保证最基本的系统响应。

        基于上述流程,下面的源码将按照 main.c、task_top.h 和 task_top.c 这三个文件的顺序来解读。

图7 程序运行流程图

3.2 main.c 文件源码

        该文件的源码如代码清单1所示,直接看 main() 函数,一上来就执行几个必要的初始化:

  1. BSP 的初始化 ls1x_drv_init(),该函数会将工程下 ls1x-drv 目录下涉及到的板载硬件进行初始化。
  2. 第三方库的初始化 install_3th_libraries(),LVGL 的初始化就在该函数中。
  3. 我们自己编写的硬件初始化 Hardware_Init(),只不过这个函数暂时为空,后面会根据需要陆续往里添加。
  4. 接下来,执行 freertos_start() 函数,该函数的定义在 task_top.c 文件中,源码见下面的3.4小节。
/***************************************************************************** 代码清单1:main.c** 项目名称:龙芯1B200 + FreeRTOS + LVGL7** 项目描述:嵌入式系统应用开发赛项第一模块样题任务** 项目日期:2024/08/17** 作    者:老耿** 版本说明:1.移植了FreeRTOS系统和LVGL7.0.1组件*           2.添加了优先级最高的主任务top_task,并部署了一个开关来测试LVGL***************************************************************************///---------------------------------------------------------------------------
// 必要的库头文件、BSP头文件、src头文件
//---------------------------------------------------------------------------
#include "mips.h"
#include <time.h>
#include "bsp.h"
#include "task_top.h"#if defined(BSP_USE_FB)#include "ls1x_fb.h"#ifdef XPT2046_DRVchar LCD_display_mode[] = LCD_800x480;#elif defined(GT1151_DRV)char LCD_display_mode[] = LCD_800x480;#else#error "在bsp.h中选择配置 XPT2046_DRV 或者 GT1151_DRV""XPT2046_DRV:  用于800*480 横屏的触摸屏.""GT1151_DRV:   用于480*800 竖屏的触摸屏.""如果都不选择, 注释掉本 error 信息, 然后自定义: LCD_display_mode[]"#endif
#endif/*---------------------------------------------------------------------------* 函数名称:Hardware_Init* 功    能:硬件初始化* 入口参数:无* 返 回 值:无* 说明描述:把所有硬件的初始化都集中在这个函数里*-------------------------------------------------------------------------*/
void Hardware_Init(void)
{//暂无,后续将硬件的初始化都写在本函数中
}/*--------------------------------------------------------------------------* 函数名称:main* 功    能:主函数* 入口参数:主函数入口参数格式* 返 回 值:* 说明描述:把硬件和LVGL初始化以后,剩下的就交给FreeRTOS了*-------------------------------------------------------------------------*/
int main(int argc, char** argv)
{printk("\r\nLS1B200 + FreeRTOS + LVGL7\r\n");ls1x_drv_init();            /* BSP驱动初始化 */install_3th_libraries(); 	/* 第三方库初始化,包括LVGL */Hardware_Init();            /* 硬件初始化 */freertos_start();           /* 启动任务,开启调度 */return 0;
}

3.3 task_top.h 文件源码

        该头文件的源码如代码清单2所示,按照笔者的规划,任务堆栈的大小以128(单位:字)为基数,任务优先级最高不超过8。因此,这两个参数以宏的形式进行了定义。另外,就是声明了一下上面提到 freertos_start() 函数。

//---------------------------------------------------------
// 代码清单2:task_top.h
//---------------------------------------------------------#ifndef _TASK_TOP_H
#define _TASK_TOP_H//---------------------------------------------------------
// 必要的宏定义
//---------------------------------------------------------
#define  STACK_SIZE    128      //任务堆栈大小(基数)
#define  MAX_PRIO      8        //任务最高优先级(暂定为8)//---------------------------------------------------------
// 函数声明
//---------------------------------------------------------
void freertos_start(void);#endif

3.4 task_top.c 文件源码

        该文件的源码如代码清单3所示,大家可以对照上面的流程图和注释来阅读。freertos_start() 函数一旦执行,便启动了 start_task 任务,同时开启了 FreeRTOS 的任务调度,而 start_task 里又创建了优先级最高的 top_task 任务,在该任务中,部署了一个用于测试的开关组件,随后就保持着 LVGL 运行。

/************************************************************** 代码清单3:task_top.c** 文件描述:主任务和主界面** 作    者:老耿** 版    本:V1.0 @ 2024/08/17***********************************************************///-----------------------------------------------------------
// 必要的库头文件、LVGL头文件、BSP头文件、src头文件
//-----------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"#include "bsp.h"#include "task_top.h"//-----------------------------------------------------------------
// 相关的任务句柄和任务函数
//-----------------------------------------------------------------
static TaskHandle_t StartTask_Handler;          //启动任务句柄
static void start_task(void *pvParameters);     //启动任务函数static TaskHandle_t TopTask_Handler;            //主任务句柄
static void top_task(void *pvParameters);       //主任务函数/*----------------------------------------------------------------* 函数名称:start_task* 功    能:启动任务* 入口参数:*pvParameters --- 传入参数(未用到)* 返 回 值:无* 说明描述:创建主任务即可*---------------------------------------------------------------*/
static void start_task(void *pvParameters)
{taskENTER_CRITICAL();				//进入临界区//创建主界面任务xTaskCreate((TaskFunction_t )top_task,			//任务函数(const char*    )"top_task",		//任务名称(uint16_t       )STACK_SIZE,	    //任务堆栈大小(void*          )NULL,				//传给任务函数的参数(UBaseType_t    )MAX_PRIO,		    //任务优先级(最高)(TaskHandle_t*  )&TopTask_Handler);	//任务句柄vTaskDelete(StartTask_Handler);		//删除开始任务taskEXIT_CRITICAL();				//退出临界区
}/*------------------------------------------------------------------* 函数名称:top_task* 功    能:生成主界面的任务* 入口参数:*pvParameters --- 传入参数(未用到)* 返 回 值:无* 说明描述:要处理LVGL任务,需要定期在OS任务中调用lv_task_handler()*-----------------------------------------------------------------*/
static void top_task(void *pvParameters)
{//在屏幕中央部署一个开关,测试LVGL的运行lv_obj_t *sw = lv_switch_create(lv_scr_act(), NULL);lv_obj_set_width(sw, 80);lv_obj_set_height(sw, 50);lv_obj_align(sw, NULL, LV_ALIGN_CENTER, 0, 0);while(1){lv_task_handler();      //在主线程中定期调用LVGL任务处理器vTaskDelay(5);          //计时并不严格,大约5ms以保持系统响应}
}/*----------------------------------------------------------------* 函数名称:freertos_start* 功    能:FreeRTOS入口函数* 入口参数:无* 返 回 值:无* 说明描述:在该函数里创建启动任务,并开启任务调度*---------------------------------------------------------------*/
void freertos_start(void)
{xTaskCreate((TaskFunction_t )start_task,			//任务函数(const char*    )"start_task",          //任务名称(uint16_t       )STACK_SIZE,		    //任务堆栈大小(void*          )NULL,                  //传入给任务函数的参数(UBaseType_t    )MAX_PRIO-7,            //任务优先级(最低)(TaskHandle_t*  )&StartTask_Handler);   //任务句柄vTaskStartScheduler();      //开启任务调度
}

四、程序运行与测试

        编译没错的话就可以运行或下载本程序了,具体效果见下面的演示视频。至此,FreeRTOS 和 LVGL 都能够正常运行了,后续我们将结合更丰满的图形化组件,去创建下面的子任务,实现样题的一个个要求。

新版的《龙芯+FreeRTOS+LVGL实战》系列启动了,从搞定移植开始

(本文完)


http://www.ppmy.cn/news/1520984.html

相关文章

BUUCTF—[BJDCTF2020]The mystery of ip

题解 打开环境点击上面的flag可以看到这个IP页面。 抓个包看看有啥东西无&#xff0c;可以看到在返回包有IP。 看到IP就想到X-Forwarded-For这个玩意&#xff0c;我们用X-Forwarded-For随便添加个IP看看。可以看到返回的IP内容变成了123。 X-Forwarded-For:123 推测它会输出我…

[数据集][目标检测]汽油检泄漏检测数据集VOC+YOLO格式237张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;237 标注数量(xml文件个数)&#xff1a;237 标注数量(txt文件个数)&#xff1a;237 标注类别…

12. GIS地图制图工程师岗位职责、技术要求和常见面试题

本系列文章目录&#xff1a; 1. GIS开发工程师岗位职责、技术要求和常见面试题 2. GIS数据工程师岗位职责、技术要求和常见面试题 3. GIS后端工程师岗位职责、技术要求和常见面试题 4. GIS前端工程师岗位职责、技术要求和常见面试题 5. GIS工程师岗位职责、技术要求和常见面试…

25版王道数据结构课后习题详细分析 第七章 7.4 B树和B+树

一、单项选择题 ———————————————————— ———————————————————— 解析&#xff1a;关键字数目比子树数目少1&#xff0c;首先可排除B树。对于4阶B树&#xff0c;根结点至少有⒉棵子树(关键字数至少为1)&#xff0c;其他非叶结点至少有n/…

Codeforces Round 920 (Div. 3)(A,B,C,D)

A 在二维坐标轴上有一个正方形&#xff0c;给你一个正方形的四个顶点坐标&#xff0c;求面积 知道一个边长&#xff0c;平方即可 for(int i0;i<4;i)x[i]x1; Arrays.sort(x); //1122 kMath.abs(x[2]-x[1]); System.out.println(k*k); B 操作1、2是添加和修改&#xff0c;操…

jupyter 笔记本中如何判定bash块是否执行完毕

jupyter notebook中 后台执行bash卡住解决 jupyter版本 !jupyter --version Selected Jupyter core packages... IPython : 8.27.0 ipykernel : 6.29.5 ipywidgets : 8.1.5 jupyter_client : 8.6.2 jupyter_core : 5.7.2 jupyter_server : 2.…

MySQL数据恢复的故障转移:策略、实践与自动化

在企业级数据库管理中&#xff0c;数据的高可用性和灾难恢复能力是至关重要的。MySQL作为流行的数据库管理系统&#xff0c;提供了多种机制来实现数据恢复的故障转移&#xff0c;确保在主数据库发生故障时&#xff0c;能够无缝切换到备份数据库&#xff0c;从而保障业务的连续性…

【c++】常量周边之const应用:常变量

【c】常量周边&#xff1a;常量概念及定义 承接上文&#xff0c;我们学习了常量的基础知识&#xff0c;在此基础上&#xff0c;本篇文章对于宏定义 #define 和常量 const进行深入学习。 目录 #define 预处理器 const:在常量方面应用 使用技巧 const与指针的结合 const 与 …

初学者指南:Spring Boot入门

引言 在当今快速发展的软件开发领域&#xff0c;Spring Boot已经成为了构建现代Java应用程序的首选框架之一。它以其简洁、易用和强大的特性&#xff0c;帮助开发者快速搭建起基于Spring的应用程序。如果你是Java开发新手&#xff0c;或者正在寻找一种更高效的开发方式&#x…

浅谈C#之ConcurrentDictionary

一、基本介绍 ConcurrentDictionary 是 .NET Framework 中提供的一个线程安全的字典类&#xff0c;它允许多个线程同时对字典进行读写操作而不需要额外的同步措施。这个类位于 System.Collections.Concurrent 命名空间中。 二、关键特性 线程安全&#xff1a;它内部使用了细粒度…

自然语言处理-词向量转换

文章目录 一、简介1.含义2.基本原理3.常见转换方法1&#xff09;. 独热编码&#xff08;One-Hot Encoding&#xff09;2&#xff09;. 词袋模型&#xff08;Bag of Words, BoW&#xff09;3&#xff09;. TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xf…

ReentrantLock 对比 ReentrantReadWriteLock

结论 ReentrantLock 保证统一时刻,锁内只能有一个线程 ReentrantReadWriteLock 写锁时 锁内只能有一个线程 ReentrantReadWriteLock 读锁时 锁内只能有一个线程 在多线程情况下 1. 如果业务上读的场景很多,ReentrantReadWriteLock 效率高于 ReentrantLock 2. 如果业务上读的写…

Taro 微信小程序 分页上拉加载

需求&#xff1a; 页面表头及上面部分都固定&#xff0c;表格数据部分可以滚动&#xff0c;支持分页&#xff0c;上拉加载下一页数据 如果是最后一页需判断一下&#xff0c;上拉不再继续加载数据 效果&#xff1a; template&#xff1a; <scroll-view class"db-det…

动态化-鸿蒙跨端方案介绍

一、背景 &#x1f449; 华为在2023.9.25官方发布会上宣布&#xff0c;新的鸿蒙系统将不再兼容安卓应用&#xff0c;这意味着&#xff0c;包括京东金融APP在内的所有安卓应用&#xff0c;在新的鸿蒙系统上将无法运行&#xff0c;需要重新开发专门适用于新鸿蒙系统的专版APP。 …

C++和Python混合编程——C++调用Python入门

大纲 代码结构初始化 Python 解释器获取 GIL为什么需要 GIL&#xff1f;GIL 的影响 导入 Python 模块并执行代码释放 GIL终止 Python 解释器 完整代码编译执行结果项目地址 在《C和Python混合编程——Python调用C入门》一文中&#xff0c;我们熟悉了Python调用C编译的动态库的方…

Android11 MTK 安装apk时进行密码验证

1、客户需求 客户要求&#xff0c;在安装apk文件时&#xff0c;进行密码验证。apk文件来源包括浏览器下载、内存中、外接SDK中、adb命令安装等。之后在测试过程&#xff0c;又添加了一个限制&#xff0c;输入错误密码超过3次&#xff0c;则放弃本次安装。2、解决 路径&#xff…

Prometheus与Grafana入门:从安装到基础监控的完整指南

Prometheus与Grafana入门&#xff1a;从安装到基础监控的完整指南 Prometheus 和 Grafana 是现代监控系统的黄金组合。Prometheus 作为一个开源的监控系统和时间序列数据库&#xff0c;以其强大的指标收集和查询能力广泛应用于云原生环境。而 Grafana 则是一个用于数据可视化和…

SQL Server 中 事务( Transaction )

在 SQL Server 中&#xff0c;Transaction&#xff08;事务&#xff09;是一种处理单位&#xff0c;它由一系列操作组成&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败。事务是数据库管理系统中的一个核心概念&#xff0c;用于确保数据的完整性和一致性。 事务具有…

Linux 进程等待与替换

✏️ 代码引入&#xff1a; #include <stdio.h> #include <unistd.h> // _exit()要此头文件&#xff0c;使用方法与 exit()类似 #include <stdlib.h> // exit(),要此头文件// int fun() //{ // printf("call fun function done!\n"); // retu…

使用 Monai Bundle 和 Model Zoo 对医学影像数据进行分类-全脑133个结构分割

使用 Monai Bundle 和 Model Zoo 对医学影像数据进行分类-全脑133个结构分割 文章目录 导读Monai Bundle 和 Model Zoo简单介绍基于monai bundle的MRI全脑分割模型简介模型描述模型训练细节训练数据注意事项电脑配置完整的133个脑结构列表在3D slicer使用全脑结构分割模型完整的…