主控为STM32F429BI,外挂32位SDRAM,请教一下:当移植了FreeRTOS和ucGUI后,在SDRAM中开辟一片存储区域作为显存,FreeRTOS的显示任务不断往SDRAM写入数据,而STM32的LTDC模块从SDRAM读出数据并传输到LCD上显示,这之间是不是有冲突呢?因为现在LCD屏幕有跳动现象,我是这么想的,显示任务不断的往SDRAM写入数据,必然触发SDRAM的写入时序,而LTDC在从SDRAM读取数据时必然触发读出时序,这两者之间如果没有互斥信号量处理的话,应该会导致时序异常。没有这方面的经验,不知道我的想法是否正确,还请过往的大侠指点迷津,从整体的概念上指点一下就行,谢谢了! |
谢谢您的回复!
问题找到了:FMC读写数据这两个函数的问题
显示格式是RGB888的,于是在SDRAM里像素是24位的,与32位的AHB接口之间存在一个转换过程,来来回回的读写造成了“AHB总线冲突”,现在改成ARGB8888格式了,alpha填充0xFF就好了,这样读写像素的速度就提高了若干倍,目前显示"hello, world"和"毫秒表"都是没有问题的,目前是这样的状况,测试过程中发现问题的话我再回来补充。
再次感谢各位这些天的耐心交流!
评分
查看全部评分
FMC 的每一个管脚都只有一定量的通信带宽。如果两个 DMA 都在访问同一块内存,这些访问就需要争抢通信带宽,发生冲突。
SDRAM 在读取的时候需要先打开页面,这个过程远远比 SDRAM 数据传输速率要慢得多,在 SDR SDRAM 上一般在 10-15 倍左右,DDR3 可以接近 20-30 倍,DDR4 直接 40 倍起跳。如果两个 DMA 所访问的内容不在同一页,那就需要不断地打开关闭页面,访问速度更慢。电脑显卡用的 GDDR SDRAM 最大的特点是支持同时打开两页,避免了这个瓶颈。
至于互斥信号量,bus matrix 是支持先来先服务排队和自动生成等待状态的,所以说一般用不到信号量,排队等数据即可。
你的这个使用场景之下,建议你考虑把程序数据放到 SDRAM 里面,使用片内 SRAM 来做 framebuffer。SRAM 本来就比 SDRAM 快,而且不会因为来回跳地址而大幅度减速。
评分
查看全部评分
STM32一般的内部SRAM只有几百KB,用来做显示缓存怕是不够哦,这款STM32F429BI只有256KB的SRAM,以800*480的8寸屏(RGB888)计算,800 * 480 * 4就超出了SRAM的范围。
评分
查看全部评分
如果处理得当,大量的显示数据可以直接从 Flash 里面 DMA 出去。这样的话依然可以支持 800x480 但 SRAM 占用就不多了。
从flash读出,然后在LCD上显示,这个是没有问题的,但是不断对flash进行写入操作是不现实的吧。
我也是这么考虑的,移植的freertos和ucgui,我是这么想的:在ucgui的最底层描点函数和ltdc的dma传输结束之间互斥操作,这两天有点其他事情,过两天我试试,到时候还请多多指教。
把窗口分块处理:整个生命周期里面不动的内容放在 Flash 里面,需要运行时填充的数据放在 RAM 里面。
我这个案子的图形数据变化比较大,数据放在内部flash的比较困难,最终方案是外挂SDRAM和nand flash,在nand flash上做文件系统,存储比如图片,图表这样的文件,根据操作显示在lcd上。内部flash只有2MB,24位的位图也存不了几张。
如果是这样的话,那必须拿外挂 SDRAM 当 VRAM,就要考虑 DMA 互锁了。两边都是顺序访问的话,只要调度得当,一般不会卡顿的。另外可以考虑用一个定时器来控制帧速率,定时器设定成 60Hz,每次定时器触发先启动 LTDC 把画面更新了,然后跑业务逻辑更新界面内容,渲染到内存,把 LTDC 的内存打开,准备下一帧。
还有一种方法:换主控,譬如全志 V3s,譬如 NXP i.MX233。这些主控用的 DRAM 要比 STM32 的快一些(前者是片内自带 64MB LPDDR2,后者是外挂 DDR)而且有都专门的 2D 图形加速单元。V3s 的主频足有 1.2GHz 而 i.MX233 也能上至少 500MHz。这两个芯片都是设计拿来跑 Linux 的,图形体系可能还好开发一点,有现成的 Qt 和 Cairo 体系可以用,甚至可以用 Chrome OS 的体系设计来偷懒(系统启动直接就是全屏的网页浏览器打开 localhost,实际界面和功能完全用 HTML5 + CSS + JS 做,至于和硬件的交互就靠 CGI)
评分
查看全部评分