0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

不服跑个分!5块钱的国产单片机—Air32移植LVGL+FreeRTOS

合宙LuatOS 2022-08-28 15:52 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1ee754d6-2560-11ed-9ade-dac502259ad0.png

合宙Air32F103系列MCU自六月初量产上市以来,以优异性能和极致低价受到广大用户好评。特别是Air32F103CCT6芯片,64K RAM+256K Flash,可满足许多复杂应用需求。

最近LuatOS社区大神@Principle,在Air32F103CCT6上移植LVGL+FreeRTOS并进行了跑分测试,我们一起来看看吧~

1f03e218-2560-11ed-9ade-dac502259ad0.gif

-合宙Air32跑分实测 -

文末【阅读原文】链接,获取最新资料

1

合宙Air32芯片选型


合宙Air32系列芯片有不同容量型号可选,我选择了QFP48封装所能提供最大存储容量的Air32F103CCT6。

合宙LuatOS淘宝直营店

luat.taobao.com

1f0f797a-2560-11ed-9ade-dac502259ad0.png

Air32F103CCT6芯片相对于STM32F103大容量型号,主要有以下几个升级点:

●216MHz的Cortex-M3内核

可以稳定超频运行在256MHz,且运行在216MHz下时,全部Flash区域仅需1个等待周期。

●新增了一些外设
包括ADC3/TRNG/TIM9-TIM14等;

●对现有外设进行了增强

例如内置USB上拉电阻、GPIO可以独立上下拉等。

2

移植FreeRTOS与LVGL


由于合宙Air32系列能够兼容STM32,因此本代码基于STM32F1的标准库,并增加了Air32的专有代码。

Air32F103最新LVGL+FreeRTOS示例工程:
https://yuanze.wang/posts/air32-lvgl-freertos/

本工程针对Air32F103CCT6芯片,使用硬件SPI+DMA的方式驱动GC9306X控制器的320x240LCD屏幕,并支持双缓冲模式,几乎榨干了Air32所有的性能。同时,使用RTOS保证了DMA传输过程中CPU能够进入休眠,降低系统功耗。

特别注意:

请使用较新版本的Keil,旧版Keil可能会出现编译的程序运行错误问题。

本工程经实测可使用Keil5.36正常编译。

1f03e218-2560-11ed-9ade-dac502259ad0.gif

2.1 工程组件


本文所使用的工程组件均来自原汁原味的官方最新版,除了配置文件之外绝无任何魔改。

● FreeRTOS:

来自FreeRTOS官网中最新的LTS 202012.04版本。
https://www.freertos.org/a00104.html

● LVGL:来自官网LVGL官方GitHub仓库中最新的LVGL 8.3.1版本。
https://github.com/lvgl/lvgl/releases

2.2 注意事项


● 中断优先级:

Air32的NVIC中断优先级只有3位,而不是STM32的4位。若想使用STM32的标准库,则需要在FreeRTOSConfig.h头文件中修改__NVIC_PRIO_BITS默认的值。

C

#ifndef __FREERTOS_CONFIG_H

#define __FREERTOS_CONFIG_H

#include "stm32f10x.h"

#undef __NVIC_PRIO_BITS

#define __NVIC_PRIO_BITS 3

● Air32专用PLL库:

需要来自合宙的闭源PLL库。为此,我将STM32原版的system_stm32f10x.c排除编译,然后实现了自己的SystemInit()函数。该函数可以从合宙官方的SDK中获取。

▼上下滚动,查看全部▼

C

voidSystemInit(void)

{

RCC_DeInit(); //复位RCC寄存器

RCC_HSEConfig(RCC_HSE_ON); //使能HSE

while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待HSE就绪

RCC_PLLCmd(DISABLE);//关闭PLL

AIR_RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_32, 1); //配置PLL, 8*32=256MHz

RCC_PLLCmd(ENABLE); //使能PLL

while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL就绪

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选择PLL作为系统时钟

RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB时钟

RCC_PCLK1Config(RCC_HCLK_Div2);//配置APB1时钟

RCC_PCLK2Config(RCC_HCLK_Div1);//配置APB2时钟

RCC_LSICmd(ENABLE); //使能内部低速时钟

while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); //等待LSI就绪

RCC_HSICmd(ENABLE); //使能内部高速时钟

while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); //等待HSI就绪

}

然后,将air.lib加入工程中,并自己定义AIR_RCC_PLLConfig()函数的原型与SystemCoreClock的值。

合宙Air32支持比STM32标准库更高的RCC_PLLMul_xx值,因此还需要将air32f10x.h中新增的PLL值复制到自己的代码中,这样可以在使用熟悉的STM32标准库的同时,使用到Air32的增强功能。

▼上下滚动,查看全部▼

C

#define RCC_PLLMul_17 ((uint32_t)0x10000000)

#define RCC_PLLMul_18 ((uint32_t)0x10040000)

#define RCC_PLLMul_19 ((uint32_t)0x10080000)

#define RCC_PLLMul_20 ((uint32_t)0x100C0000)

#define RCC_PLLMul_21 ((uint32_t)0x10100000)

#define RCC_PLLMul_22 ((uint32_t)0x10140000)

#define RCC_PLLMul_23 ((uint32_t)0x10180000)

#define RCC_PLLMul_24 ((uint32_t)0x101C0000)

#define RCC_PLLMul_25 ((uint32_t)0x10200000)

#define RCC_PLLMul_26 ((uint32_t)0x10240000)

#define RCC_PLLMul_27 ((uint32_t)0x10280000)

#define RCC_PLLMul_28 ((uint32_t)0x102C0000)

#define RCC_PLLMul_29 ((uint32_t)0x10300000)

#define RCC_PLLMul_30 ((uint32_t)0x10340000)

#define RCC_PLLMul_31 ((uint32_t)0x10380000)

#define RCC_PLLMul_32 ((uint32_t)0x103C0000)

uint32_t SystemCoreClock = 256000000;

uint32_t AIR_RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul, uint8_t Latency);

注意:
如需使用Air32相比STM32新增的外设中断,请自行更换STM32的启动文件到Air32的启动文件。

● Keil编译器设置:

LVGL需要最低支持C99的编译器才能正确编译,因此需要开启Keil AC5的C99模式。同时,为了减少生成固件的体积,建议选择最高级别的-O3优化。

2.3 组件库的裁剪与优化


由于芯片的RAM空间有限,因此需要对芯片的RAM空间进行一定的规划与优化。程序中占用RAM较大的部分与相应的规划如下:

● 系统栈:

由于使用了FreeRTOS,各个Task有其自己的任务栈,因此系统栈只有ISR与main函数使用。

因此,在startup_stm32f10x_hd.s中将Stack_Size改为0x00000100,即256字节。

● 任务栈:

目前的代码中只有三个Task,分别是LVGL Task LED Task与IDLE Task。

其中,LED Task与IDLE Task都非常简单,为它们设置128字节的任务栈;LVGL Task较为复杂,根据官方推荐的2-8K范围,设置为4K。

● LVGL堆:

LVGL的所有句柄都是动态内存,因此其自己维护了一个堆空间。堆空间的大小可以在lv_conf.h中的LV_MEM_SIZE中修改,您可以根据自己使用的UI复杂度对其进行修改。对于benchmark demo,12K即可满足要求。

● LVGL缓冲区:

LVGL需要将画面渲染到缓冲区中,之后再刷新到屏幕上。本工程支持单缓冲与双缓冲模式(可以在Keil的Target中选择),单缓冲模式使用1个240x40像素的缓冲区,双缓冲模式则使用2个240x40像素的缓冲区。使用双缓冲模式可以在DMA控制器向屏幕写入一个缓冲区的数据时,CPU继续渲染到另一个缓冲区中,提升渲染效率,但会占用双倍的缓冲区。

同时,由于芯片的ROM空间也有限,因此我裁剪了一些LVGL与FreeRTOS的功能。您可以在lv_conf.h与FreeRTOSConfig.h中自行开关它们。benchmarkdemo中包含了大量的字体与图像,因此导致最终编译生成的bin文件较大。只使用FreeRTOS与LVGL内核时,ROM占用约120K。使用常用的控件后,还能剩余约100K空间给用户开发自己的应用。

3

运行效果及总结


接下来通过单缓冲模式及双缓冲模式实测数据,看看整体运行效果如何:

3.1 单缓冲模式


单缓冲模式的存储空间占用情况如下:

C

Total RO Size (Code + RO Data) 230904 ( 225.49kB)

Total RW Size (RW Data + ZI Data) 40768 ( 39.81kB)

Total ROM Size (Code + RO Data + RW Data) 231472 ( 226.05kB)

单缓冲模式跑分结果:

1f2e5322-2560-11ed-9ade-dac502259ad0.jpg

3.2双缓冲模式


双缓冲模式的存储空间占用情况如下:

C

Total RO Size (Code + RO Data) 230904 ( 225.49kB)

Total RW Size (RW Data + ZI Data) 40768 ( 39.81kB)

Total ROM Size (Code + RO Data + RW Data) 231472 ( 226.05kB)

双缓冲模式跑分结果:

1f3fa1c2-2560-11ed-9ade-dac502259ad0.jpg

可以看出,单缓冲模式相比双缓冲模式节约了大量的RAM,帧数却只下降了25%,因此单缓冲模式更具有实用意义。这主要是因为,在复杂UI界面下,瓶颈主要在CPU的运算速度上,而不是向屏幕写入缓冲区的IO操作上。

● 实测总结:

5元钱的Air32F103CCT6确实具有了流畅运行LVGL的能力,并且还有100K左右的ROM和超过20K的RAM空间可用,这使得在Air32F103上使用LVGL+FreeRTOS的同时开发复杂的用户程序成为了可能,我们又多了一个高性价比的国产MCU选择。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6074

    文章

    45344

    浏览量

    663802
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    怎么学好单片机

    的一些接口可用,也就是说,需要架一简单的前后台系统,只会写应用软件,就比较难使用单片机,因为他们对这些只有硬件,没有软件接口的东西,无从下手。 所以,学单片机,首先学会硬件,也就是简单的电阻电容电感
    发表于 12-04 07:16

    单片机:一承载科技与工程思维的核心平台

    ,还是工业自动化、嵌入式系统,单片机都扮演着不可或缺的角色。它不仅仅是一芯片,而是承载着技术与工程思维的核心平台,其重要性不言而喻。 一、单片机的核心要素 单片机的核心要素主要包括以
    的头像 发表于 09-29 01:07 378次阅读

    【RA-Eco-RA6M4开发板评测】移植LVGL

    开发板评测】驱动ST7796LCD屏 - 瑞萨单片机论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛! 【lvgl安装包】*附件:LVGL.lvgl.8.3.10.pack.zip 下载后直接安装即可
    发表于 08-05 12:38

    怎么测单片机系统频率

    单片机系统频率是指单片机工作时的时钟频率,它直接影响单片机的运行速度和处理能力,准确测量系统频率对单片机应用开发、程序调试和性能优化具有重要意义。测量
    的头像 发表于 07-25 11:39 487次阅读

    单片机怎么驱动电机?

    在各类自动化设备和智能装置中,电机是重要的执行部件,而单片机作为控制核心,需要通过特定的方式驱动电机运转。单片机驱动电机并非直接连接即可,而是要根据电机类型和功率,搭配合适的驱动电路,才能实现稳定
    的头像 发表于 07-25 09:31 447次阅读

    机智云配网教程第三期:单片机代码移植实战

    前言本篇文章将分享单片机移植的经验。可以下载并按步骤移植,也可以直接使用已移植好的工程文件。文中将介绍我在移植过程中遇到的问题,并提供解决方
    的头像 发表于 07-01 17:32 1005次阅读
    机智云配网教程第三期:<b class='flag-5'>单片机</b>代码<b class='flag-5'>移植</b>实战

    使用恩智浦FRDM-MCXN947开发板移植LVGLbenchmark

    在弹出的组件选择框中查找或者输入lvgl并勾选,导入LVGL组件,如下图所示。
    的头像 发表于 06-20 10:34 1672次阅读
    使用恩智浦FRDM-MCXN947开发板<b class='flag-5'>移植</b><b class='flag-5'>LVGL</b><b class='flag-5'>跑</b>benchmark

    10钟上手睿擎平台GUI开发:第一LVGL图形应用

    ,在睿擎平台上支持LVGL能够更好地发挥其优势,为开发者带来更多便利。一环境搭建:5钟极速配置1.睿擎派硬件准备开发板:睿擎派(RK3506J,三核Cortex
    的头像 发表于 06-06 18:41 2268次阅读
    10<b class='flag-5'>分</b>钟上手睿擎平台GUI开发:第一<b class='flag-5'>个</b><b class='flag-5'>LVGL</b>图形应用

    51单片机笔记(建议收藏!)

    了解一下。 5、掌握一电路设计软件,对于单片机,其实会Protell99都可以了。 6、会使用万用表,最好有示波器啦,而且要掌握一些常用的测试手段。 7、在自己学习过程中,整理并形成自己的元器件库
    发表于 05-21 17:24

    国产单片机倒车影像合作

    寻找国产低成本单芯片单片机AMT630,SSD101合作方案, 寻找国产低成本单芯片单片机AMT630,SSD101合作方案, 寻找国产低成
    发表于 04-29 09:00

    移植LWIP+FREERTOS时遇到的问题怎么解决?

    各位大佬,小弟在尝试移植LWIP+FREERTOS的时候出现了如下问题,请各位大佬帮忙看看是哪里的问题,我用了FreeRTOS+LWIP做ModbusTCP时出现了链接出现通信12次然后通信
    发表于 03-11 06:48

    Deepseek上单片机?RT-Thread上通大语言模型

    前言单片机也能聊天?RT-Thread上通大语言模型在RT-Thread论坛上忽然看到了单片机和大模型对话的文章,想着春节期间看到大语言模型的热度持续攀升,恰巧手头有RA8D1Vi
    的头像 发表于 02-07 18:59 2381次阅读
    Deepseek上<b class='flag-5'>单片机</b>?RT-Thread上<b class='flag-5'>跑</b>通大语言模型

    什么是单片机的ADC接口

    ,简称ADC)接口是单片机中不可或缺的一部,它负责将模拟信号转换为数字信号,使得单片机能够处理来自传感器、仪表等模拟世界的信号。本文将深入探讨单片机的ADC接口技术,包括其定义、工作
    的头像 发表于 02-03 11:27 3759次阅读

    开发第1LVGL程序与实现按键操作

    开发第1LVGL程序与实现按键操作
    的头像 发表于 01-07 13:49 4444次阅读
    开发第1<b class='flag-5'>个</b><b class='flag-5'>LVGL</b>程序与实现按键操作

    单片机Debug工具性能对比 单片机调试常用命令

    单片机(Microcontroller Unit, MCU)调试是嵌入式开发中的一重要环节,它帮助开发者发现和修复代码中的错误,优化程序性能。不同的单片机和开发环境可能使用不同的调试工具和命令
    的头像 发表于 12-19 09:56 2175次阅读