您好,
在鹅 肝转发( https://www.ti.com/lit/ug/tidubo1/tidubo1.pdf )的应用注释后,准骨示例应该起作用,而不是在议会联盟核心报告“任务栏:链接关闭”。 该示例是从 tipse0074 ( https://git.ti.com/cgit/apps/tidep0074/tree/ipu1/PktProcEng.c )的 git repo 中提取的,但更改次数不多(链接状态在这些更改之前已关闭)。
我们正在使用:
EDMA2_12_5.
IPC3_47_1_0
BIOS6_73_0_12
PDK1_0_2
第一个也是最重要的变化是函数“PRUICSS_CREATE”。 “PRUICSS_CREATE”始终从 PRU0_ICSS1启动。 由于我们更改了使用的 PRU (PRU0_ICSS2和 PRU1_ICSS2),我们使用了 pdk1_0_12中的函数,该函数允许选择要使用实例编号初始化的 PRU 核心。
另一项更改是对 server.c -> Server_exec 进行的。 在这里,我们删除了有关 IPC 通信的所有内容,只需将 ICSS_TX 无限循环,间隔为5秒。
pktProcEng.c (未更改的函数被省略)
/* * ---task to initialize PRU--- */ Void taskPruss(void) { Uint8 firmwareLoad_done = FALSE; System_printf("start task PRU-ICSS\n"); uint32_t pgVersion = (VHW_RD_REG32( CSL_MPU_CTRL_MODULE_WKUP_CORE_REGISTERS_REGS + CTRL_WKUP_ID_CODE) & 0xf0000000) >> 28; PRUICSS_pruDisable(pruIcssHandle, ICSS_EMAC_PORT_1-1); PRUICSS_pruDisable(pruIcssHandle, ICSS_EMAC_PORT_2-1); #ifdef SOC_AM572x if (pgVersion >= 2) { System_printf("taskPruss: Load FW to PG2.0 AM572x\n"); if(PRUICSS_pruWriteMemory(pruIcssHandle,PRU_ICSS_IRAM(0), 0, (uint32_t *) PRU0_FIRMWARE_NAME, sizeof(PRU0_FIRMWARE_NAME))) { if(PRUICSS_pruWriteMemory(pruIcssHandle, PRU_ICSS_IRAM(1), 0, (uint32_t *) PRU1_FIRMWARE_NAME, sizeof(PRU1_FIRMWARE_NAME))) firmwareLoad_done = TRUE; } } else { if(PRUICSS_pruWriteMemory(pruIcssHandle,PRU_ICSS_IRAM(0), 0, (uint32_t *) PRU0_FIRMWARE_V1_0_NAME, sizeof(PRU0_FIRMWARE_V1_0_NAME))) { if(PRUICSS_pruWriteMemory(pruIcssHandle, PRU_ICSS_IRAM(1), 0, (uint32_t *) PRU1_FIRMWARE_V1_1_NAME, sizeof(PRU1_FIRMWARE_V1_1_NAME))) firmwareLoad_done = TRUE; } } #else if(PRUICSS_pruWriteMemory(pruIcssHandle,PRU_ICSS_IRAM(0) ,0, (uint32_t *) PRU0_FIRMWARE_NAME, sizeof(PRU0_FIRMWARE_NAME))) { if(PRUICSS_pruWriteMemory(pruIcssHandle,PRU_ICSS_IRAM(1) ,0, (uint32_t *) PRU1_FIRMWARE_NAME, sizeof(PRU1_FIRMWARE_NAME))) firmwareLoad_done = TRUE; } #endif if( firmwareLoad_done) { int32_t fbge = 5; fbge = PRUICSS_pruEnable(pruIcssHandle, ICSS_EMAC_PORT_1-1); System_printf("enable status 1: %d\n", fbge); fbge = PRUICSS_pruEnable(pruIcssHandle, ICSS_EMAC_PORT_2-1); System_printf("enable status 2: %d\n", fbge); } System_printf("sleeping 5 sec\n"); Task_sleep(5000); while (!(((ICSS_EmacObject*)emachandle->object)->linkStatus[0] | ((ICSS_EmacObject*)emachandle1->object)->linkStatus[0])) { System_printf("linkStatus 1: %d, linkstatus 2: %d\n", ((ICSS_EmacObject*)emachandle->object)->linkStatus[0], ((ICSS_EmacObject*)emachandle1->object)->linkStatus[0]); System_printf("taskPruss: link down\n"); Task_sleep(1000); // ((ICSS_EmacObject*)emachandle->object)->linkStatus[0] = 1; // ((ICSS_EmacObject*)emachandle1->object)->linkStatus[0] = 1; } System_printf("link is finally up \n"); ICSS_EmacRegisterHwIntRx(emachandle, (ICSS_EmacCallBack)testCallbackRxPacket); //ICSS_EmacRegisterHwIntRx(emachandle1, testCallbackRxPacket); } /** * @brief initialize PRU & ICSS_EMAC config parameters due to MMU in IPU * * @param none * * @retval none */ void initPruIcssEmacCfg() { uint32_t i; /* phys. to virt translation for prussInitCfg[0], [1]*/ for(i=0; i<sizeof(PRUICSS_HwAttrs)/2; i++) *((uint32_t *)prussInitCfg + i) += VIRT0; prussInitCfg[0].version = 0; prussInitCfg[1].version = 0; /* phys. to virt translation for ICSS_EmacBaseAddrCfgParams[0], [1]*/ for(i=0; i<sizeof(ICSS_EmacBaseAddrCfgParams)/2; i++) *((uint32_t *)icss_EmacBaseAddrCfgParams + i) += VIRT0; } PRUICSS_Handle PRUICSS_create1(PRUICSS_Config *config ,int32_t instance); PRUICSS_Handle PRUICSS_create1(PRUICSS_Config *config ,int32_t instance) { PRUICSS_Handle handle; PRUICSS_V1_Object *object; PRUICSS_HwAttrs const *hwAttrs; uint32_t temp_addr = 0U; uint32_t temp_val; handle = (PRUICSS_Config *)&config[instance-1]; hwAttrs = (PRUICSS_HwAttrs const *)handle->hwAttrs; object = (PRUICSS_V1_Object*)handle->object; object->instance = instance; // REVID register is offset by 0 in AM5728, // othervise you should put "CSL_ICSSCFG_REVID" temp_addr = (hwAttrs->prussCfgRegBase + 0/*CSL_ICSSCFG_REVID*/); temp_val = HWREG(temp_addr) & 0xFFFFU; object->pruicss_version = temp_val; return(&config[instance-1]); } /** * @brief PRU & ICSS_EMAC initialization * * @param none * * @retval 0: success * -1: rx semaphore creation failed * -2: rx task creation failed */ int pru_icss() { Error_Block eb; Task_Params taskParams; SemaphoreP_Params semParams; Error_init(&eb); initPruIcssEmacCfg(); pruIcssHandle = PRUICSS_create1((PRUICSS_Config *)pruss_config, PRUICCSS_INSTANCE_TWO); Task_Params_init(&taskParams); taskParams.priority = 15; taskParams.instance->name = "SwitchTask"; Task_create((Task_FuncPtr)taskPruss, &taskParams, &eb); /*ETH0 initializations*/ emachandle = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig)); ICSS_EmacInitConfig* switchEmacCfg; switchEmacCfg = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig)); switchEmacCfg->phyAddr[0] = 0; switchEmacCfg->portMask = ICSS_EMAC_MODE_MAC1; switchEmacCfg->ethPrioQueue = ICSS_EMAC_QUEUE1; /* Crosssbar confiiguration */ *(unsigned int*)(0x4A0027E8U + VIRT0) =(unsigned int)(0x00C400CA); *(unsigned int*)(0x4A0027ECU + VIRT0) =(unsigned int)(0x00CB00C5); switchEmacCfg->halfDuplexEnable = 1; switchEmacCfg->enableIntrPacing = ICSS_EMAC_ENABLE_PACING; switchEmacCfg->ICSS_EmacIntrPacingMode = ICSS_EMAC_INTR_PACING_MODE1; switchEmacCfg->pacingThreshold = 100; switchEmacCfg->learningEn = 0; SOCCtrlGetPortMacAddr(0,lclMac); switchEmacCfg->macId = lclMac; ICSSEmacDRVInit(emachandle, 2); switchEmacCfg->rxIntNum = 70; switchEmacCfg->linkIntNum = 69; ((ICSS_EmacObject*)emachandle->object)->pruIcssHandle = pruIcssHandle; ((ICSS_EmacObject*)emachandle->object)->emacInitcfg = switchEmacCfg; /*ETH1 initializations*/ emachandle1 = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig)); ICSS_EmacInitConfig* switchEmacCfg1; switchEmacCfg1 = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig)); switchEmacCfg1->phyAddr[0] = 1; switchEmacCfg1->portMask = ICSS_EMAC_MODE_MAC2; switchEmacCfg1->ethPrioQueue = ICSS_EMAC_QUEUE3; switchEmacCfg1->enableIntrPacing = ICSS_EMAC_DISABLE_PACING; switchEmacCfg1->pacingThreshold = 100; switchEmacCfg1->learningEn = 0; SOCCtrlGetPortMacAddr(1,lclMac1); switchEmacCfg1->macId = lclMac1; ICSSEmacDRVInit(emachandle1, 2); switchEmacCfg1->rxIntNum = 78; switchEmacCfg1->linkIntNum = 75; ((ICSS_EmacObject*)emachandle1->object)->pruIcssHandle = pruIcssHandle; ((ICSS_EmacObject*)emachandle1->object)->emacInitcfg = switchEmacCfg1; PRUICSS_IntcInitData pruss_intc_initdata = PRUSS_INTC_INITDATA; ICSS_EmacInit(emachandle,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC1); ICSS_EmacInit(emachandle1,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC2); Task_Params_init(&taskParams); taskParams.priority = 10; taskParams.instance->name = (char*)"port0_rxTaskFnc"; taskParams.stackSize = 0x1000; taskParams.arg0 = (UArg)emachandle; ((ICSS_EmacObject*)emachandle->object)->rxTaskHandle = Task_create(ICSS_EMacOsRxTaskFnc, &taskParams, NULL); if(((ICSS_EmacObject*)emachandle->object)->rxTaskHandle==NULL) return -2; Task_Params_init(&taskParams); taskParams.priority = 10; taskParams.instance->name = (char*)"port1_rxTaskFnc"; taskParams.stackSize = 0x1000; taskParams.arg0 = (UArg)emachandle1; ((ICSS_EmacObject*)emachandle1->object)->rxTaskHandle = Task_create(ICSS_EMacOsRxTaskFnc, &taskParams, NULL); if(((ICSS_EmacObject*)emachandle1->object)->rxTaskHandle==NULL) return -2; PRUICSS_pinMuxConfig(pruIcssHandle, 0x0); InterruptInit(emachandle); InterruptInit(emachandle1); EMACOpen(emachandle, 2); // EMACOpen(emachandle1, 2); EnableEMACInterrupts(emachandle); EnableEMACInterrupts(emachandle1); semParams.mode = SemaphoreP_Mode_COUNTING; semParams.name= "icss_rxSemaphore"; icssRxSem = SemaphoreP_create(0,&semParams);; if(icssRxSem == NULL) return -1; semParams.mode = SemaphoreP_Mode_COUNTING; semParams.name= "icss_rxSemaphore1"; icssRxSem1 = SemaphoreP_create(0,&semParams);; if(icssRxSem1 == NULL) return -1; System_printf("main_pruss: initialization done!\n"); return(0); } /** * @brief Get MAC address * * @param portNum: port number * pMacAddr: MAC address data pointer * * @retval none */ void SOCCtrlGetPortMacAddr(uint32_t portNum, uint8_t *pMacAddr) { if(portNum == 0) { pMacAddr[5U] = (VHW_RD_REG32(0x4A002514) >> 0U) & 0xFFU; pMacAddr[4U] = (VHW_RD_REG32(0x4A002514) >> 8U) & 0xFF; pMacAddr[3U] = (VHW_RD_REG32(0x4A002514) >> 16U) & 0xFFU; pMacAddr[2U] = (VHW_RD_REG32(0x4A002518) >> 0U) & 0xFFU; pMacAddr[1U] = (VHW_RD_REG32(0x4A002518) >> 8U) & 0xFFU; pMacAddr[0U] = (VHW_RD_REG32(0x4A002518) >> 16U) & 0xFFU; } else { pMacAddr[5U] = (VHW_RD_REG32(0x4A00251c) >> 0U) & 0xFFU; pMacAddr[4U] = (VHW_RD_REG32(0x4A00251c) >> 8U) & 0xFF; pMacAddr[3U] = (VHW_RD_REG32(0x4A00251c) >> 16U) & 0xFFU; pMacAddr[2U] = (VHW_RD_REG32(0x4A002520) >> 0U) & 0xFFU; pMacAddr[1U] = (VHW_RD_REG32(0x4A002520) >> 8U) & 0xFFU; pMacAddr[0U] = (VHW_RD_REG32(0x4A002520) >> 16U) & 0xFFU; } }
我们发现了一个可能的问题:
- 错误的 MAC 地址检索:函数 SOCCtrlGetPortMacAddr 返回不同的 MAC 地址,即 eth2和 eth3接口,并且始终是恒定的。 引导期间,端口1和端口2的 MAC 地址会随机初始化
[4.243312] prueth pruss2_eth:端口1:使用随机 MAC 地址:2E:7c:13:0c:A2:db
[4.308953] prueth pruss2_eth:端口1:使用随机 MAC 地址:92:5b:94:07:AC:08
[4.312874] prueth pruss2_eth:端口2:使用随机 MAC 地址:A6:07:29:C5:f3:12
[4.329570] prueth pruss2_eth:端口1:使用随机 MAC 地址:3A:B7:41:AB:21:A6
[4.341593] prueth pruss2_eth:端口2:使用随机 MAC 地址:8A:00:7d:2c:D9:76
在 SOCCtrlGetPortMacAddr 完成后,我们试图通过直接更改 lclMac 和 lclMac1强制随机分配的 MAC 地址,但链接仍然无法启动。
用于议会联盟的跟踪(添加 的链接状态1:0,链接状态2:0由我自己):
[0]启动任务 PRU-ICSS
[0][0.000]任务框架:将固件加载到 PG2.0 AM572x
[0]链接状态1:0,链接状态2:0
[0][5.000]任务栏:链接关闭
[0]链接状态1:0,链接状态2:0
等等...永远重复
必须补充:PRU 还可以,因为我们可以使用所有3个以太网端口(其中2个位于 PRU 内核上) ping 两个方向,并通过 SSH 连接到 am5728。只有使用以下固件才能实现这一点:
am57xx-pru0-prueth-fw.elf
am57xx-pru1-prueth-ffs.elf
因此,这必须与议会联盟<->PRU 部分有关