將TCPIP_STACK_DRAM_SIZE調來調去,還是串口信息報錯
TCP/IP Stack: HHeap creation failed, type: 1
錯誤代碼"type: 1"對應的是TCPIP_STACK_HEAP_TYPE_INTERNAL_HEAP,
而實際的錯誤是TCPIP_STACK_HEAP_RES_SYNCH_ERR
查看代碼發現,在TCP/IP堆創建過程中,會調用OSAL_SEM_Create創建一個信號量用於同步訪問堆:
if(OSAL_SEM_Create(&hDcpt->_heapSemaphore, OSAL_SEM_TYPE_BINARY, 1, 1) != OSAL_RESULT_TRUE)
{
(*pHeapConfig->free_fnc)(allocatedHeapBuffer);
hInst = 0;
res = TCPIP_STACK_HEAP_RES_SYNCH_ERR;
break;
}
根據配置文件FreeRTOSConfig.h中的設置,增大系統配置的堆大小。
#define configTOTAL_HEAP_SIZE ( ( size_t ) 40960 )
但是調大了也沒用。最後發現跟大小沒關係,我是反覆鞭策ai找到了原因。
因為目前TCP/IP堆使用的是標準C庫的malloc/free函數:
#define TCPIP_STACK_MALLOC_FUNC malloc
#define TCPIP_STACK_FREE_FUNC free
但在FreeRTOS環境中,更好的選擇是使用FreeRTOS的內存管理函數pvPortMalloc/vPortFree,這已經在OSAL中封裝為OSAL_Malloc/OSAL_Free。
所以要修改TCP/IP堆使用的內存分配函數,從標準C庫的malloc/free改為使用OSAL提供的OSAL_Malloc/OSAL_Free
#define TCPIP_STACK_MALLOC_FUNC OSAL_Malloc
#define TCPIP_STACK_FREE_FUNC OSAL_Free
因為在FreeRTOS環境中:
標準C庫的malloc/free可能與RTOS的內存管理不兼容
OSAL提供的內存分配函數(OSAL_Malloc/OSAL_Free)專門針對FreeRTOS環境進行了優化
這些函數內部使用FreeRTOS的pvPortMalloc/vPortFree,與RTOS的內存管理機制完全兼容
這個方法確實成功創建了tcp的heap,成功過了這一步初始化。但是我回頭看了下網絡例程裏用到了rtos的例程是怎麼配置的configuration的,發現人家例程就沒這麼改。暫時擱置,先用我自己的方法跑通。誰讓這個mhc配置的代碼自己都沒法初始化。
接下來馬上就遇到了DRV_PHY operation error: -2 DRV PHY init failed: -2 ,
可以的,雖然是巧合,但是剛好到error 2 。錯誤代碼-2對應的是DRV_ETHPHY_RES_DTCT_TMO,即PHY檢測超時。
説明預期時間內沒發現設備。在設置超時的宏隔壁就找到了與例程不一樣的配置,
#define DRV_ETHPHY_KSZ8081_RESET_CLR_TMO 500
#define DRV_KSZ8081_PHY_ADDRESS 1//應該為0
只要把1改成0就行了。大概是因為這個ksz8081對應的應該是emac0.這個開發板只有一個emac。
error 1和2解決了,下一個是 DRV_PHY operation error: -4 DRV PHY init failed: -4 。很好的考公數字推理[doge]
錯誤碼-4對應的是DRV_ETHPHY_RES_CFG_ERR,表示硬件配置與請求的模式不匹配。
分析發現:
EMAC0配置為RMII模式(DRV_EMAC0_RMII_MODE = 1)
ksz8081 PHY也配置為RMII接口(KSZ8081RNB = 1)
但是PHY配置標誌DRV_KSZ8081_PHY_CONFIG_FLAGS設置為0,沒有明確指定接口模式
#define DRV_KSZ8081_PHY_CONFIG_FLAGS ( 0 \
| DRV_ETHPHY_CFG_RMII \
)
所以加上DRV_ETHPHY_CFG_RMII就ok。
總算是初始化成功了。而且都是驅動沒有自動配置好的原因。挺好,讓我多瞭解一下底層細節。。