最近在移植 niche stack 网络协议栈,用的操作系统是 ucos ii ,硬件平台是 NUCLEO H743ZI遇到了一些问题请教一下各位。
现象:用ATKKPING 做PING测试。按下复位键
单片机开始运行,PING时间<1ms,过了一会就会PING不通,或者PING延时非常高。以上是在我去掉 FTP 、TELNET、 PINGAPP 等一些无关任务后做的测试。附件是我用 SYSTEM VIEW 抓到的数据。
我也移植到了FREERTOS下但是也遇到了相似问题,所以回到Ucos 下。
下面是我的的 时钟、 MPU、 ETHDSC、接收 发送、 关键代码。
时钟:
void BSP_ClkInit (void)
{
RCC_ClkInitTypeDef RCC_ClkInit;
RCC_OscInitTypeDef RCC_OscInit;
RCC_PeriphCLKInitTypeDefPeriphClkInitStruct;
PWR->CR3 = ~PWR_CR3_SCUEN;
/* Supplyconfiguration updated locked. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* See Note 2. */
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)){
;
}
/* Enable D2 domainSRAM3 Clock (0x30040000 AXI)*/
__HAL_RCC_D2SRAM3_CLK_ENABLE();
/* Enable D2 domainSRAM2 Clock (0x30020000 AXI)*/
__HAL_RCC_D2SRAM2_CLK_ENABLE();
/* Enable HSE Osc and activate PLL with HSE as source */
RCC_OscInit.OscillatorType =RCC_OSCILLATORTYPE_HSE; /* HSE = 8MHz */
RCC_OscInit.HSEState = RCC_HSE_BYPASS;
RCC_OscInit.HSIState = RCC_HSI_OFF;
RCC_OscInit.CSIState = RCC_CSI_OFF;
RCC_OscInit.PLL.PLLState = RCC_PLL_ON;
RCC_OscInit.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInit.PLL.PLLM = 4u; /*f(REF_CK) = HSE / PLLM = 2MHz */
RCC_OscInit.PLL.PLLN = 400u; /* f(VCO clock)= f(REF_CK) * PLLN = 800MHz */
RCC_OscInit.PLL.PLLP = 2u; /* PLL(PCLK) = f(VCO clock) / PLLR =400MHz */
RCC_OscInit.PLL.PLLR = 2u; /* PLL(RCLK) = f(VCO clock) / PLLR =400MHz */
RCC_OscInit.PLL.PLLQ = 4u; /* PLL(QCLK) = f(VCO clock) / PLLQ =200MHz */
RCC_OscInit.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInit.PLL.PLLRGE =RCC_PLL1VCIRANGE_2;
if (HAL_RCC_OscConfig( RCC_OscInit) != HAL_OK) {
while(1u); /* STOP iferror */
}
/* ----- CFG SYSCLK SOURCE AND BUS CLOCK DIVIDERS ----- */
RCC_ClkInit.ClockType =(RCC_CLOCKTYPE_SYSCLK |
RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_D1PCLK1 |
RCC_CLOCKTYPE_PCLK1 |
RCC_CLOCKTYPE_PCLK2 |
RCC_CLOCKTYPE_D3PCLK1);
RCC_ClkInit.SYSCLKSource =RCC_SYSCLKSOURCE_PLLCLK; /* Select PLL assystem clock source. */
RCC_ClkInit.SYSCLKDivider =RCC_SYSCLK_DIV1; /* SYSCLK = PLL(P CLK) = 400MHz */
RCC_ClkInit.AHBCLKDivider =RCC_HCLK_DIV2; /* HCLK = AHBxCLK = SYSCLK / AHBPRES(2) =200MHz. */
RCC_ClkInit.APB3CLKDivider =RCC_APB3_DIV2; /* APB3CLK =AHB3CLK / APB3DIV(2) =100MHz. */
RCC_ClkInit.APB1CLKDivider =RCC_APB1_DIV2; /* APB1CLK =AHB1CLK / APB1DIV(2) =100MHz. */
RCC_ClkInit.APB2CLKDivider =RCC_APB2_DIV2; /* APB2CLK =AHB2CLK / APB2DIV(2) =100MHz. */
RCC_ClkInit.APB4CLKDivider =RCC_APB4_DIV2; /* APB2CLK =AHB4CLK / APB4DIV(2) =100MHz. */
if (HAL_RCC_ClockConfig( RCC_ClkInit,FLASH_LATENCY_4) != HAL_OK) {
while(1u); /* STOP iferror */
}
PeriphClkInitStruct.PeriphClockSelection =RCC_PERIPHCLK_USART3;
PeriphClkInitStruct.Usart234578ClockSelection =RCC_USART234578CLKSOURCE_D2PCLK1;
if (HAL_RCCEx_PeriphCLKConfig( PeriphClkInitStruct)!= HAL_OK) {
while(1u); /* STOP iferror */
}
__HAL_RCC_CSI_ENABLE(); /* activate CSI clkmondatory for I/O Compensation Cell */
__HAL_RCC_SYSCFG_CLK_ENABLE(); /* Enable SYSCFGclk mondatory for I/O Compensation Cell*/
HAL_EnableCompensationCell(); /* Enables theI/O Compensation Cell */
}
MPU:
/**
* @brief Configure the MPU attributes
* @param None
* @retval None
*/
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes asDevice not cacheable
for ETH DMA descriptors */
MPU_InitStruct.Enable =MPU_REGION_ENABLE; //区域使能/禁止
MPU_InitStruct.BaseAddress = 0x30040000; //配置区域基地址
MPU_InitStruct.Size =MPU_REGION_SIZE_256B; //区域容量
MPU_InitStruct.AccessPermission =MPU_REGION_FULL_ACCESS; //设置访问权限
MPU_InitStruct.IsBufferable =MPU_ACCESS_BUFFERABLE; //禁止/允许缓冲
MPU_InitStruct.IsCacheable =MPU_ACCESS_NOT_CACHEABLE; //禁止/允许缓存
MPU_InitStruct.IsShareable =MPU_ACCESS_NOT_SHAREABLE; //禁止/允许共享
MPU_InitStruct.Number = MPU_REGION_NUMBER0; //区域编号
MPU_InitStruct.TypeExtField =MPU_TEX_LEVEL0; //类型扩展级别
MPU_InitStruct.SubRegionDisable = 0x00; //子 region 除能位段设置
MPU_InitStruct.DisableExec =MPU_INSTRUCTION_ACCESS_ENABLE; //允许/禁止取指
HAL_MPU_ConfigRegion( MPU_InitStruct);
/* Configure the MPU attributes asCacheable write through */
MPU_InitStruct.Enable =MPU_REGION_ENABLE; //区域使能/禁止
MPU_InitStruct.BaseAddress = 0x30020000; //配置区域基地址
MPU_InitStruct.Size =MPU_REGION_SIZE_128KB; //区域容量
MPU_InitStruct.AccessPermission =MPU_REGION_FULL_ACCESS; //设置访问权限
MPU_InitStruct.IsBufferable =MPU_ACCESS_NOT_BUFFERABLE; //禁止/允许缓冲
MPU_InitStruct.IsCacheable =MPU_ACCESS_CACHEABLE; //禁止/允许缓存
MPU_InitStruct.IsShareable =MPU_ACCESS_NOT_SHAREABLE; //禁止/允许共享
MPU_InitStruct.Number =MPU_REGION_NUMBER1; //区域编号
MPU_InitStruct.TypeExtField =MPU_TEX_LEVEL0; //类型扩展级别
MPU_InitStruct.SubRegionDisable = 0x00; //子 region 除能位段设置
MPU_InitStruct.DisableExec =MPU_INSTRUCTION_ACCESS_ENABLE; //允许/禁止取指
HAL_MPU_ConfigRegion( MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
ETH DSC
#pragma location=0x30040000
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet RxDMA Descriptors */
#pragma location=0x30040060
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet TxDMA Descriptors */
#pragma location=0x30040200
uint8_tRx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet ReceiveBuffers */
RX
void EthifTask (void *p_arg)
{
(void)p_arg;
ETH_BufferTypeDef RxBuff;
uint32_t framelength = 0;
CPU_INT08U err;
for (;;)
{
OSSemPend(RxPktSemaphore, 0, err);
if ((err != OS_NONE_ERR) (err != OS_SEM_TIMEOUT))
dtrap();
if (HAL_ETH_GetRxDataBuffer( EthHandle, RxBuff) == HAL_OK)
{
HAL_ETH_GetRxDataLength( EthHandle, framelength);
/* Invalidate datacache for ETH Rx Buffers */
SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff,(ETH_RX_DESC_CNT * ETH_RX_BUFFER_SIZE));
if (current_pbuf_idx <(ETH_RX_DESC_CNT - 1))
{
current_pbuf_idx++;
}
else
{
current_pbuf_idx = 0;
}
}
#ifdef ALT_INICHE
#ifdef SYSTEM_VIEW
SEGGER_SYSVIEW_PrintfHostEx("ETH Rcv RxPkt",SEGGER_SYSVIEW_LOG);
#endif
input_ippkt(RxBuff.buffer, framelength);
#endif
/* Build Rxdescriptor to be ready for next data reception */
HAL_ETH_BuildRxDescriptors( EthHandle);
}
}
TX
int8_t ETH_SendTxPkt(uint8_t *buffer, uint32_t len)
{
int8_t errval = HAL_OK;
ETH_BufferTypeDef *Txbuffer = NULL;
memset(Txbuffer, 0, sizeof(ETH_BufferTypeDef));
Txbuffer->buffer = buffer;
Txbuffer->len = len;
Txbuffer->next = NULL;
TxConfig.Length = len;
TxConfig.TxBuffer = Txbuffer;
#ifdef SYSTEM_VIEW
SEGGER_SYSVIEW_PrintfHostEx("ETH SendTx Pkt",SEGGER_SYSVIEW_LOG);
#endif
errval = HAL_ETH_Transmit( EthHandle, TxConfig, 0);
return errval;
}