问题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
这不对啊,我记得407有192KB的啊,我特意查了一下手册,407单片机有三块系统RAM,分别为SRAM1、SRAM2和CCMRAM
是的我没记错,不过这CCMRAM是什么嘞,没听说过啊,又翻了翻手册
说白了就是一块只能由CPU访问的RAM,外设无法访问,那不如干点坏事,RTThread貌似不需要跟外设聊天,都是CPU在执行任务,那就让它去当那个大冤种吧,把整个RTThread用到的RAM都放到CCMRAM里,这个SRAM就可以只供给LVGL了,那可是128KB啊,整整128KB啊,理论可行开始实践。SRAM1和SRAM2在地址上是连续的,从0x20000000到0x20020000,CCMRAM的地址为0x10000000到0x10010000,在keil中配置一下
同时需要修改存放的定义,目前默认的为(+RW +ZI),我们给它改成(ccmram),记得保存
保存过后我们就已经定义好了这片内存,我所使用的是RTThread Nano版本,也就是内核,在board.c文件里有定义堆栈大小,在那里做些修改,就是在申请RAM的时候前面加上__attribute__ ((section("ccmram"))),就相当于这片内存里存放了该数组。
至此,内存小的问题得到了明显改善,我的LVGL也开启了双缓冲区,同时还分给了它64KB的RAM,用不完,根本用不完
问题3:
这个屏幕为320*240的,驱动芯片为ST7789V,驱动是厂家提供的,我做了一点修改,成功的跑起来了,但是最初的时候跑来卡的跟PPT一样,还没PPT流畅,根本不能用,仔细研究了一下驱动,发现厂家提供的这个驱动只能使用SPI发送数据,我的意思是无法使用DMA发送数据,这点我在上篇文章里解释了原因,大家自行移步查阅,这点也是坑了我好久,最中ST7789V的手册上的一句话点醒了我
翻译一下就是,如果你想连续发送数据,那么在下一个数据开始时,你的SCL的电平必须时上升沿,什么意思嘞,看图,D7数据开始发送前的时候SCL为低电平
但是厂家给的驱动里面是这么写的
这就导致了在下一个数据发送时,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,不然显示出来的颜色是错误的
最后:
感谢你读到了最后,这里才是问题1的答案
RTThread+LVGL移植后,lv_timer_Handler()会占用RTThread的堆栈,而RTThread堆栈是程序员设定的,不是它自己设定的可变大小,默认的大小为15KB根本无法让你的lv_timer_Handler()跑起来,所以,调大RTTread的堆栈大小,然后创建一个线程,里面运行LVGL初始化和lv_timer_Handler();线程堆栈给到16KB左右就很舒服,关于lv_tick_inc()放到RTThread的系统滴答时钟回调里即可
记得点赞+关注。。。emmmmm蟹蟹