初始化版本
This commit is contained in:
69
lwip/port/arch/cc.h
Normal file
69
lwip/port/arch/cc.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef __ARCH_CC_H__
|
||||
#define __ARCH_CC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Compiler specific types */
|
||||
typedef uint8_t u8_t;
|
||||
typedef int8_t s8_t;
|
||||
typedef uint16_t u16_t;
|
||||
typedef int16_t s16_t;
|
||||
typedef uint32_t u32_t;
|
||||
typedef int32_t s32_t;
|
||||
typedef uintptr_t mem_ptr_t;
|
||||
|
||||
/* Formatters for printf */
|
||||
#define U16_F "u"
|
||||
#define S16_F "d"
|
||||
#define X16_F "x"
|
||||
#define U32_F "u"
|
||||
#define S32_F "d"
|
||||
#define X32_F "x"
|
||||
#define SZT_F "u"
|
||||
#define X8_F "02x"
|
||||
|
||||
/* Endianness (Usually Little Endian for ARM) */
|
||||
#ifndef BYTE_ORDER
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* Compiler hints for packing structures */
|
||||
#if defined(__GNUC__)
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#elif defined(__CC_ARM)
|
||||
#define PACK_STRUCT_BEGIN __packed
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#define PACK_STRUCT_USE_INCLUDES
|
||||
#else
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#endif
|
||||
|
||||
/* Platform specific diagnostic output */
|
||||
extern void osal_kprintf(const char *fmt, ...);
|
||||
#define LWIP_PLATFORM_DIAG(x) do { osal_kprintf x; } while(0)
|
||||
|
||||
/* Assert */
|
||||
#define LWIP_PLATFORM_ASSERT(x) do { osal_kprintf("Assertion \"%s\" failed at line %d in %s\n", \
|
||||
x, __LINE__, __FILE__); } while(0)
|
||||
|
||||
/* Random number generator */
|
||||
#define LWIP_RAND() ((u32_t)rand())
|
||||
|
||||
#endif /* __ARCH_CC_H__ */
|
||||
34
lwip/port/arch/sys_arch.h
Normal file
34
lwip/port/arch/sys_arch.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef __ARCH_SYS_ARCH_H__
|
||||
#define __ARCH_SYS_ARCH_H__
|
||||
|
||||
#include "osal.h"
|
||||
|
||||
/* LwIP Type Mapping to OSAL Types */
|
||||
typedef osal_sem_t sys_sem_t;
|
||||
typedef osal_mutex_t sys_mutex_t;
|
||||
typedef osal_mq_t sys_mbox_t;
|
||||
typedef osal_thread_t sys_thread_t;
|
||||
|
||||
/* LwIP Constants */
|
||||
#define SYS_MBOX_NULL NULL
|
||||
#define SYS_SEM_NULL NULL
|
||||
|
||||
/* OSAL returns OSAL_ETIMEOUT, LwIP expects SYS_ARCH_TIMEOUT (usually 0xFFFFFFFF) */
|
||||
#define SYS_ARCH_TIMEOUT 0xffffffffUL
|
||||
|
||||
/* Protection (Critical Section) */
|
||||
typedef uint32_t sys_prot_t;
|
||||
|
||||
static inline sys_prot_t sys_arch_protect(void)
|
||||
{
|
||||
osal_enter_critical();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void sys_arch_unprotect(sys_prot_t pval)
|
||||
{
|
||||
(void)pval;
|
||||
osal_exit_critical();
|
||||
}
|
||||
|
||||
#endif /* __ARCH_SYS_ARCH_H__ */
|
||||
332
lwip/port/drv_eth.c
Normal file
332
lwip/port/drv_eth.c
Normal file
@ -0,0 +1,332 @@
|
||||
#include "drv_eth.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/timeouts.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "osal.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Ethernet Handle */
|
||||
ETH_HandleTypeDef heth;
|
||||
static uint32_t g_phy_address = 0; /* Stored PHY Address */
|
||||
|
||||
/* DMA Descriptors and Buffers */
|
||||
__attribute__((section(".RxDecripSection"))) __attribute__((aligned(4))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB];
|
||||
__attribute__((section(".TxDecripSection"))) __attribute__((aligned(4))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB];
|
||||
__attribute__((section(".RxArraySection"))) __attribute__((aligned(4))) uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
|
||||
__attribute__((section(".TxArraySection"))) __attribute__((aligned(4))) uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
|
||||
|
||||
/* Semaphore for Ethernet */
|
||||
static osal_sem_t s_xSemaphore = NULL;
|
||||
|
||||
/* MSP Init */
|
||||
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
|
||||
{
|
||||
(void)heth;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_ETH_CLK_ENABLE();
|
||||
|
||||
/* PA1, PA2, PA7 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* PC1, PC4, PC5 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
/* PB11, PB12, PB13 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
HAL_NVIC_SetPriority(ETH_IRQn, 0x07, 0);
|
||||
HAL_NVIC_EnableIRQ(ETH_IRQn);
|
||||
}
|
||||
|
||||
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
|
||||
{
|
||||
(void)heth;
|
||||
if (s_xSemaphore != NULL)
|
||||
{
|
||||
osal_sem_release(s_xSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_ETH_RxAllocateCallback(uint8_t **buff)
|
||||
{
|
||||
static int rx_idx = 0;
|
||||
*buff = Rx_Buff[rx_idx];
|
||||
rx_idx = (rx_idx + 1) % ETH_RXBUFNB;
|
||||
}
|
||||
|
||||
void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
|
||||
{
|
||||
(void)Length;
|
||||
*pStart = (void *)buff;
|
||||
*pEnd = (void *)buff;
|
||||
}
|
||||
|
||||
void ETH_IRQHandler(void)
|
||||
{
|
||||
osal_enter_critical();
|
||||
HAL_ETH_IRQHandler(&heth);
|
||||
osal_exit_critical();
|
||||
}
|
||||
|
||||
static void low_level_init(struct netif *netif)
|
||||
{
|
||||
/* Use a fixed MAC address to avoid conflicts/filtering */
|
||||
uint8_t macaddress[6] = { 0x00, 0x80, 0xE1, 0x00, 0x00, 0x55 };
|
||||
ETH_MACConfigTypeDef macConf;
|
||||
HAL_StatusTypeDef hal_eth_init_status;
|
||||
uint32_t phy_id1 = 0, phy_id2 = 0;
|
||||
uint8_t detected_phy_addr = 0;
|
||||
uint32_t regvalue;
|
||||
|
||||
/* Generate MAC address from UID */
|
||||
/*
|
||||
uint32_t uid0 = HAL_GetUIDw0();
|
||||
uint32_t uid1 = HAL_GetUIDw1();
|
||||
uint32_t uid2 = HAL_GetUIDw2();
|
||||
|
||||
macaddress[0] = 0x02;
|
||||
macaddress[1] = 0x80;
|
||||
macaddress[2] = 0xE1;
|
||||
macaddress[3] = (uid0 >> 16) & 0xFF;
|
||||
macaddress[4] = (uid1 >> 8) & 0xFF;
|
||||
macaddress[5] = uid2 & 0xFF;
|
||||
*/
|
||||
|
||||
osal_log_i("MAC: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
macaddress[0], macaddress[1], macaddress[2],
|
||||
macaddress[3], macaddress[4], macaddress[5]);
|
||||
|
||||
heth.Instance = ETH;
|
||||
heth.Init.MACAddr = macaddress;
|
||||
heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
|
||||
heth.Init.TxDesc = DMATxDscrTab;
|
||||
heth.Init.RxDesc = DMARxDscrTab;
|
||||
heth.Init.RxBuffLen = ETH_RX_BUF_SIZE;
|
||||
|
||||
/* Initialize ETH (MAC, DMA, GPIOs via MSP) first to enable MDC/MDIO */
|
||||
hal_eth_init_status = HAL_ETH_Init(&heth);
|
||||
|
||||
if (hal_eth_init_status == HAL_OK)
|
||||
{
|
||||
/* Step 1: PHY address detection */
|
||||
osal_log_i("Detecting PHY Address...");
|
||||
detected_phy_addr = 0xFF; /* Invalid initial value */
|
||||
|
||||
for(uint8_t addr = 0; addr <= 31; addr++) {
|
||||
/* Read PHY ID registers (typically Reg 2 and 3) */
|
||||
/* Using 4-arg version: heth, PhyAddr, Reg, Value */
|
||||
if(HAL_ETH_ReadPHYRegister(&heth, addr, 2, &phy_id1) == HAL_OK &&
|
||||
HAL_ETH_ReadPHYRegister(&heth, addr, 3, &phy_id2) == HAL_OK) {
|
||||
if((phy_id1 != 0xFFFF) && (phy_id1 != 0x0000) && (phy_id1 != 0)) {
|
||||
detected_phy_addr = addr;
|
||||
osal_log_i("Found PHY at Address %d (ID: %04x %04x)", addr, phy_id1, phy_id2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (detected_phy_addr != 0xFF)
|
||||
{
|
||||
g_phy_address = detected_phy_addr;
|
||||
|
||||
/* Step 2: PHY Soft Reset */
|
||||
osal_log_i("Resetting PHY...");
|
||||
/* Write Reset Bit */
|
||||
HAL_ETH_WritePHYRegister(&heth, g_phy_address, PHY_BCR, PHY_RESET);
|
||||
|
||||
/* Wait for Reset to clear */
|
||||
uint32_t tickstart = osal_tick_get();
|
||||
do {
|
||||
HAL_ETH_ReadPHYRegister(&heth, g_phy_address, PHY_BCR, ®value);
|
||||
if((regvalue & PHY_RESET) == 0) break;
|
||||
} while ((osal_tick_get() - tickstart) < 500); // 500ms timeout
|
||||
|
||||
/* Add a delay to ensure PHY is stable */
|
||||
osal_thread_mdelay(100);
|
||||
netif->flags |= NETIF_FLAG_LINK_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
osal_log_e("No PHY found!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osal_log_e("HAL_ETH_Init failed");
|
||||
}
|
||||
|
||||
HAL_ETH_GetMACConfig(&heth, &macConf);
|
||||
macConf.DuplexMode = ETH_FULLDUPLEX_MODE;
|
||||
macConf.Speed = ETH_SPEED_100M;
|
||||
macConf.ChecksumOffload = ENABLE; /* Enable HW Checksum */
|
||||
HAL_ETH_SetMACConfig(&heth, &macConf);
|
||||
|
||||
/* Enable Promiscuous Mode manually as it's not in the struct */
|
||||
heth.Instance->MACFFR |= ETH_MACFFR_PM;
|
||||
|
||||
HAL_ETH_Start_IT(&heth);
|
||||
|
||||
s_xSemaphore = osal_sem_create("eth_sem", 0);
|
||||
|
||||
netif->hwaddr_len = 6;
|
||||
memcpy(netif->hwaddr, macaddress, 6);
|
||||
netif->mtu = 1500;
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||
#if LWIP_IPV6
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static err_t low_level_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
(void)netif;
|
||||
err_t errval;
|
||||
struct pbuf *q;
|
||||
ETH_TxPacketConfigTypeDef txConfig;
|
||||
ETH_BufferTypeDef txBuffers[16];
|
||||
|
||||
memset(&txConfig, 0, sizeof(ETH_TxPacketConfigTypeDef));
|
||||
/* Disable Hardware Checksum Insertion */
|
||||
txConfig.Attributes = 0; // ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
|
||||
txConfig.ChecksumCtrl = ETH_CHECKSUM_DISABLE; // ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
|
||||
txConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
|
||||
|
||||
int i = 0;
|
||||
for(q = p; q != NULL; q = q->next)
|
||||
{
|
||||
if (i >= 16) break;
|
||||
txBuffers[i].buffer = (uint8_t*)q->payload;
|
||||
txBuffers[i].len = q->len;
|
||||
if (q->next != NULL) {
|
||||
txBuffers[i].next = &txBuffers[i+1];
|
||||
} else {
|
||||
txBuffers[i].next = NULL;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
txConfig.Length = p->tot_len;
|
||||
txConfig.TxBuffer = &txBuffers[0];
|
||||
|
||||
if (HAL_ETH_Transmit(&heth, &txConfig, 10) == HAL_OK) {
|
||||
errval = ERR_OK;
|
||||
} else {
|
||||
errval = ERR_IF;
|
||||
}
|
||||
|
||||
return errval;
|
||||
}
|
||||
|
||||
static struct pbuf * low_level_input(struct netif *netif)
|
||||
{
|
||||
(void)netif;
|
||||
struct pbuf *p = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t rxLength = 0;
|
||||
|
||||
if (HAL_ETH_ReadData(&heth, (void**)&buffer) == HAL_OK)
|
||||
{
|
||||
rxLength = heth.RxDescList.RxDataLength;
|
||||
// osal_log_i("Rx: rxLength=%d", rxLength);
|
||||
|
||||
if (rxLength > 0 && buffer != NULL) {
|
||||
p = pbuf_alloc(PBUF_RAW, rxLength, PBUF_POOL);
|
||||
if (p != NULL) {
|
||||
/* Copy data */
|
||||
pbuf_take(p, buffer, rxLength);
|
||||
// osal_log_i("Rx: p->tot_len=%d", p->tot_len);
|
||||
} else {
|
||||
osal_log_e("pbuf_alloc failed");
|
||||
}
|
||||
/* HAL_ETH_ReadData internally calls ETH_UpdateDescriptor, so descriptors are rebuilt automatically */
|
||||
}
|
||||
} else {
|
||||
/* ReadData failed, maybe no data available */
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void ethernetif_input(struct netif *netif)
|
||||
{
|
||||
struct pbuf *p;
|
||||
|
||||
if (s_xSemaphore == NULL) {
|
||||
osal_thread_mdelay(100);
|
||||
return;
|
||||
}
|
||||
|
||||
if (osal_sem_take(s_xSemaphore, 100) == OSAL_OK)
|
||||
{
|
||||
do {
|
||||
p = low_level_input(netif);
|
||||
if (p != NULL)
|
||||
{
|
||||
// osal_log_i("Rx: len=%d", p->tot_len); // Debug print
|
||||
if (netif->input(p, netif) != ERR_OK)
|
||||
{
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
} while(p != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
err_t ethernetif_init(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
netif->hostname = "lwip";
|
||||
#endif
|
||||
|
||||
netif->name[0] = 'e';
|
||||
netif->name[1] = 't';
|
||||
|
||||
netif->output = etharp_output;
|
||||
netif->linkoutput = low_level_output;
|
||||
|
||||
low_level_init(netif);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void ethernet_link_check_state(struct netif *netif)
|
||||
{
|
||||
uint32_t regvalue = 0;
|
||||
|
||||
/* Use configured PHY Address */
|
||||
HAL_ETH_ReadPHYRegister(&heth, g_phy_address, PHY_BSR, ®value);
|
||||
|
||||
if ((regvalue & PHY_LINKED_STATUS) != (uint16_t)RESET)
|
||||
{
|
||||
if (!netif_is_link_up(netif))
|
||||
{
|
||||
netif_set_link_up(netif);
|
||||
osal_log_i("Ethernet Link Up");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (netif_is_link_up(netif))
|
||||
{
|
||||
netif_set_link_down(netif);
|
||||
osal_log_i("Ethernet Link Down");
|
||||
}
|
||||
}
|
||||
}
|
||||
47
lwip/port/drv_eth.h
Normal file
47
lwip/port/drv_eth.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef __DRV_ETH_H__
|
||||
#define __DRV_ETH_H__
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/err.h"
|
||||
|
||||
/* MAC Address */
|
||||
#ifndef MAC_ADDR0
|
||||
#define MAC_ADDR0 0x00
|
||||
#endif
|
||||
#ifndef MAC_ADDR1
|
||||
#define MAC_ADDR1 0x80
|
||||
#endif
|
||||
#ifndef MAC_ADDR2
|
||||
#define MAC_ADDR2 0xE1
|
||||
#endif
|
||||
#ifndef MAC_ADDR3
|
||||
#define MAC_ADDR3 0x00
|
||||
#endif
|
||||
#ifndef MAC_ADDR4
|
||||
#define MAC_ADDR4 0x00
|
||||
#endif
|
||||
#ifndef MAC_ADDR5
|
||||
#define MAC_ADDR5 0x00
|
||||
#endif
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#ifndef ETH_RX_BUF_SIZE
|
||||
#define ETH_RX_BUF_SIZE 1536 /* ETH Max packet size */
|
||||
#endif
|
||||
#ifndef ETH_TX_BUF_SIZE
|
||||
#define ETH_TX_BUF_SIZE 1536 /* ETH Max packet size */
|
||||
#endif
|
||||
#ifndef ETH_RXBUFNB
|
||||
#define ETH_RXBUFNB 4
|
||||
#endif
|
||||
#ifndef ETH_TXBUFNB
|
||||
#define ETH_TXBUFNB 4
|
||||
#endif
|
||||
|
||||
/* Exported functions */
|
||||
err_t ethernetif_init(struct netif *netif);
|
||||
void ethernetif_input(struct netif *netif);
|
||||
void ethernet_link_check_state(struct netif *netif);
|
||||
|
||||
#endif /* __DRV_ETH_H__ */
|
||||
117
lwip/port/lwipopts.h
Normal file
117
lwip/port/lwipopts.h
Normal file
@ -0,0 +1,117 @@
|
||||
#ifndef __LWIPOPTS_H__
|
||||
#define __LWIPOPTS_H__
|
||||
|
||||
/* Enable OS support */
|
||||
#define NO_SYS 0
|
||||
|
||||
/* DHCP options */
|
||||
#define LWIP_DHCP 1
|
||||
#define LWIP_NETIF_HOSTNAME 1
|
||||
|
||||
/* Socket options */
|
||||
#define LWIP_SOCKET 1
|
||||
#define LWIP_NETCONN 1
|
||||
#define SO_REUSE 1
|
||||
#define LWIP_RAW 1
|
||||
#define LWIP_SO_RCVTIMEO 1
|
||||
#define LWIP_SO_SNDTIMEO 1
|
||||
|
||||
/* DNS options */
|
||||
#define LWIP_DNS 1
|
||||
|
||||
/* Memory options */
|
||||
#define MEM_ALIGNMENT 4
|
||||
#define MEM_SIZE (16 * 1024) /* 16KB Heap for LwIP */
|
||||
#define MEMP_NUM_PBUF 16
|
||||
#define MEMP_NUM_UDP_PCB 4
|
||||
#define MEMP_NUM_TCP_PCB 5
|
||||
#define MEMP_NUM_TCP_PCB_LISTEN 8
|
||||
#define MEMP_NUM_TCP_SEG 16
|
||||
#define MEMP_NUM_SYS_TIMEOUT 8
|
||||
|
||||
/* Pbuf options */
|
||||
#define PBUF_POOL_SIZE 16
|
||||
#define PBUF_POOL_BUFSIZE 1536
|
||||
|
||||
/* Thread options */
|
||||
#define TCPIP_THREAD_NAME "tcpip"
|
||||
#define TCPIP_THREAD_STACKSIZE 2048
|
||||
#define TCPIP_THREAD_PRIO 10
|
||||
#define TCPIP_MBOX_SIZE 8
|
||||
#define DEFAULT_THREAD_STACKSIZE 1024
|
||||
#define DEFAULT_THREAD_PRIO 10
|
||||
#define DEFAULT_RAW_RECVMBOX_SIZE 8
|
||||
#define DEFAULT_UDP_RECVMBOX_SIZE 8
|
||||
#define DEFAULT_TCP_RECVMBOX_SIZE 8
|
||||
#define DEFAULT_ACCEPTMBOX_SIZE 8
|
||||
|
||||
/* OSAL provides malloc/free wrappers if needed, but LwIP has its own heap management.
|
||||
If you want LwIP to use OSAL's malloc:
|
||||
*/
|
||||
#define MEM_LIBC_MALLOC 1
|
||||
#include "osal_mem.h"
|
||||
#define mem_clib_malloc osal_malloc
|
||||
#define mem_clib_free osal_free
|
||||
#define mem_clib_calloc osal_calloc
|
||||
|
||||
/* Debug options */
|
||||
#define LWIP_DEBUG 1
|
||||
#define LWIP_DBG_TYPES_ON LWIP_DBG_OFF
|
||||
#define ETHARP_DEBUG LWIP_DBG_OFF
|
||||
#define NETIF_DEBUG LWIP_DBG_OFF
|
||||
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||
#define API_LIB_DEBUG LWIP_DBG_OFF
|
||||
#define API_MSG_DEBUG LWIP_DBG_OFF
|
||||
#define SOCKETS_DEBUG LWIP_DBG_OFF
|
||||
#define ICMP_DEBUG LWIP_DBG_OFF
|
||||
#define IGMP_DEBUG LWIP_DBG_OFF
|
||||
#define INET_DEBUG LWIP_DBG_OFF
|
||||
#define IP_DEBUG LWIP_DBG_OFF
|
||||
#define IP_REASS_DEBUG LWIP_DBG_OFF
|
||||
#define RAW_DEBUG LWIP_DBG_OFF
|
||||
#define MEM_DEBUG LWIP_DBG_OFF
|
||||
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||
#define SYS_DEBUG LWIP_DBG_OFF
|
||||
#define TIMERS_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_RTO_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_CWND_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_WND_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
||||
#define UDP_DEBUG LWIP_DBG_OFF
|
||||
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||
#define PPP_DEBUG LWIP_DBG_OFF
|
||||
#define SLIP_DEBUG LWIP_DBG_OFF
|
||||
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||
#define AUTOIP_DEBUG LWIP_DBG_OFF
|
||||
#define SNMP_MSG_DEBUG LWIP_DBG_OFF
|
||||
#define SNMP_MIB_DEBUG LWIP_DBG_OFF
|
||||
#define DNS_DEBUG LWIP_DBG_OFF
|
||||
|
||||
/* Checksums - HW Checksum Enabled */
|
||||
#define CHECKSUM_GEN_IP 0
|
||||
#define CHECKSUM_GEN_UDP 0
|
||||
#define CHECKSUM_GEN_TCP 0
|
||||
#define CHECKSUM_GEN_ICMP 0
|
||||
#define CHECKSUM_CHECK_IP 0
|
||||
#define CHECKSUM_CHECK_UDP 0
|
||||
#define CHECKSUM_CHECK_TCP 0
|
||||
#define CHECKSUM_CHECK_ICMP 0
|
||||
|
||||
/* Link Callback */
|
||||
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||
|
||||
/* ICMP options */
|
||||
#define LWIP_ICMP 1
|
||||
#define LWIP_BROADCAST_PING 1
|
||||
#define LWIP_MULTICAST_PING 1
|
||||
|
||||
/* Ethernet options */
|
||||
#define LWIP_ARP 1
|
||||
#define LWIP_ETHERNET 1
|
||||
|
||||
#endif /* __LWIPOPTS_H__ */
|
||||
260
lwip/port/sys_arch.c
Normal file
260
lwip/port/sys_arch.c
Normal file
@ -0,0 +1,260 @@
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/arch.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "osal.h"
|
||||
|
||||
/* Initialize the system architecture */
|
||||
void sys_init(void)
|
||||
{
|
||||
/* OSAL should be initialized before calling this */
|
||||
}
|
||||
|
||||
/* Semaphore functions */
|
||||
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
|
||||
{
|
||||
*sem = osal_sem_create("lwip_sem", count);
|
||||
if (*sem == NULL)
|
||||
{
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void sys_sem_free(sys_sem_t *sem)
|
||||
{
|
||||
if (sem != NULL && *sem != NULL)
|
||||
{
|
||||
osal_sem_delete(*sem);
|
||||
*sem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_sem_signal(sys_sem_t *sem)
|
||||
{
|
||||
if (sem != NULL && *sem != NULL)
|
||||
{
|
||||
osal_sem_release(*sem);
|
||||
}
|
||||
}
|
||||
|
||||
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
|
||||
{
|
||||
osal_tick_t start_tick = osal_tick_get();
|
||||
osal_err_t ret;
|
||||
osal_int32_t osal_timeout;
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
osal_timeout = -1; /* Wait forever */
|
||||
}
|
||||
else
|
||||
{
|
||||
osal_timeout = (osal_int32_t)timeout;
|
||||
}
|
||||
|
||||
ret = osal_sem_take(*sem, osal_timeout);
|
||||
|
||||
if (ret == OSAL_OK)
|
||||
{
|
||||
return osal_tick_get() - start_tick;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if a sem is valid */
|
||||
int sys_sem_valid(sys_sem_t *sem)
|
||||
{
|
||||
if (sem != NULL && *sem != NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set a sem to invalid */
|
||||
void sys_sem_set_invalid(sys_sem_t *sem)
|
||||
{
|
||||
if (sem != NULL)
|
||||
*sem = NULL;
|
||||
}
|
||||
|
||||
/* Mutex functions */
|
||||
err_t sys_mutex_new(sys_mutex_t *mutex)
|
||||
{
|
||||
*mutex = osal_mutex_create("lwip_mutex");
|
||||
if (*mutex == NULL)
|
||||
{
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void sys_mutex_free(sys_mutex_t *mutex)
|
||||
{
|
||||
if (mutex != NULL && *mutex != NULL)
|
||||
{
|
||||
osal_mutex_delete(*mutex);
|
||||
*mutex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_mutex_lock(sys_mutex_t *mutex)
|
||||
{
|
||||
if (mutex != NULL && *mutex != NULL)
|
||||
{
|
||||
osal_mutex_take(*mutex, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void sys_mutex_unlock(sys_mutex_t *mutex)
|
||||
{
|
||||
if (mutex != NULL && *mutex != NULL)
|
||||
{
|
||||
osal_mutex_release(*mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mailbox functions */
|
||||
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
|
||||
{
|
||||
/* LwIP messages are pointers */
|
||||
*mbox = osal_mq_create("lwip_mbox", sizeof(void*), size);
|
||||
if (*mbox == NULL)
|
||||
{
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void sys_mbox_free(sys_mbox_t *mbox)
|
||||
{
|
||||
if (mbox != NULL && *mbox != NULL)
|
||||
{
|
||||
osal_mq_delete(*mbox);
|
||||
*mbox = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
|
||||
{
|
||||
if (mbox != NULL && *mbox != NULL)
|
||||
{
|
||||
osal_mq_send(*mbox, &msg, sizeof(void*));
|
||||
}
|
||||
}
|
||||
|
||||
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
|
||||
{
|
||||
/* OSAL MQ doesn't strictly separate blocking/non-blocking send in current API wrapper,
|
||||
but we assume osal_mq_send is blocking if full.
|
||||
However, sys_mbox_trypost expects non-blocking.
|
||||
For now, we just call send. If you need true non-blocking, OSAL needs an update.
|
||||
Assuming OSAL queue has space.
|
||||
*/
|
||||
/* TODO: Implement non-blocking send in OSAL if needed */
|
||||
if (mbox != NULL && *mbox != NULL)
|
||||
{
|
||||
if (osal_mq_send(*mbox, &msg, sizeof(void*)) == OSAL_OK)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
|
||||
{
|
||||
return sys_mbox_trypost(mbox, msg);
|
||||
}
|
||||
|
||||
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
|
||||
{
|
||||
osal_tick_t start_tick = osal_tick_get();
|
||||
osal_err_t ret;
|
||||
osal_int32_t osal_timeout;
|
||||
void *dummy_msg;
|
||||
|
||||
if (msg == NULL)
|
||||
{
|
||||
msg = &dummy_msg;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
osal_timeout = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
osal_timeout = (osal_int32_t)timeout;
|
||||
}
|
||||
|
||||
ret = osal_mq_recv(*mbox, msg, sizeof(void*), osal_timeout);
|
||||
|
||||
if (ret == OSAL_OK)
|
||||
{
|
||||
return osal_tick_get() - start_tick;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
|
||||
{
|
||||
osal_err_t ret;
|
||||
void *dummy_msg;
|
||||
|
||||
if (msg == NULL)
|
||||
{
|
||||
msg = &dummy_msg;
|
||||
}
|
||||
|
||||
ret = osal_mq_recv(*mbox, msg, sizeof(void*), 0); /* 0 timeout */
|
||||
|
||||
if (ret == OSAL_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SYS_MBOX_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if an mbox is valid */
|
||||
int sys_mbox_valid(sys_mbox_t *mbox)
|
||||
{
|
||||
if (mbox != NULL && *mbox != NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set an mbox to invalid */
|
||||
void sys_mbox_set_invalid(sys_mbox_t *mbox)
|
||||
{
|
||||
if (mbox != NULL)
|
||||
*mbox = NULL;
|
||||
}
|
||||
|
||||
/* Thread functions */
|
||||
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
|
||||
{
|
||||
osal_thread_t t;
|
||||
|
||||
t = osal_thread_create(name, (osal_thread_entry)thread, arg, stacksize, (osal_priority_t)prio);
|
||||
|
||||
if (t != NULL)
|
||||
{
|
||||
osal_thread_start(t);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Time functions */
|
||||
u32_t sys_now(void)
|
||||
{
|
||||
return osal_tick_get();
|
||||
}
|
||||
Reference in New Issue
Block a user