合宙air32f103系列mcu自六月初量产上市以来,以优异性能和极致低价受到广大用户好评。特别是air32f103cct6芯片,64k ram+256k flash,可满足许多复杂应用需求。
最近luatos社区大神@principle,在air32f103cct6上移植lvgl+freertos并进行了跑分测试,我们一起来看看吧~
- 合宙air32跑分实测 -
文末【阅读原文】链接,获取最新资料。
1
合宙air32芯片选型
合宙air32系列芯片有不同容量型号可选,我选择了qfp48封装所能提供最大存储容量的air32f103cct6。
合宙luatos淘宝直营店
luat.taobao.com
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正常编译。
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
void systeminit (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)
单缓冲模式跑分结果:
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)
双缓冲模式跑分结果:
可以看出,单缓冲模式相比双缓冲模式节约了大量的ram,帧数却只下降了25%,因此单缓冲模式更具有实用意义。这主要是因为,在复杂ui界面下,瓶颈主要在cpu的运算速度上,而不是向屏幕写入缓冲区的io操作上。
● 实测总结:
5元钱的air32f103cct6确实具有了流畅运行lvgl的能力,并且还有100k左右的rom和超过20k的ram空间可用,这使得在air32f103上使用lvgl+freertos的同时开发复杂的用户程序成为了可能,我们又多了一个高性价比的国产mcu选择。
富士晶振正式入驻得捷电子和艾睿
腕表式个人剂量仪是业内首款穿戴式健康与辐射为一体的智能终端
毫米波雷达和激光雷达的对比
恒温恒湿试验箱你了解多少?
国内模拟芯片行业解析
不服跑个分!5块钱的国产单片机—Air32移植LVGL+FreeRTOS
最全面的Python字符串拼接总结说明
融地智能携手任超博士,共筑数字化MOM与智能化AI新篇章!
智能工具的广泛应用,将人类带向了数据驱动的智能时代
人工智能为什么会引发人类深刻的医疗革命
苹果的新车或将由鸿海代工,最早会在2024年底发布
基于嵌入式Qt的车载GUI平台的设计详解
NMOS管应用电路设计
选择智能交互大屏,让企业展厅更有看点!
Wi-Fi 6和6E有什么区别 到底哪个好
采用SIEMENS S7-200小型PLC在复合机张力控制系统中的应用
嵌入式Linux入门(二、Linux文件系统、文件类型及权限管理)
MANET路由协议性能对比
ttl与非门中不用的输入端如何处理?
大众EA211发动机,燃烧效能提高10%