1. 初遇“4G壁垒”:那个让人头疼的报错信息
大家好,我是老张,在嵌入式多媒体开发这块儿摸爬滚打十多年了。最近在RK3588平台上折腾多路视频处理,相信不少朋友跟我一样,都撞上过RGA那个著名的“4G内存壁垒”。当时我正在调试一个8路4K视频流的实时拼接项目,程序跑得好好的,突然就崩了,终端里刷刷刷地弹出几行刺眼的错误信息:
rga_policy: RGA2 only support under 4G memory!
RGA_MMU unsupported Memory larger than 4G!
RgaBlit(1483) RGA_BLIT fail: Invalid argument
Failed to call RockChipRga interface, please use 'dmesg' command to view driver error log.
那一瞬间,感觉就像开车上了高速,突然看到前面立了个“限高4米”的牌子,而我的货柜车有4.1米高,直接被卡住了。这个报错的核心意思非常明确:RGA2核心不支持处理物理地址超过4GB(即4G字节)的内存块。RK3588的RGA(Raster Graphic Acceleration)硬件加速器是处理图像缩放、旋转、格式转换的利器,性能强悍,但它的内部设计,特别是RGA2核心的MMU(内存管理单元),有这么一个历史遗留的限制。
为什么会有这个限制呢?这得从硬件设计说起。早期的ARM架构和一些专用的硬件IP,在寻址时使用的地址总线位数可能有限,或者为了简化设计、降低成本,MMU的页表映射机制被设计为只能覆盖低4GB的物理地址空间。当你的应用程序通过malloc或类似接口申请内存时,系统从DDR(也就是我们常说的运行内存)中划出一块给你。在RK3588这种大内存(比如8GB、16GB)平台上,系统为了高效利用所有内存,分配出的内存其物理地址很可能就落在4GB以上。一旦你把这块内存的句柄或地址传给RGA2去处理,它一看地址值“超纲”了,立马就“罢工”报错。
这个场景非常典型:你正在开发智能NVR、多屏异显、高清视频会议终端或者AR/VR设备,需要同时处理多路高清视频流。一路4K的YUV图像,一帧就要占大约12MB(384021601.5字节),8路就是96MB。如果你用的是ION或系统默认的DMA内存分配器,在多路视频流持续处理、内存反复申请释放的过程中,分配到高地址(>4GB)内存的概率会大大增加。错误并非每次都出现,但一旦出现,就意味着功能不可用,产品稳定性大打折扣。所以,理解并解决这个问题,是RK3588高性能多媒体应用开发必须跨过的一道坎。
2. 快速绕行方案:指定RGA3核心,一招鲜吃遍天
遇到问题先别急着深挖底层,咱们工程师讲究效率。对于RK3588的RGA“4G壁垒”,其实有一个非常直接、快速的解决方案,我称之为“快速绕行法”。这个方法的核心思想是:避开有问题的RGA2核心,只用没有这个限制的RGA3核心。
RK3588芯片内部其实集成了三个RGA硬件核心:一个RGA2和两个RGA3(RGA3_CORE0和RGA3_CORE1)。关键的差异就在于,RGA3核心在设计上已经解决了MMU的寻址限制,可以处理整个系统物理地址空间的内存,没有那个烦人的4GB天花板。所以,我们的思路就是,强制让我们的图像处理任务只跑在RGA3核心上。
怎么实现呢?Rockchip提供的librga库给了我们一个非常方便的API:imconfig。你可以在你的图像处理线程初始化的时候,或者在任何调用RGA功能之前,插入这么一行代码:
imconfig(IM_CONFIG_SCHEDULER_CORE, IM_SCHEDULER_RGA3_CORE0 | IM_SCHEDULER_RGA3_CORE1);
我来解释一下这行代码在干什么。imconfig是一个配置函数,第一个参数IM_CONFIG_SCHEDULER_CORE告诉它我们要配置任务调度的核心,第二个参数是一个位掩码,IM_SCHEDULER_RGA3_CORE0和IM_SCHEDULER_RGA3_CORE1分别代表两个RGA3核心。用“或”操作符|把它们组合起来,意思就是“我这个线程接下来的所有RGA处理任务,请只调度到这两个RGA


2186

被折叠的 条评论
为什么被折叠?



