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

        本专栏是笔者另一个专栏《龙芯+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_DRV
    char 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实战》系列启动了,从搞定移植开始

(本文完)

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南耿先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值