This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320C6674:HeapBufMP_create 失败并出现断言失败"Region has no heap"

Guru**** 657930 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1206838/tms320c6674-heapbufmp_create-fails-with-assertion-failure-region-has-no-heap

器件型号:TMS320C6674

我将根据示例 IPC_3_50_04_08\examples\C6678_BIOS_elf\ex11_ping 创建应用。

我使用 MessageQ 在任务之间进行通信。

根据文档、MessageQ 使用具有可变长度块大小的堆(HeapMemMP)。 我担心这会导致碎片化、从而减慢执行速度。 因此、我曾尝试改用固定块大小堆(HeapBufMP)。

ipc.cfg.xs 中包含以下代码:

VAR SHAREDMEM = 0x0C000000;
VAR SHAREDMEMSIZE = 0x00200000;

SharedRegion.setEntryMeta(0、
 新的 SharedRegion.MetaEntry ({
  名称:"SR_0"、
  基地址:SHAREDMEM、
  LEN:SHAREDMEMSIZE、
  ownerProcId:0、
  IsValid:true、
  高速缓冲存储器启用:true、
  createHeap:错误
 })
);

(我将变量 createHeap 更改为 false、以便可以使用不同类型的堆。)

我在 main.c 中包含以下代码:

#define IPC_HEAP_FIXED_SIZE 1.

#if IPC_HEAP_FIXED_SIZE
 HeapBufMP_Params heap_params;

 /*创建将用于分配消息的堆。 */
 HeapBufMP_Params_init (&heap_params);
 heap_params.RegionID = 0;/*使用默认区域*/
 heap_params.name ="IPC_HEAP";
 heap_params.align = 256;
 heap_params.numBlocks = 2000;// SR_0大小为2MB
 heap_params.blocksize = 1024;
 heap_params.gate = NULL;/*使用系统门*/

 HEAP_Handle =(IHeap_Handle) HeapBufMP_create (&heap_params);

#else /*在 ipc-cfg.xs 中的共享区域 SR_0中定义的堆*/
 /*获取 SR_0堆句柄*/
 HEAP_Handle =(IHeap_Handle) SharedRegion_getHeap (0);
#endif

 status = MessageQ_registerHeap (heap_handle、IPC_heap);

(#else 部分是有效的原始代码。)

当我运行代码时、会发生断言故障:

  TI.sdo.ipc.grant.HeapBufMP:第831行:断言失败:A_noHeap:区域没有堆

如果是单步执行、在步进到函数 HeapBufMP_create 时、该生效立即失败

什么地方出错了? 为什么当我们刚刚创建堆时、HeapBufMP 希望共享区域有一个堆?

--

Pauli.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pauli,

    让我来看看并回来。

    此致

    Shankari G

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pauli,

    根据下面 API 的应用使用说明、堆似乎仅在共享存储器区域中创建。

    ——

    位于 doxygen 文件--> /ti/ipc_3_50_04_08/docs/doxygen/html/_heap_buf_m_p_8h.html

    ===================================================

    多处理器固定大小缓冲器堆实现。

    注意
    HeapBufMP 当前只适用于 SYS/BIOS。

    管理可在具有共享存储器的多处理器系统中使用的固定大小缓冲器的堆实现。

    HeapBufMP 管理器提供函数来分配和释放从 IHeap 继承的 HeapBufMP 类型堆中的存储空间。 HeapBufMP 管理一个固定大小的缓冲区、分成大小相等的可分配块。

    HeapBufMP 管理器的用途是作为一个非常快速的内存管理器、只能分配单一大小的块。 它非常适用于管理仅用于分配单个类型对象的堆或大小非常相似的对象。

    在创建实例时、HeapBufMP 模块使用 nameserver 实例来存储实例信息。 为所有 HeapBufMP 实例提供的名称必须是唯一的。

    ——

    此致

    Shankari G

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    共享区域0位于 MSM SRAM 共享存储器中、如文件 IPC.cfg.XC (请参阅上文)中定义的那样。

    在  HeapBufMP_create ()调用中,字段 RegionID 为0。 我假设它应该使用共享区域0。

    --

    Pauli.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pauli,

    你的问题是--> 当我们只是在创建堆时,HeapBufMP 为什么要求共享区域有一个堆?"

    这就是为什么我指出,为什么 HeapBufMP 期望共享区域..

    ——

    我建议您浏览 C6678 EVM 上的 IPC-Image 处理演示代码(即工作代码)。 它可以正确使用这些 API。

     文件位置 :--> \processor_sdk_rtos_c667x_6_03_00_106\demos\image_processing

    此致

    Shankari G

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Shankari、

    我不明白你 所说的"HeapBufMP 期望共享区域"是什么意思。

    给出的参数  HeapBufMP_create() 没有一个字段  heap_params.RegionID = 0 。 我假设它定义了要使用的共享区域。

    不过、我看了图像处理代码。 我发现的唯一区别是  createHeap  来实现  SharedRegion.setEntryMeta 未给出定义。 此字段的默认值似乎为"TRUE"(即使在任何文档中都没有提及)。 当我将此字段设置为"true"时、不再发生断言失败。

    那意味着进行调用  HeapBufMP_create() 想要保留另一个堆的存储器空间? 这很奇怪。 文档中没有这方面的信息。

    --

    Pauli.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pauli,

    让我更仔细地看一下并返回。

    此致

    Shankari G

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pauli,

    当我查看 IPC 软件包及其源代码时、有一点很明显...

    1. 如果"createHeap"字段设置为 true、在 SharedRegion 中创建一个 HeapMemMP 实例

    请注意,IPC_START()使用索引为0 (零)的 SharedRegion 来创建资源管理表,供 GateMP、nameserver 和 Notify 模块内部使用。 因此、所有处理器都必须可以访问 SharedRegion "0"。

    可以尝试更改共享区域的索引、例如0、2等、

    例如、  

    SharedRegion.setEntryMeta(1,/*创建共享区域1 *

    ---------------- 以下仅供参考共享区域的 setEntry 的实现。。  

    *每个共享区域包含以下内容:
    *-@b 基地址-基地址
    *-@b len -长度
    *-@b name -地区的名称
    *-@b IsValid -区域是否有效
    *-@b ownerProcId -拥有该区域的处理器的 ID
    *-@b 高速缓存启用-该区域是否可高速缓存
    *-@b cacheLineSize -高速缓存行大小
    *-@b createHeap -是否为该区域创建了一个堆。
    *
    *使用 SharedRegion_setEntry () API 添加一个区域。
    *所有处理器的区域长度必须相同。
    *可以指定区域的所有者。 如果指定了所有者
    *管理共享区域。 它会创建一个可覆盖的 HeapMemMP 实例
    *整个区域的大小。 其他处理器打开同一个 HeapMemMP
    *实例。
    *
    *注:调用 IPC_START()之前,如果 SharedRegion 的'IsValid'
    *是正确的和'createHeap'是正确的那么 SharedRegion 的所有者
    *必须与 SharedRegion 0的所有者相同。

    ---

    /*

     *===========  SharedRegion_setEntry =========

     * 设置表中指定的区域。

     */

    int SharedRegion_setEntry (Uint16 id、SharedRegion_Entry *条目)

       TI_sdo_IPC_ShardRegion_Region *区域;

       HeapMemMP_Params   参数;

       HeapMemMP_Handle heapHandle   ;

       HeapMemMP_Handle   * heapHandlePtr;

       UINT               密钥;

       PTR sharedAddr                ;

       int status = SharedRegion_S_SUCCESS;

       Error_Block EB;

     

       /*需要确保 id 小于 numEntries */

       assert_isTrue ((id < ti_sdo_ipc_SharedRegion_numEntries)、

           TI_sdo_IPC_SharedRegion_A_idTooCharge);

     

       /*确保条目不是 NULL */

       assert_isTrue ((entry!= NULL)、ti_sdo_ipc_ipc_a_nullArgument);

     

       error_init (&eb);

     

       Region =&(SharedRegion_MODULE->Regions[id]);

     

       /*确保区域不与现有区域重叠*/

       状态= SharedRegion_checkOverlap (entry->base、(SizeT) entry->len);

     

       如果(status == SharedRegion_S_SUCCESS){

           /*此时区域条目应无效*/

           if (region->entry.IsValid){

               /*断言某个区域已存在*/

               assert_isTrue (false、ti_sdo_ipc_SharedRegion_A_alreadyExists);

               状态= SharedRegion_E_ALREADYEXISTS;

               返回(状态);

           }

     

           /*如果 CacheEnabled 和 CacheLineSize 等于0,则置位*/

           if ((entry->cacheEnable)&&(entry->cacheLineSize == 0)){

               /*如果启用了高速缓存,则高速缓存行大小必须为!= 0 */

               assert_isTrue (false、ti_sdo_ipc_SharedRegion_A_cacheLineSizeIsZero);

           }

     

           /*需要线程安全*/

           KEY = Hwi_disable ();

     

           /*将指定区域 ID 设置为条目值*/

           region->entry.base = entry->base         ;

           region->entry.len          =(ptr) entry->len;

           region->entry.ownerProcId  = entry->ownerProcId;

           region->entry.cacheEnable  = entry->cacheEnable;

           region->entry.cacheLineSize = entry->cacheLineSize;

           region->entry.createHeap   = entry->createHeap;

           region->entry.name         = entry->name;

           region->entry.IsValid      = entry->IsValid;

     

           /*离开闸门*/

           HWI_RESTORE (KEY);

     

           如果(!region->entry.IsValid){

               /*地区尚未生效*/

               返回(状态);

           }

     

           如果(entry->ownerProcId == MultiProc_self()){

               if ((entry->createHeap)&&(region->heap == NULL)){

                   /*获取当前 ptr (保留大小为0的存储器)*/

                   sharedAddr = ti_sdo_ipc_SharedRegion_reserveMemory (id、0);

     

                   HeapMemMP_Params_init (&params);

                   params.sharedAddr = sharedAddr;

                   params.sharedBufSize =(SizeT)(region->entry.len)-

                                          区域->reservedSize;

     

                   /*

                    * 计算 HeapMemMP_Attrs 的大小并调整 sharedBufSize

                    * HeapMemMP_Attrs 的大小= HeapMemMP_sharedMemReq (&params)-

                    *                           params.sharedBufSize.

                    */

                   params.sharedBufSize -=(HeapMemMP_sharedMemReq (&params)

                                            - params.sharedBufSize);

     

                   heapHandle = HeapMemMP_create (&params);

                   if (heapHandle == NULL){

                       region->entry.IsValid = false;

                       返回(SharedRegion_E_MEMORY);

                   }

     

                   region->heap =(IHeap_Handle) heapHandle;

               }

           }

           否则{

               if ((entry->createHeap)&&(region->heap == NULL)){

                   /* sharedAddr 应与每个区域的创建者匹配*/

                   sharedAddr =(ptr)((UArg)entry->base +

                       区域->reservedSize);

     

                   /*将指针设置为堆句柄*/

                   heapHandlePtr =(HeapMemMP_Handle *)和(region->heap);

     

                   /*通过地址打开堆*/

                   如果(HeapMemMP_openByAddr (sharedAddr、heapHandlePtr)!=

                       HeapMemMP_S_SUCCESS){

                       状态= SharedRegion_E_FAIL;

                       region->entry.IsValid = false;

                   }

               }

           }

       }

     

       返回(状态);

    }

    ——

    堆*mp 模块的其他信息

    Heap*MP 模块进行了以下假设:

    •SharedRegion 模块处理虚拟共享地址空间和本地处理器地址空间间的地址转换。 如果存储器地址空间在所有处理器上都相同、或者正在使用单个处理器、则无需地址转换、必须适当配置 SharedRegion 模块

    创建 Heap*MP 实例

    堆可以动态创建。 您可以使用 Heap*MP_create()函数动态地创建 Heap*MP 实例。 与其他 IPC 模块一样,在创建 Heap*MP 实例之前,您需要初始化 Heap*MP_Params 结构并将该结构中的字段设置为所需的值。 创建堆时,会初始化共享内存,并在本地内存中创建 Heap*MP 对象。 只有实际的缓冲区和一些共享信息驻留在共享存储器中。

    有关这些 API 的更多内容如下所示均适用于 IPC 模块、难怪是否必须在共享存储器区域中创建堆。

    对于所有这些分配函数、消息的缓存一致性由管理用于堆的共享存储器区域的 SharedRegion 模块进行管理。

    如需更多信息、请查看"\ti\ipc_3_50_04_08\docs"--> IPC_Users_Guide.pdf 下的 IPC 用户指南

    e2e.ti.com/.../IPC_5F00_Users_5F00_Guide.pdf

    此致

    Shankari G

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我尝试通过将其添加到 ipc.cfg.xs 中来定义另一个共享区域:

    SharedRegion.setEntryMeta(1、 
    新的 SharedRegion.MetaEntry ({
    名称:"SR_1"、
    基址:0x84000000、
    LEN:0x00100000、
    ownerProcId:0、
    IsValid:true、
    高速缓冲存储器启用:true
    })
    );

    并更改了 main.c 中的 HeapBufMP_create ()以使用区域1而不是区域0。

    但我遇到以下链接器错误:


    "bin/release/configuro/linker.cmd"、第142行:警告:指定的地址位于存储器映射之外
    错误:默认内存范围与现有内存范围 ddr3_mailbox_reserved 重叠
    错误:默认存储器范围与现有存储器范围 TSIP 缓冲区重叠
    错误:默认存储器范围与现有存储器范围 CORE0_DATA 重叠
    错误:链接期间遇到错误;未生成"bin/release/nextear_app.xe66"

    >>编译失败

    据我所见、定义的共享区域不会与上述任何存储器范围重叠。

    无论如何、从共享区域0堆中定义堆(正如我之前描述的那样)似乎可行、所以我认为没关系。

    --

    Pauli.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、Pauli。 感谢您的尝试和投篮。

    我来关闭该主题。

    此致

    Shankari G