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.

[参考译文] AM5728:处理器论坛

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1072956/am5728-processors-forum

部件号:AM5728

您好,

在鹅 肝转发( 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 部分有关