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.

[参考译文] TMS320C6678:OpenMP、SRIO 与 qmss 协同工作

Guru**** 2539500 points
Other Parts Discussed in Thread: SYSBIOS

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/862025/tms320c6678-openmp-srio-work-together-with-qmss

器件型号:TMS320C6678

大家好、

我正在使用 TMS320C6678 DSP 并尝试在项目中实现 OpenMP。 原始项目是 SRIO 项目。我在使它们协同工作时遇到问题。

   我从 e2e 和 wiki 搜索了很多、有些问题与我的问题相同。例如 、https://e2e.ti.com/support/processors/f/791/t/468231?OpenMP-QMSS-manual-setup#pi320966=1 、但我尝试时遇到了

 与论坛相同的操作,项目无法正常运行。

 

   首先、我的程序旨在通过 SRIO 实现 FPGA 向 DSP 传输数据、在传输完成后发送门铃中断、然后将数据处理分频为 core0-core7、以便使用进行计算

OMP  并行编程。

   此程序根据 PDK 生成的 SRIO_LpbkDioIsr_evmc6678_C66BiosExampleProject 进行修改。 许多帖子以前都被引用过。 由于 SRIO 使用 qmss、omp 也使用 qmss、

按照 http://downloads.ti.com/mctools/esd/docs/openmp-dsp/integrating_apps_with_qmss.html 手动初始化 qmss。 由于 SRIO 使用128个描述符并使用 Qms_MemRegion_memory_REGION0、

在 cfg 文件中修改以下内容。

 

ompSettings.runtimeInitializesQmss = false;

OpenMP* qmsMemRegionIndex = 1;

OpenMP* qmsFirstDescIdxInLinkingRam = 128;

在 DDR.len 后面添加以下代码。

VAR Cache = xdc.useModule('ti.sysbios.family.c66.Cache');
Cache.setMarMeta(msmcNcVirt.base、msmcNcVirt.len、0);
Cache.setMarMeta(OpenMP.ddrBase、OpenMP*、ddrSize  
cache.p|cache.pfx|cache.wTE);
Cache.setMarMeta(OpenMP.msmcBase、OpenMP*。msmmcSize  
cache.p|cache.pfx|cache.wTE);

在 _TI_omp_initialize_rtsc_mode 之前添加定制的 qmss 函数

VAR 启动= xdc.useModule('xdc.runtime.Startup');
startup.lastFxns.$add ('&qmsInitOmp');
startup.lastFxns.$add ("&_TI_omp_initialize_rtsc_mode");

存在以下现象:

1如果 SRIO 的任务未启动、则 omp 程序正常运行;

2如果 omp 程序未启动、SRIO 程序正常运行、并且可以接收门铃中断;

3如果 SRIO 和 omp 程序同时启动、则仍然可以在 SRIO 程序中接收门铃中断、但 omp 程序报告错误内部错误:Unexpected NULL pointer-src/tomp_parallel.c、224

我的任务是通过 cfg 文件静态启动的。 SRIO 具有最低优先级、omp 程序具有最高优先级。 我严格遵循 omp2.0用户指南中的说明,例如,修改自动运行选项等等

我的问题是:

1我的 qmss 启动方法是否正确?

2当 omp 程序将显示此类错误内部错误时:Unexpected NULL Pointer-src / tomp_parallel.c、224;

在下面发布我的 cfg 文件和相关代码。

我想我在 QMSS init 中犯了一些错误、但我无法通过自己找到它。 提前感谢您。

此致

 

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

    这是我的 cfg 文件

    //
    *版权所有(c) 2013,Texas Instruments Incorporated - http://www.ti.com/
    *保留所有权利。
    *
    *
    只要满足以下条件
    、就允许以源代码和二进制形式重新分发和使用、无论是否进行*修改:* *重新分发源代码必须保留上述版权
    * 声明、此条件列表和以下免责声明。
    * *二进制形式的再发行必须复制上述版权
    * 请注意
    、*中的此条件列表和以下免责声明 分发时提供的文档和/或其他材料。
    * *德州仪器公司的名称和
    * 其贡献者的姓名可用于认可或推广产品
    * 未经特定的事先书面许可从该软件派生。
    *
    本软件由版权所有者和贡献者"按原样"提供
    *、
    
    不承担任何明示或暗示的保证、包括但不限于*适销性和特定用途适用性的暗示保证*。 在任何情况下、版权所有者或贡献者
    都不对任何直接、间接、偶然、特殊、模范、 或
    *相应的损害(包括但不限于采购
    *替代产品或服务;丧失使用、数据或利润; 或业务
    *中断)、但出于
    
    任何责任理论、无论是在*合同中、严格责任还是在使用本软件时以任何方式产生的侵权行为(包括疏忽或其他原因)*、即使已告知
    *可能会发生此类损坏。
    */
    
    
    ********* //*
    段映射 */
    ********* /*
    加载 CSL 软件包*/
    var CSl = xdc.loadPackage ('ti.csl');
    
    //加载 CPPI 软件包*/
    var cpi = xdc.loadPackage ('ti.drv.cppi');
    
    /*加载 QMSS 软件包*/
    var Qmss = xdc.loadPackage ('ti.drv.qms');
    var SRIO = xdc.loadPackage ('ti.drv.SRIO');
    //加载并配置 SYSBIOS 软件包*/
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var 任务 = xdc.useModule('ti.sysbios.knl.Task');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Mailbox = xdc.useModule('ti.sysbios.knl.Mailbox');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var ECM = xdc.useModule('ti.sysbios.family.c64p.EventCombiner');
    var BiosCache = xdc.useModule('ti.sysbios.hal.Cache');
    var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var EXC = xdc.useModule('ti.sysbios.family.c64p.Exception');
    var 高速缓存 = xdc.useModule('ti.sysbios.family.c66.Cache');
    
    BIOS.taskEnabled = true;
    Task.common$.namedInstance = true;
    var 程序= xdc.useModule('xdc.cfg.Program');
    
    program.sectMap[".args"] = new Program.SectionSpec ();
    program.sectMap[".bss"] = new Program.SectionSpec ();//
    program.sectMap[".cinit"] = new Program.SectionSpec ();//
    program.sectMap[".cio"] = new Program.SectionSpec ();//
    program.sectMap[".const"] = new Program.SectionSpec ();//
    program.sectMap[".data"] = new Program.SectionSpec ();
    program.sectMap[".far"] = new Program.SectionSpec ();//
    program.sectMap[".fardata"] = new Program.SectionSpec ();//
    program.sectMap[".neardata"]= new Program.SectionSpec ();//
    program.sectMap[".rodata"] = new Program.SectionSpec ();//
    program.sectMap[".stack"] = new Program.SectionSpec ();//
    program.sectMap[".switch"] = new Program.SectionSpec ();//
    program.sectMap[".sysmem"] = new Program.SectionSpec ();
    program.sectMap[".text"] = new Program.SectionSpec ();//
    Program.sectMap[".inputbuff"]= new Program.SectionSpec ();//添加何时处理缓冲器合金
    
    //必须将这些段放置在核心本地存储
    器 program.sectMap[".args"].loadSegment 中 ="L2SRAM";
    program.sectMap[".cio"].loadSegment ="L2SRAM";
    
    //
    在// OpenMP 中,以下数据段中的变量可能会被“共享”。 这些段必须放置在共享存储器中。
    program.sectMap[".bss"].loadSegment ="DDR3";
    program.sectMap[".cinit"].loadSegment ="DDR3";
    program.sectMap[".const"].loadSegment ="DDR3";
    program.sectMap[".data"].loadSegment ="DDR3";
    program.sectMap[".far"].loadSegment ="DDR3";
    program.sectMap[".fardata"].loadSegment ="DDR3";
    program.sectMap[".neardata"].loadSegment ="DDR3";
    program.sectMap[".rodata"].loadSegment ="DDR3";
    program.sectMap[".sysmem"].loadSegment ="DDR3";
    Program.sectMap[".inputbuff"].loadSegment ="MSMCSRAM";
    
    //内核共享的代码段-放置在共享存储器中以避免复制
    program.sectMap[".switch"].loadSegment = program.platform.codeMemory;
    program.sectMap[".text"].loadSegment = program.platform.codeMemory;
    
    //调整默认堆栈的大小并将其放置在 L2SRAM
    程序中。stack = 0x20000;
    program.sectMap[".stack"].loadSegment ="L2SRAM";
    
    //由于没有参数传递给 main,因此将.args 大小设置为0
    program.argSize = 0;
    
    
    //将 System_printf 输出发送到 printf
    var System = xdc.useModule('xdc.runtime.System');
    var Std = xdc.useModule('xdc.runtime.SysStd');
    System.SupportProxy = SysStd;
    
    
    /******** /*
    OpenMP 运行时配置*/********
    //
    
    在编译
    中包含 OMP 运行时 var ompSettings = xdc.useModule("ti.runtime.openmp.Settings");
    
    //如果应用程序使用 BIOS 组件或依赖 BIOS 组件则设置为 true
    ompSettings.usingRtsc = true;
    // ompSettings.runtimeInitializesQmss = false;
    
    if (ompSettings.usingRtsc)
    {
    /*为 BIOS 配置 OpenMP
    *- OpenMP* configureCores (masterCoreId、numberofCoresInRuntime)
    * 配置主内核的 ID 和内核数
    * 运行时可用。
    *
    
    VAR OpenMP = xdc.useModule('ti.runtime.ompbios.OpenMP');
    
    //配置主内核的索引和可用内核的数量
    //到运行时。 内核是连续的。
    OpenMP*主 CoreIdx = 0;
    
    
    //OpenMP* qmsMemRegionIndex = 1;//4;//1
    //OpenMP* qmsFirstDescIdxInLinkingRam = 128;/224;//160
    
    //根据器件设置内核数
    VAR deviceName =字符串(Program.cpu.deviceName);
    如果 (deviceName.search("6670")!=-1){OpenMP* = 4;}
    否则,如果(deviceName.search("6657")!=-1){ OpenMP* = 2;}
    其他 { OpenMP* = 8;}
    
    //拉入 Platform.XDC 中描述的内存范围以配置运行时
    VAR DDR3 = Program.cpu.memoryMap["DDR3"];
    VAR MSMC = Program.cpu.memoryMap["MSMCSRAM"];
    var msmcNcVirt= Program.cpu.memoryMap["OMP_MSMC_NC_virt"];
    var msmcNcPhy = Program.cpu.memoryMap["OMP_MSMC_NC_PHY"];
    
    //使用内存范围信息初始化运行时间
    OpenMP* msmcBase = MSMC.base;
    OpenMP* msmcSize = MSMC.len;
    
    OpenMP* msmcNoCacheVirtualBase = msmcNcVirt.base;
    OpenMP* msmcNoCacheVirtualSize = msmcNcVirt.len;
    
    OpenMP*(msmcNoCachePhysicalBase)= msmcNcPhy.base;
    
    OpenMP*版 = DDR3.base;
    OpenMP*文件大小 = DDR3.len;
    
    VAR Cache = xdc.useModule('ti.sysbios.family.c66.Cache');
    Cache.setMarMeta(msmcNcVirt.base、msmcNcVirt.len、0);
    Cache.setMarMeta(OpenMP.ddrBase、OpenMP*、ddrSize
    cache.p|cache.pfx|cache.wTE);
    Cache.setMarMeta(OpenMP.msmcBase、OpenMP*。msmmcSize
    cache.p|cache.pfx|cache.wTE);
    
    
    
    //使用 HeapOMP 配置内存分配
    // HeapOMP 句柄
    //- BIOS 组件发出的内存分配请求(内核本地内存)
    //-使用 IPC 模块启用共享内存分配
    //从同一堆中分配内存的多个内核-由 malloc 使用
    VAR HeapOMP = xdc.useModule('ti.runtime.ompbios.HeapOMP');
    
    //必须为 IPC 初始化共享区域0
    VAR sharedRegionId = 0;
    
    //内核本地堆的大小
    VAR localHeapSize = 0x8000;
    
    //所有内核共享的堆的大小
    var sharedHeapSize = 0x80000;
    
    //初始化共享区域并在 DDR3存储器区域中创建堆
    VAR SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
    SharedRegion.setEntryMeta (sharedRegionId、
    {base:dr3.base、
    Len:sharedHeapSize、
    ownerProId:0、
    高速缓冲启用:true、
    createHeap:true、
    IsValid:true、
    名称:"DDR3_SR0"、
    });
    
    
    
    //配置和设置 HeapOMP
    HeapOMP.configure (sharedRegionId、localHeapSize);
    
    
    
    //复位后必须调用函数__TI_omp_reset_rtsc_mode
    VAR Reset = xdc.useModule('xdc.runtime.Reset');
    reset.Fxns.$add ("&_TI_omp_reset_rtsc_mode");
    
    //__TI_omp_start_rtsc_mode 配置运行时并调用 main
    VAR 启动= xdc.useModule('xdc.runtime.Startup');
    
    startup.lastFxns.$add ('&qmsInitOmp');
    
    startup.lastFxns.$add ('&_TI_omp_initialize_rtsc_mode');
    }
    否则
    {
    /*调整堆的大小。 必须将其放置在共享存储器中*
    program.heap = sharedHeapSize;
    }
    var Task =xdc.useModule('ti.sysbios.knl.Task');
    
    
    
    
    
    
    
    task2Params.instance.name="taskDio";
    
    
    
    
    task1Params.instance.name // var task0Params = new Task.Params ();task0Params.instance.name = task0;task0Params.priority=15;Program.global.task0 = Task.create ('&dioExampleTask'、task0Params);*/ var task2Params.priors=15;Program.Params.params=new.task1Params.params.params1r
    
    (&params.params=globality.params.task1.a);task1r = task.params.params.params.params=globality.params1r = task.params.params.params1r = task.params.params.params.params.params1r;task.params.
    
    VAR task0Params = new Task.Params ();
    task0Params.instance.name ="task0";
    task0Params.priority=11;
    Program.global.task0 = Task.create ('&FxnZh'、task0Params);
    

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

    这是它在正常模式下工作的 SRIO 任务

    void dioExampleTask (UArg0、UArg0 arg1)
    
    {
    #ifdef simpler_support
    #warn SRIO DIO LSU ISR 示例在仿真器上不受支持!!!
    System_printf (仿真器不支持"SRIO DIO LSU ISR 示例。 正在退出!\n");
    return;
    #else
    System_printf ("在器件上执行 SRIO DIO 示例\n");
    #endif
    
    /*仅当内核配置为初始化系统时才初始化。 *
    if (coreNum == CORE_SYS_INIT)
    {
    System_printf ("Debug (Core %d):CPPI 和 QMSS\n"的系统初始化、coreNum);
    
    /*系统初始化*/
    //if (system_init()<0)
    //返回;
    
    /*在使用 SRIO 外设之前打开该外设的电源*/
    如果(ENABLE_SRIO ()< 0)
    {
    System_printf ("错误:SRIO PSC 初始化失败\n");
    返回;
    }
    
    /*特定于器件的 SRIO 初始化:应始终在之前调用此函数
    *初始化 SRIO 驱动程序。 *
    if (SrioDevice_init()< 0)
    返回;
    
    /*初始化 SRIO 驱动程序*/
    if (SRIO_init ()< 0)
    {
    System_printf ("错误:SRIO 驱动程序初始化失败\n");
    返回;
    }
    
    /*此时 SRIO 驱动程序可以运行。 *
    System_printf ("Debug (Core %d):SRIO 驱动程序已初始化\n"、coreNum);
    
    /*此时写入共享存储器位置。 其他内核无法执行
    *直到 SRIO 驱动程序启动并运行。 *
    isSRIOInitialized [0]= 1;
    
    /* SRIO IP 块已初始化。 我们需要在此处写回缓存、因为它会
    *确保等待 SRIO 初始化的其余内核现在将是
    *被唤醒。 *
    cache_wbL1d ((void *)&isSRIOInitialized [0]、128、cache_wait);
    
    }
    其他
    {
    /*所有其他内核都需要等待 SRIO 初始化后才能继续。 *
    System_printf ("Debug (Core %d):正在等待 SRIO 初始化。\n"、coreNum);
    
    /*所有其他内核会一直循环、直到 SRIO 启动并运行。
    *我们需要使高速缓存无效,以便始终从内存中读取该数据。 *
    while (isSRIOInitialized [0]=0)
    cache_invL1d ((void *)&isSRIOInitialized [0]、128、cache_wait);
    
    /*启动 QMSS。 *
    if (Qms_start()!= QMSS_Sok)
    {
    System_printf ("错误:无法启动 QMSS\n");
    返回;
    }
    
    System_printf ("Debug (Core %d):现在可以使用 SRIO。\n"、coreNum);
    }
    system_printf ("dio has entered\n");
    uint8 等位;
    SRIO_DrvConfig drvcfg;
    /*初始化 SRIO 驱动程序配置。 *
    memset ((void *)&drvcfg、0、sizeof (SRIO_DrvConfig));
    
    /*初始化 OSAL */
    if (OSAL_dataBufferInitMemory (SRIO_MAX_MTU)< 0)
    {
    System_printf ("错误:无法初始化 OSAL。 \n");
    返回;
    }
    
    /********
    *将使用以下属性创建 SRIO 驱动程序实例:
    *-驱动程序管理
    *-中断支持(将 Rx 完成队列传递为 NULL)
    秘书长的报告 /
    
    /*设置 SRIO 驱动程序管理的配置。 *
    drvcfg.bAppManagedConfig = false;
    
    /*受管理的驱动程序:接收配置*/
    drvcfg.U.drvManagedCfg.bIsRxCfgValid = 1;
    drvcfg.U.drvManagedCfg.rxCfg.rxMemRegion = Qmss_MemRegion_memory_REGION1;
    drvcfg.U.drvManagedCfg.rxCfg.numRxBuffers = 4;
    drvcfg.U.drvManagedCfg.rxCfg.rxMTU = SRIO_MAX_MTU;
    
    /*累加器配置。 *
    {
    int32_t coreToQueueSelector [4];
    
    /*这是将内核映射到特定接收队列的表。 *
    coreToQueueSelector [0]= 704;
    coreToQueueSelector [1]= 705;
    coreToQueueSelector [2]= 706;
    coreToQueueSelector [3]= 707;
    //由于我们正在对累加器进行编程,因此我们希望此队列成为高优先级队列*/
    drvcfg.U.drvManagedCfg.rxCfg.rxCompleQueue = Qmss_queueOpen (Qmss_QueueType_high_priority_queue、
    coreToQueueSelector [coreNum]、isAllocated);
    if (drvcfg.U.drvManagedCfg.rxCfg.rxCompleQueue < 0)
    {
    System_printf ("错误:无法打开 SRIO 接收完成队列\n");
    返回;
    }
    
    /*累加器配置有效。 *
    drvcfg.U.drvManagedCfg.rxCfg.bIsLatr累 加器 CfgValid = 1;
    
    /*累加器配置。 *
    drvCfg.u.drvManagedCfg.rxCfg.accCfg.channel = coreNum;
    drvCfg.u.drvManagedCfg.rxCfg.accCfg.command = Qms_AccCmd_enable_channel;
    drvcfg.U.drvManagedCfg.rxCfg.accCfg.queueEnMask = 0;
    drvcfg.U.drvManagedCfg.rxCfg.accCfg.queMgrIndex = coreToQueueSelector [coreNum];
    drvcfg.U.drvManagedCfg.rxCfg.accCfg.maxPageEntry = 2;
    drvcfg.U.drvManagedCfg.rxCfg.accCfg.timerLoadCount = 0;
    drvCfg.u.drvManagedCfg.rxCfg.accCfg.interruptPacingMode = Qms_AccPacingMode_Last_interrupt;
    drvcfg.U.drvManagedCfg.rxCfg.accCfg.listEntrySize = Qms_AccEntrySize_REG_D;
    drvcfg.U.drvManagedCfg.rxCfg.accCfg.listCountMode = Qms_AccCountMode_entry_count;
    drvcfg.U.drvManagedCfg.rxCfg.accCfg.multiQueueMode = Qms_AccQueueMode_Single_queue;
    
    /*初始化累加器列表内存*/
    //memset ((void *)&gHiPriAccumList[0]、0、sizeof (gHiPriAccumList));
    // drvcfg.U.drvManagedCfg.rxCfg.accCfg.listAddress = L2_global_address ((uint32)&gHiPriAccumList[0]);
    }
    
    /*驱动程序管理:传输配置*/
    drvcfg.U.drvManagedCfg.bIsTxCfgValid = 1;
    drvcfg.U.drvManagedCfg.txCfg.txMemRegion = Qmss_MemRegion_memory_REGION1;
    drvcfg.U.drvManagedCfg.txCfg.numTxBuffers = 4;
    drvcfg.U.drvManagedCfg.txCfg.txMTU = SRIO_MAX_MTU;
    
    /*启动驱动程序管理的 SRIO 驱动程序。 *
    hDrvManagedSrioDrv = SRIO_START (&drvcfg);
    if (hDrvManagedSrioDrv ==空)
    {
    System_printf ("错误(核心%d):SRIO 驱动程序启动失败\n"、coreNum);
    返回;
    }
    
    
    /*获取 CSL SRIO 句柄。 *
    hSrioCSL = CSL_SRIO_Open (0);
    if (hSrioCSL ==空)
    返回-1;
    Hwi_Params HwiParams;
    Hwi_handle myHwi;
    ERROR_Block EB;
    
    Hwi_Params_init (hwiParams);
    ERROR_INIT (&EB);
    HwiParams.arg =(UARg) hDrvManagedSrioDrv;
    hwiParams.EventID = 20;
    //
    myHwi = Hwi_create (11、(CpIntc_FuncPtr) myDoorbellCompleOptionIsr、&hwiParams、&EB);
    
    System_printf ("完成派单插件\n");
    
    } 

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

    这是我的 omp 任务、此任务是一个演示、用于查看任务是否继续正常运行  

    void FxnZh (UARg arg0、UARg arg1){
    内部 tid;
    OMP_SET_num_threads(8);
    while (1){
    pragma omp 并行私有(tid)
    {
    tid=omp_get_thread_num ();
    system_printf ("核心%d 已激活\n"tid);
    }
    system_printf ("fxn_zh 已加入主线程\n");
    Task_sleep (100);
    }
    
    
    } 

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

    您好!

    这与以下内容重复:

    关闭此主题。 请勿在将来重复发布。

    此致、
    Yordan

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

    你(们)好  

    删除此主题时遇到问题、在我的原始帖子中没有删除按钮、您能否帮助我删除此主题、非常感谢  

    此致、

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

    无需将其删除。 我已将其标记为关闭、因此不会解决该问题。 所有答案都将发布在您打开的另一个主题上。


    此致、
    Yordan