ARM硬件平台上基于UCOS移植Lwip网络协议栈
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = MyMacID[0];
netif->hwaddr[1] = MyMacID[1];
netif->hwaddr[2] = MyMacID[2];
netif->hwaddr[3] = MyMacID[3];
netif->hwaddr[4] = MyMacID[4];
netif->hwaddr[5] = MyMacID[5];
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
/* dont set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
/* Do whatever else is needed to initialize interface. */
board_eth_init();
}
netif结构体是协议栈内核对系统网络接口设备进行管理的重要数据结构,内核会为每个网络接口分配一个netif结构,用于描述接口属性。上面函数初始化了hwaddr、mtu、flag等关键属性域,并最后调用board_eth_init函数。
board_eth_init函数源代码如下:
void board_eth_init(void)
{
unsigned char i;
unsigned char j;
IODIR=IODIR|RSTDRV;
IOCLR=RSTDRV;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOSET=RSTDRV;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
IOCLR=RSTDRV;
for(i=0;i<200;i++)
{
for(j=0;j<200;j++);
}
NE_RESET = 0x12;
Delay(500);
NE_CR = ENCR_PAGE0 + ENCR_NODMA;
NE_DCR = NE_DCRVAL;
NE_RBCR0 = 0x00; /* MSB remote byte count reg */
NE_RBCR1 = 0x00; /* LSB remote byte count reg */
NE_TPSR = TX_START_PG;
NE_PSTART = RX_START_PG ; /* DMA START PAGE 46h */
NE_PSTOP = RX_STOP_PG; /* Ending page +1 of ring buffer */
NE_BNRY = RX_START_PG;/* Boundary page of ring buffer */
NE_RCR = ENRCR_RXCONFIG;
NE_TCR = ENTCR_TXCONFIG; /* xmit on. */
NE_ISR = 0xff; /* Individual bits are cleared by writing a "1" into it. */
NE_IMR = ENIMR_RX; // by Forrest..
NE_CR = ENCR_PAGE1 + ENCR_NODMA;
NE_PAR0 = MyMacID[0];
NE_PAR1 = MyMacID[1];
NE_PAR2 = MyMacID[2];
NE_PAR3 = MyMacID[3];
NE_PAR4 = MyMacID[4];
NE_PAR5 = MyMacID[5];
NE_MAR0 = 0xff;
NE_MAR1 = 0xff;
NE_MAR2 = 0xff;
NE_MAR3 = 0xff;
NE_MAR4 = 0xff;
NE_MAR5 = 0xff;
NE_MAR6 = 0xff;
NE_MAR7 = 0xff;
NE_CURR = RX_START_PG; /* RX_CURR_PG; Current memory page = RX_CURR_PG ? */
NE_CR = ENCR_PAGE0 + ENCR_NODMA + ENCR_START;
}
board_eth_init函数是保证网卡RTL8019AS正常工作的前提,它首先完成网卡的硬件复位,然后进行网卡的软件复位(往0X18端口写入任意值使其软复位),接着初始化网卡配置中的发送、接收缓冲区的页地址、配置了网卡发送配置寄存器、接收寄存器,最后设置网卡自身的物理地址和多播过滤地址。
low_level_output函数,上层应用层数据需要封装成协议栈要求的pbuf数据格式,然后再操作网卡发送数据。其源代码如下:
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
u8_t isr;
u8_t chain=0;
u8_t * tr_ptr;
u16_t tr_len, temp_dw;
u16_t padLength,packetLength;
/* Set up to transfer the packet contents to the NIC RAM. */
padLength = 0;
packetLength = p->tot_len;
/* packetLength muse >=64 (see 802.3) */
if ((p->tot_len) < 64)
{
padLength = 64 - (p->tot_len);
packetLength = 64;
}
/* dont close nic,just close receive interrupt */
NE_CR = ENCR_PAGE2 | ENCR_NODMA | ENCR_START;
isr = NE_IMR;
isr &= ~ENISR_RX;
NE_CR = ENCR_PAGE0 | ENCR_NODMA | ENCR_START;
NE_IMR = isr;
NE_ISR = ENISR_RDC;
/* Amount to send */
NE_RBCR0 = packetLength & 0xff;
NE_RBCR1 = packetLength >> 8;
/* Address on NIC to store */
NE_RSAR0 = 0x00;
NE_RSAR1 = NE_START_PG;
/* Write command to start */
NE_CR = ENCR_PAGE0 | ENCR_RWRITE | ENCR_START;
/* write packet to ring buffers. */
for(q = p, chain = 0; q != NULL; q = q->next)
{
if(chain == 1)
{
if(((q->len-1) & 0x01) && (q->next != NULL))
{
tr_len = q->len - 2;
tr_ptr = ((u8_t*)q->payload) + 1;
temp_dw = *(((u8_t *)q->payload) + q->len - 1);
temp_dw += *(u8_t *)(q->next->payload) < 8;
chain = 1;
}
else
{
tr_len = q->len - 1;
tr_ptr = ((u8_t*)q->payload) + 1;
chain = 0;
}
}
else
{
if((q->len & 0x01) && (q->next != NULL))
{
tr_len = q->len - 1;
tr_ptr = (u8_t*)q->payload;
temp_dw = *(((u8_t *)q->payload) + q->len - 1);
temp_dw += *(u8_t *)(q->next->payload) < 8;
ARM硬件平台UCOS移植网络协议 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)