Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
CACHE
lwip与CACHE引出关于GCC 连接脚本的疑惑
发布于 2020-01-31 15:40:44 浏览:1383
订阅该版
先描述一下情景。 使用STM32F745芯片配合RTThread+lwip。 对于带ETH MAC的STM32芯片,会使用特殊的DMA来完成以太网MAC与通用内存之间的数据交互,这就需要程序员在内存中开辟一片空间用于存放接收和发送的DMA描述符与DMA缓冲区。 对于裸机,我们一般是直接定义结构体数组来静态存放。对于RTThread这类有内存管理的系统,一般是使用内存管理方法动态分配,就像下图 ![malloc.jpg](/uploads/202001/31/142745ap9oojj89cpjojcj.jpg) 对于其他CM3,CM4芯片来说,这并没什么问题。但对于f745这种有I.D CACHE的CM7芯片就会出现问题了。测试结果发现后来测试发现网络无法使用,ping不通。抓包发现有时也有ICMP包的请求与应答,只是错位了,简单来讲就是host连续发两包才能收到板子给的第一包的回复。按其现象推测是CACHE在捣乱了。引发了数据一致性问题! ![li.jpg](/uploads/202001/31/144007lqiiqhq8jq2zjqh6.jpg) 就像这样,主机ping过来的ICMP包,由DMA将MAC数据推送到SRAM。同时触发中断通知lwip调用netinput从上图分配的buf中读取数据。但是此时此地址的内存正好处于cache命中状态,内核将cache中的数据返回给netinput函数。结果就是lwip收到的数据根本就不是当前中断要推送的数据。自然网络就无法使用了。既然是cache引发的问题,我们就考虑关掉它。 ![cachestatus.jpg](/uploads/202001/31/144811qqymkd1a0a1kadf4.jpg) 参考这张cache配置图。我们走红线标记的这条路,这个S选项,我个人理解在CM7,至少STM32F7这个处理器上并没有它本身的用途,不管前面的选项如何配置,只要置为了S选项,那此块内存就会变为"无cache,无buffer"的状态。这个S存在的目的就是为了区分访问设备内存还是一块叫PPB的内存。开始配置,上MPU ![mpu.jpg](/uploads/202001/31/145910a1zo7411yyap01pe.jpg) 在程序的最开始,最最开始那里,就是 void rt_hw_board_init()这个函数的最开始,对MPU进行此配置,记得配置完HAL_MPU_Enable,我没截图。 从上图可以看出我们使能了0x20000000这块区域的访问,设置区域大小,剩下的配置就完全按照上上的路线图,TEX=1,CACHE=0,BUFFER=0,SHARE=0.这样就完成了对系统SRAM1的CACHE关闭操作。编译烧录进板子发现网络就正常了没完全可以使用 但是对于CM7这个芯片,费这么大辛苦设计的CACHE让我们就这样关掉了,岂不是太浪费资源了。起初想过根据RTThread动态分配出来的内存来配置MPU关闭某一区域是否可行,后来想想放弃了,动态分配出来的地址千奇百怪,不好保证MPU区域配置的对齐问题。 网上查资料发现其实芯片设计师早就想到了会出现这个问题。 ![cache.jpg](/uploads/202001/31/142744mjulqmcdl2qf9pfn.jpg) 这个是F7的内部总线图。发现SRAM分成了两块。 ![mem.jpg](/uploads/202001/31/150905o8r4m1dzmmm34r1y.jpg) SRAM2就是专门设计给高速外设DMA用来避免CACHE导致的数据一致性问题的。 现在我们就可以修改我们的代码。 1.屏蔽DMA描述符与缓冲区系统动态分配内存。 2.重新定义DMA描述符 ![idfaction.jpg](/uploads/202001/31/142745hctwtttijgei8t9w.jpg) 就像这样,我们将变量地址手动分配到SRAM2的地址去 3.配置MPU ![mpuconfig.jpg](/uploads/202001/31/151340iny3987ygn7ga3qq.jpg) 具体是这样的, - 第一块就是把系统内存(SRAM1)配置为"写回,无写分配,非共享"。这里没有打开写分配,针对不同应用打开可能会进一步提升性能 - 第二块就是把SRAM2内存配置为“无cache,无buffer,共享内存”。这里用于收发数据缓冲区 - 第三块就是把SRAM2区起始的256Byte区域配置成“DEVICE”这个TEX,C,B,S标志位就没有意义了,就是固定组合,就只能这样配置。至于为什么要将次块内存配置称DEVICE属性,暂时没有想明白,姑且认为是网络DMA描述符区域与硬件相关,在读写顺序上有要求把。 重点注意下这里的`“MPU_InitStruct.Number = MPU_REGION_NUMBER2;”`这个是MPU块号。 号越大优先级越高,所以虽然同样是对0x2004C000这块区域的配置,导致前256Byte的空间优先按照第三块的配置去执行。 --- 到了这里该提出这篇帖子的疑问,上面说到我们手动把变量分配到指定地址,对于keil的ARMCC来说,可以直接在变量定义后指定。但对于GCC,我尝试无效,不清楚是不是我写法有问题,还请知道的大神给予帮助。目前我是修改链接脚本,在其中定义一个我想要的段出来 ![map.jpg](/uploads/202001/31/142745l595b9b9ffl4cbv7.jpg) 就像这样, - 1.我弄不明白是的上面那个MEMORY区域有什么作用? - 2.每一个内存段区域最后的>RAM这个标识有什么作用? - 3.我使用的是LOADADDR(.BSS)+SIZEOF(.BSS).这样的方确定这个自定义段的家在地址(如果不这样定义也可以正常运行。但是会导致自定义段的加载地址默认到运行地址0x2004C000,导致生成的BIN文件有384MB之大:L,所以只能这样显试的指定加载地址)。只能采用这样端+大小的方法吗?有没有别的指定方法 - 4.为什么看map文件,.bss段竟然也占空间,对于bss段不是应该只有标识,并不占空间吗?是不是我哪里理解有误区 --- 来一张网速测试图,同时祝RTThread团队所有成员以及社区贡献者新春快乐。 大家每人奉献一分力,RTThread在大家的努力下越做越好! ![test.jpg](/uploads/202001/31/154010aomzmsgaaumzsuh6.jpg)
查看更多
李肯陪你玩赚嵌入式
认证专家
2021-10-11
2022年度和2023年度RT-Thread社区优秀开源布道师,COC深圳城市开发者社区主理人,专注于嵌入式物联网的架构设计
对GCC的链接脚本研究过一段时间,目前的项目中也经常使用,简单回答下你的几个问题: 1.我弄不明白是的上面那个MEMORY区域有什么作用? **这个MEMORY就是约定你的芯片平台有那块memory区域,一般包含ROM(大部分使用flash在代替)和RAM(内存);像你的模板,其中RAM就分两块,对应RAM和RAM2;它的地址空间是分开的;** 2.每一个内存段区域最后的>RAM这个标识有什么作用? **这个>RAM就表示这个段约定只使用RAM区域的地址空间(对应就是MEMORY部分规划的地址);如果是>RAM2,那就是约定使用RAM2区域;** 3.我使用的是LOADADDR(.BSS)+SIZEOF(.BSS).这样的方确定这个自定义段的家在地址(如果不这样定义也可以正常运行。但是会导致自定义段的加载地址默认到运行地址0x2004C000,导致生成的BIN文件有384MB之大:L,所以只能这样显试的指定加载地址)。只能采用这样端+大小的方法吗?有没有别的指定方法 **这个问题的根源应该是你的MEMORY里面有2段RAM/RAM2,而他们的地址空间不是连在一起的,如果你不用LOADADDR显式指定的话,就会引入一些填充数据,所以导致编译处理的bin文件有300多MB。如果加上LOADADDR能解决你的问题,就加上吧。** 4.为什么看map文件,.bss段竟然也占空间,对于bss段不是应该只有标识,并不占空间吗?是不是我哪里理解有误区 **一般来说BSS段是跟DATA段一起来对比的;BSS段指的是全局的未初始化的数据,而DATA段指的是已初始化且初始化非0的数据;BSS段和DATA段都会占用RAM区域,因为他们是变量,允许修改的,只能使用RAM来保存;而DATA段不仅要占用RAM,还有占用ROM,因为它的值不是0,必须有地方来存储它的值,所以只能到ROM里面;因为BSS段全是0,所以ROM里面是找不到BSS段的东西,所以不占ROM空间。**
2
个回答
默认排序
按发布时间排序
whj467467222
认证专家
2020-02-01
开源,分享,交流,共同进步
同样在H7中,也存在找个问题。我在使用H7以太网的时候是参考了ST的例程,使用的是keil开发环境。 接收数据缓存区在ST提供的例程里面使用了宏定义的方式来适配的不通编译器,楼主有去看过嘛?
撰写答案
登录
注册新账号
关注者
0
被浏览
1.4k
关于作者
Rses_001
这家伙很懒,什么也没写!
提问
6
回答
19
被采纳
0
关注TA
发私信
相关问题
1
COTEX-A7配置L2 cache
2
h743 ICache无法进行socket通信
3
H750 SPI DMA 问题
4
关于 DMA 和 Dcache 操作的疑惑?
5
谁知道cache,uncache的概念
6
v4.0.1的bsp下的imxrt1021工程下没有drv_cache.c
7
stm32h743xi 开启D-Cache后死机
8
针对STM32F7系列平台的MPU,Cache特性,需要注意哪些问题?
9
如何实现内存分配成uncached
10
RTT有CACHE以及MMU操作接口吗?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部