STM32+RTThread Nano+LVGL避坑指南

问题1:

        RTThread+LVGL移植后出现lv_timer_Handler()运行卡住的现象,在网上查了很多教程,大多是让你增大LVGL的RAM或者是改启动文件的堆栈大小。这些我都尝试了,没有用!偶然间,我将lv_timer_Handler()和lv_tick_inc()都放到了RTTread的系统滴答时钟回调函数SysTick_Handler()里,震惊!!它跑起来了,但此时我明白这并没有真正解决问题...

问题2:

        本人使用STM32F407VGT6平台运行LVGL,在使用KEIL编写程序的时候,发现RAM不太够用,可是我才写了5个界面,丫的!为难...想着不妨换个STM32H743VIT6,查了一下手册,淦!!引脚不对应,无法Pin To Pin替换,那只能优化了,优化过程中发现KEIL编译RAM大小才用了126KB

76736b2d562f4406aa1cdb664fe35c07.png

        这不对啊,我记得407有192KB的啊,我特意查了一下手册,407单片机有三块系统RAM,分别为SRAM1、SRAM2和CCMRAM

929fa632bd17459f84058d8e1afaf7df.png        是的我没记错,不过这CCMRAM是什么嘞,没听说过啊,又翻了翻手册

12cf229fbcef4988b332c68ac846673c.png

        说白了就是一块只能由CPU访问的RAM,外设无法访问,那不如干点坏事,RTThread貌似不需要跟外设聊天,都是CPU在执行任务,那就让它去当那个大冤种吧,把整个RTThread用到的RAM都放到CCMRAM里,这个SRAM就可以只供给LVGL了,那可是128KB啊,整整128KB啊,理论可行开始实践。SRAM1和SRAM2在地址上是连续的,从0x20000000到0x20020000,CCMRAM的地址为0x10000000到0x10010000,在keil中配置一下

62ab094ae7e14b089b3b62eda40ea629.png

同时需要修改存放的定义,目前默认的为(+RW +ZI),我们给它改成(ccmram),记得保存

a8e13b8075a44d0b9c1d2d89e7e656c8.png

aa21b650ff9946e9ab2c28948b7475d8.png

保存过后我们就已经定义好了这片内存,我所使用的是RTThread Nano版本,也就是内核,在board.c文件里有定义堆栈大小,在那里做些修改,就是在申请RAM的时候前面加上__attribute__ ((section("ccmram"))),就相当于这片内存里存放了该数组。

f24d1c428d954ac0834cda4d86d619df.png

至此,内存小的问题得到了明显改善,我的LVGL也开启了双缓冲区,同时还分给了它64KB的RAM,用不完,根本用不完

c99b8c9f191e4720931c222557343e8d.png问题3:

        这个屏幕为320*240的,驱动芯片为ST7789V,驱动是厂家提供的,我做了一点修改,成功的跑起来了,但是最初的时候跑来卡的跟PPT一样,还没PPT流畅,根本不能用,仔细研究了一下驱动,发现厂家提供的这个驱动只能使用SPI发送数据,我的意思是无法使用DMA发送数据,这点我在上篇文章里解释了原因,大家自行移步查阅,这点也是坑了我好久,最中ST7789V的手册上的一句话点醒了我

973ff7a36bcc43788bf77f385096769d.png

翻译一下就是,如果你想连续发送数据,那么在下一个数据开始时,你的SCL的电平必须时上升沿,什么意思嘞,看图,D7数据开始发送前的时候SCL为低电平

dd07e1ae12b040838a1b730d65d4e404.png

但是厂家给的驱动里面是这么写的

bc13cdfbb17d4c4cb76ca79d46fc2d6b.png

这就导致了在下一个数据发送时,SCL处于高电平,无法达到ST7789V的连续发送时序要求,建议改成如下

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_1LINE;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;

后面就可以改写驱动,DMA也可以使用了。

问题4:

        现在可以开启DMA了,众所周知LVGL需要实现屏幕刷新函数,在刷新函数里有一个颜色数据lv_color_t *color_p,这是一个lv_color_t的共用体,什么意思呢?熟悉C语言的同学应该都知道,共用体的内存只按照最大的那个进行分配,多嘴了,自行百度;我之前不知道,一直都是将color_p->full进行分割成两个8位的数据,现在知道了,直接把指针发过去,让DMA直接搬,卧槽,又节约了20KB的显存RAM,用不完,根本用不完,最后在使用DMA搬颜色数据的时候记得将

LV_COLOR_16_SWAP置1,不然显示出来的颜色是错误的

1ca676c795e54f5a902d9c2522470138.png

 最后:

        感谢你读到了最后,这里才是问题1的答案

RTThread+LVGL移植后,lv_timer_Handler()会占用RTThread的堆栈,而RTThread堆栈是程序员设定的,不是它自己设定的可变大小,默认的大小为15KB根本无法让你的lv_timer_Handler()跑起来,所以,调大RTTread的堆栈大小,然后创建一个线程,里面运行LVGL初始化和lv_timer_Handler();线程堆栈给到16KB左右就很舒服,关于lv_tick_inc()放到RTThread的系统滴答时钟回调里即可

b364a117030745a0b05d5279938e386d.png

be7ab8616b35497dbc055794966d3254.png

记得点赞+关注。。。emmmmm蟹蟹

 

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值