硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5384|回复: 12
收起左侧

[GUI] STemWin GUI_ALLOC_AllocZero申请内存后GUI_ALLOC_h2p转为指针。f_read()时写到buf里的数据不正常。求指点

[复制链接]

4

主题

25

回帖

37

积分

新手上路

积分
37
发表于 2019-10-23 16:02:24 | 显示全部楼层 |阅读模式
移植STemWin后想要测试一下从SD卡读取图片信息然后添加到储存器再GUI_BMP_Draw()显示图片。
  1. /* 申请一块内存空间 并且将其清零 */
  2. hMem = GUI_ALLOC_AllocZero(file.fsize);
  3. /* 将申请到内存的句柄转换成指针类型 */
  4. _acBuffer = GUI_ALLOC_h2p(hMem);
复制代码
在教程里看到有这样的一个方法,可以直接用emWin的内存申请出来给用户使用。于是我就这样用了
  1. res = f_read(&file, _acBuffer, gFileSize, &br);
  2.        
  3.         if(res != FR_OK){
  4.                 printf("f_read _acBuffer error\r\n");
  5.                 GUI_ALLOC_Free(hMem);
  6.                 f_close(&file);
  7.                 return 0;
  8.         }
复制代码




但是这样读出来后我发现显示不了。于是我定义了一个全局数组
  1. char buf[230454];
  2. res = f_read(&file, buf, gFileSize, &br);

  3. if(res != FR_OK){
  4. printf("f_read buf error\r\n");
  5. GUI_ALLOC_Free(hMem);
  6. f_close(&file);
  7. return 0;
  8. }
复制代码


文件是230454字节大小的。
我用f_read把图片数据读取到全局变量"buf"中能正常使用GUI_BMP_Draw()显示图片。
我用f_read把图片数据读取到GUI_ALLOC_AllocZero所申请到的内存"_acBuffer"数据不能正常使用GUI_BMP_Draw()显示图片。
最终发现f_read()读取到全局变量"buf"和读取数据到GUI_ALLOC_AlloZero所申请的"_acBuffer"里的数据都完全不同的。这个我就很头痛了。但是_acBuffer里我手动写数据读数据又是正常的。有没有大神能给指点一个方向?谢谢。
我用的STemWin版本是5.44a名称是:STemWin_CM7_OS_wc16_ARGB.a。



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2019-10-23 16:12:37 | 显示全部楼层
关闭你emWin动态内存空间的Cache。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2019-10-23 16:17:41 | 显示全部楼层
1、看一下GUIConf.c设置EMWIN的内存是否足够
2、这个操作要先初始化GUI,也就是GUI_Init()之后才能使用EMWIN的内存
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2019-10-24 07:34:39 | 显示全部楼层
panda_lei 发表于 2019-10-23 16:17
1、看一下GUIConf.c设置EMWIN的内存是否足够
2、这个操作要先初始化GUI,也就是GUI_Init()之后才能使用EMW ...

初始化过的。是Cache的问题。
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2019-10-24 08:18:25 | 显示全部楼层
eric2013 发表于 2019-10-23 16:12
关闭你emWin动态内存空间的Cache。

硬汉哥,真乃神人也!不过这个f_read读到GUI所申请的空间读出来的数据倒是正常了。但是。这个当运行到GUI_BMP_Draw(_acBuf, x, y);的时候会出现“未对齐”硬件错误。如图。这个也弄了好久没有解决。烦请指点一下。谢谢! H7Fault_Reports.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2019-10-24 08:23:58 | 显示全部楼层
yconnor 发表于 2019-10-24 08:18
硬汉哥,真乃神人也!不过这个f_read读到GUI所申请的空间读出来的数据倒是正常了。但是。这个当运行到GUI ...

此贴,可以解决:

STM32H7使用emWin的存储设备方式操作图片注意事项
http://www.armbbs.cn/forum.php?m ... 5027&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2019-10-24 09:19:27 | 显示全部楼层
eric2013 发表于 2019-10-24 08:23
此贴,可以解决:

STM32H7使用emWin的存储设备方式操作图片注意事项

好的。谢谢。找了一下。出现“未对齐错误”是由于MPU配置的 Memory type的关系。把其配置成normal就可以了。但是使用GUI_BMP_Draw()的时候不能显示。使用GUI_BMP_GetXSize()的时候获得的X也是0。我先看看你的那个帖子吧。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2019-10-24 09:34:51 | 显示全部楼层
yconnor 发表于 2019-10-24 09:19
好的。谢谢。找了一下。出现“未对齐错误”是由于MPU配置的 Memory type的关系。把其配置成normal就可以 ...

这个也好解决,继续关闭Cache,将MPU里面的TEX设置为LEVEL1
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2019-10-24 09:57:55 | 显示全部楼层
eric2013 发表于 2019-10-24 09:34
这个也好解决,继续关闭Cache,将MPU里面的TEX设置为LEVEL1

但是玄学的问题又来了!现在能够把这个数据给读到GUI所申请的内存中(_acBuf)去了。数据也是正常的。但是调用xSize = GUI_BMP_GetXSize(_acBuf);返回的是0.而且GUI_BMP_Draw(_acBuf, x, y);也不能显示。就好像GUI不能读取一样。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2019-10-24 10:04:54 | 显示全部楼层
yconnor 发表于 2019-10-24 09:57
但是玄学的问题又来了!现在能够把这个数据给读到GUI所申请的内存中(_acBuf)去了。数据也是正常的。但 ...

最后回复一下,你还是搞不定的话,帮不上了

STM32H7使用emWin的存储设备方式操作图片注意事项
http://www.armbbs.cn/forum.php?m ... 5027&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2019-10-24 10:10:10 | 显示全部楼层
eric2013 发表于 2019-10-24 10:04
最后回复一下,你还是搞不定的话,帮不上了

STM32H7使用emWin的存储设备方式操作图片注意事项

好吧。我看了您的那个帖子。我再看看吧。 如果解决了问题我再把原因发上来吧。
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2019-10-28 14:34:29 | 显示全部楼层
问题都解决了。这里问题总结一下吧。以后有人遇到也能快速出坑!
我这个工程是用cubeMX来建立的。SD卡结合FATFS可以直接在cube上面配置这里SD卡是用了IDMA。IDMA不需要额外的配置DMA只需要配置其地址就好了。 一开始的时候我是运行在0x2000 0000 的0x20000(128K)的区域里,后来在网上查了一下IDMA是不能接到这一块的如图:
cotexM7内部总线图.png
否则的话在FATFS挂载SD卡的时候,因为会读取特定的区域来判定是不是FATFS格式或者是否需要初始化SD卡的文件系统。不但读取不到而且SDMMC会出现溢出错误。所以要用IDMA需要选择让程序运行到IRAM2区域(在MDK里选择IRAM2)。
再后面的数据读出来正常但GUI_BMP_Draw()不正常。这个应该是Cache一致性的问题。GUI_BMP_Draw是先把文件先全部给读取到GUI申请的内存中,然后再GUI_BMP_Draw来解码到SDRAM中相应的位置再DMA2D到显存中去。
      整个过程如下
1.从SD卡到SDRAM  =>  IDMA处理数据
2.解码图片文件1  =>  CPU读取文件数据(此时就会出现一致性问题,当cache hit的时候 IDMA传递到目的地址的数据并不会在Cache中更新,CPU解码出来的数据就不正确,更无从显示了。)
  在出现像上面这样CPU经过Cache读取文件,但DMA传送数据改变了实际地址的数据,导致Cache一致性问题的时候,CPU读取的时候可以SCB_InvalidateDCache();来无效化DCache或者
SCB_CleanInvalidateDCache_by_Addr()来无效化相应的地址的DCache。可解决此问题。3.解码图片文件2 =>   CPU解码后把解码后的图片数据暂存到SDRAM中
3.显示图片      =>   DMA2D把解码后的数据加速显示到显存中去(此时如果Cache策略配置的是WB“写回”也会出现一致性问题,当Cache hit的时候 CPU不会立即写到实际地址DMA2D的时候当然不正常了。)
  在出现像上面这样CPU经过Cache写入文件,DMA2D读取实际地址之前可以SCB_CleanDCache();清除Cache强制使其写到实际地址。当然WT不会出现这种情况。
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2019-10-28 15:08:37 | 显示全部楼层
在SDRAM区域如果采取的Cache策略是WB那么在GUI_ALLOC_AllocZero()的时候可能会出现PRECISERR(精准总线错误)。暂时没有明白是啥原因。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-16 01:29 , Processed in 0.200902 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表