网络通讯的效果不必多说,而这次进行的作业便是对以太网通讯过程中,需求用到的硬件部分进行初始化,也介绍了发送和接纳数据的办法。
由于较为杂乱,所以运用了ASF结构。可是也会对用到的库函数的完结做一个介绍。
一、 MAC、PHY和MII
IEEE 802.3是现在常用的以太网规范,它界说了物理层(Physical Layer, PHY)和介质拜访操控层(Media Access Control, MAC)的规范。别的,在OSI模型中,MAC则处于数据链路层的底层。
而在硬件完结上,M4运用的GMAC外设完结了802.3中MAC的功用。开发板带着型号为KSZ8051MNL的PHY芯片以及RJ45接口则完结了物理层的功用:
MAC和PHY之间交互的接口则是介质独立接口(Media Independent Interface,MII)。MII包括一个数据通讯接口,以及一个办理接口(Management Data Input/Output ,MDIO)。由于PHY的接口是面向MAC的,所以咱们需求经过MAC来对PHY进行办理及数据交互。
别的,更早拟定的Ethernet II帧则是现在以太网传输中常运用的帧格局。
二、 GMAC的DMA缓冲区
GMAC运用了一个DMA接口。和M4的通用DMAC相同,它也能够主动进行屡次传输,可是方法略微有点差异。GMAC的DMA 对发送和接纳运用不同的缓冲区列表,而缓冲区描述符列表是一个数组,而不是DMAC所运用的链表。数组的开始方位保存在寄存器(GMAC_RBQB、GMAC_TBQB)中,且缓冲区描述符中有一个字段(Wrap)指示其是否为数组中的最终一个描述符。如接纳缓冲区:
在作业过程中,DMA会次序拜访每个缓冲区描述符,而在拜访最终一个描述符时,就会从头开始遍历。
关于接纳缓冲,列表中每一个缓冲区的长度是相同的,这个长度由DMA装备寄存器(GMAC_DCFGR)中的DRBS字段指定。在DMA将数据写入接纳缓冲时,也会设置描述符相应的字段,以标明每帧的开始与完毕;一起,也会标示相关的信息,如是否为播送帧等。
关于发送缓冲,其帧长度、是否需求增加CRC等操控信息也均在描述符中表明。在预备好数据后,向GMAC_NCR寄存器写入TSTART字段即可触发发送操作。
三、 运用ASF初始化GMAC
由于PHY是经过MAC拜访的,一切在设置PHY前要完结GMAC的设置。
GMAC约有94个寄存器,其间约有40个为计算寄存器,约15个寄存器与1588和PTP相关,约15个寄存器与特别地址和ID有关。别的,在有些状况寄存器中,需求向特定位写入1才会铲除该位的状况。
运用的ASF模块为Ethernet GMAC,然后conf_eth.h中能够设置MAC地址,IP地址,子网掩码,网关以及缓冲区巨细等参数。
然后调用gmac_dev_init( ) 函数即可对GMAC进行初始化:
pmc_enable_periph_clk(ID_GMAC);
// MAC地址
uint8_t mac_address[] =
{ ETHERNET_CONF_ETHADDR0, ETHERNET_CONF_ETHADDR1,
ETHERNET_CONF_ETHADDR2,ETHERNET_CONF_ETHADDR3,
ETHERNET_CONF_ETHADDR4, ETHERNET_CONF_ETHADDR5
};
// GMAC选项
gmac_options_t gmac_option;
gmac_option.uc_copy_all_frame = 0; // 不复制一切帧
gmac_option.uc_no_boardcast = 0; // 不疏忽播送
memcpy(gmac_option.uc_mac_addr,
mac_address, sizeof(mac_address)); //复制MAC地址
// GMAC驱动设置
gmac_device_t gmac_dev;
gs_gmac_dev.p_hw = GMAC; // 指定GMAC寄存器基址
// 初始化GMAC
gmac_dev_init(GMAC, &gmac_dev, &gmac_option);
gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev, gmac_options_t* p_opt) 函数完结了以下的作业:
禁用发送接纳,禁用GMAC一切中止;铲除计算寄存器,以及发送承受状况寄存器。
设置GMAC_NCFGR寄存器。依据p_opt,判别是否复制一切帧,以及是否疏忽播送。一起,追加GMAC_NCFGR_PEN 和 GMAC_NCFGR_IRXFCS位。(我觉得这儿应该是个BUG,从其注释判别需求追加的应该是GMAC_NCFGR_RFCS位)
设置好DMA缓冲,然后调用gmac_init_mem( ) 对缓冲区描述符等进行初始化。这个函数里也会使能发送和接纳,一起也会启用一系列的中止。设置完结后,DMA缓冲的信息将储存在p_gmac_dev中。
将MAC地址写入特别地址寄存器1。
四、 PHY的地址
在MDIO通讯过程中,每个PHY都会有一个4位的地址。而开发板带着的KSZ8051MNL芯片,能够在上电或复位时,依据引脚设置地址的低3位:
在开发板中,上电时PHYAD[2:0]的值为001,即其地址为0x1。
特别指出,地址0可作为该芯片的播送地址,而开发板也做了这样的装备。别的,在ASF中,过错地将PHY的地址界说成了0。这样能正确作业的原因仅是0为播送地址,而开发板只要一个PHY芯片。谨慎起见,将这个地址修改为正确的值:
#ifdef BOARD_GMAC_PHY_ADDR
#undef BOARD_GMAC_PHY_ADDR
#endif
#define BOARD_GMAC_PHY_ADDR 1
五、 在ASF中运用PHY
运用的模块为Ethernet Physical Transceiver。需求在conf_board.h 中声明宏:
/* 运用 ETH PHY: KSZ8051MNL */
#define CONF_BOARD_KSZ8051MNL
初始化。
在PHY上电后,需求等候一段时间让其运转安稳。之后就能够对其进行初始化了:
if (ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR,sysclk_get_cpu_hz())
!= GMAC_OK) {
puts("PHY Initialize ERROR!\r");
return -1;
}
在该ethernet_phy_init( ) 函数中,完结了以下作业:
设置MDIO的时钟MDC。
经过MDIO向PHY发送重置指令。
查看地址是否正确。查看的逻辑是先读取PHY的PHYID1的内容,再判别读出的内容是否正确。KSZ8051MNL芯片中,该寄存器的值是0x22。
假如地址无效的话,由于MDIO有用地址只要32个,就遍历这些地址。然后运用查看出的新地址从头发送一次重置指令。
假如初始化成功,则回来GMAC_OK。
自洽谈。
然后需求让PHY洽谈通讯速率、双工形式:
ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
if (ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 0)
!= GMAC_OK) {
puts("Set link ERROR!\r");
return -1;
}
ethernet_phy_auto_negotiate() 函数就会完结PHY的洽谈作业,然后依据洽谈的成果设置GMAC的速率、双工形式。ethernet_phy_set_link() 函数则会查看链路的状况,一起能够依据参数(第3个)运用PHY的自洽谈成果至GMAC中。
中止处理。
ASF的GMAC模块需求获取相关的中止,以进行相关的作业:如更新发送缓冲区描述符相关的信息,或是调用用户界说的回调函数等。
// 需求在NV%&&&&&%中启用相关中止
void GMAC_Handler(void)
{
gmac_handler(&gs_gmac_dev);
}
数据接纳。
先预备好一个缓冲,然后就能够调用gmac_dev_read() 读取出接纳到的帧的内容。
//#define GMAC_FRAME_LENTGH_MAX 1536
uint8_t eth_buffer[GMAC_FRAME_LENTGH_MAX];
uint32_t frm_size;
gmac_dev_read(&gmac_dev, (uint8_t *) eth_buffer,
sizeof(eth_buffer), &frm_size);
数据发送。
gmac_dev_write(&gmac_dev, (uint8_t *)eth_buffer, frm_size, NULL);
经过该函数即可运用GMAC发送数据,第4个参数是发送完结后的回调函数。该回调函数时是在gmac_handler() 中被调用的。