当前位置:文档之家› STM32F103驱动W5500网络程序

STM32F103驱动W5500网络程序

STM32F103驱动W5500网络程序
STM32F103驱动W5500网络程序

#include "W5500.h"

/***************----- 网络参数变量定义-----***************/

unsigned char Gateway_IP[4];//网关IP地址

unsigned char Sub_Mask[4]; //子网掩码

unsigned char Phy_Addr[6]; //物理地址(MAC)

unsigned char IP_Addr[4]; //本机IP地址

unsigned char S0_Port[2]; //端口0的端口号(5000)

unsigned char S0_DIP[4]; //端口0目的IP地址

unsigned char S0_DPort[2]; //端口0目的端口号(6000)

unsigned char UDP_DIPR[4]; //UDP(广播)模式,目的主机IP地址

unsigned char UDP_DPORT[2]; //UDP(广播)模式,目的主机端口号

/***************----- 端口的运行模式-----***************/

unsigned char S0_Mode =3; //端口0的运行模式,0:TCP服务器模式,1:TCP客户端模式,2:UDP(广播)模式

#define TCP_SERVER 0x00 //TCP服务器模式

#define TCP_CLIENT 0x01 //TCP客户端模式

#define UDP_MODE 0x02 //UDP(广播)模式

/***************----- 端口的运行状态-----***************/

unsigned char S0_State =0; //端口0状态记录,1:端口完成初始化,2端口完成连接(可以正常传输数据)

#define S_INIT 0x01 //端口完成初始化

#define S_CONN 0x02 //端口完成连接,可以正常传输数据

/***************----- 端口收发数据的状态-----***************/

unsigned char S0_Data; //端口0接收和发送数据的状态,1:端口接收到数据,2:端口发送数据完成

#define S_RECEIVE 0x01 //端口接收到一个数据包

#define S_TRANSMITOK 0x02 //端口发送一个数据包完成

/***************----- 端口数据缓冲区-----***************/

unsigned char Rx_Buffer[2048]; //端口接收数据缓冲区

unsigned char Tx_Buffer[2048]; //端口发送数据缓冲区

unsigned char W5500_Interrupt; //W5500中断标志(0:无中断,1:有中断)

/*外部中断4服务程序*/

void EXTI4_IRQHandler(void)

{

if(W5500_INT==0)

{

W5500_Interrupt=1;

EXTI->PR=1<<4; //清除LINE4上的中断标志位

}

}

void SPI1_Init(void)

{

RCC->APB2ENR|=1<<2; //PORTA时钟使能

RCC->APB2ENR|=1<<12; //SPI1时钟使能

RCC->APB2ENR|=1<<0;

GPIOA->CRL&=0XFFF0FFFF;

GPIOA->CRL|=0X00030000;//PA4通用挽推输出,输出速度50MHz

GPIOA->ODR|=1<<4; //PA4上拉,设置片选引脚

//这里只针对SPI口初始化

GPIOA->CRL&=0X000FFFFF;

GPIOA->CRL|=0XBBB00000;//PA5.6.7复用功能挽推输出,输出速度50MHz

GPIOA->ODR|=0X7<<5; //PA5.6.7上拉

SPI1->CR1&=~(1<<10);//全双工模式

SPI1->CR1=1<<9; //外部管理NSS引脚

SPI1->CR1&=~(1<<11);//8bit数据格式

SPI1->CR1&=~(1<<1); //CPOL=0时空闲模式下SCK为0 CPOL=0

SPI1->CR1&=~(1<<0); //数据采样从第一个时间边沿开始,CPHA=0

SPI1->CR1|=1<<8;

SPI1->CR1|=1<<2; //SPI主机

SPI1->CR1|=0<<3; //Fsck=Fcpu/2

SPI1->CR1&=~(1<<7); //MSBfirst先发送高位

SPI1->CRCPR = 0X07;

SPI1->CR1|=1<<6; //SPI设备使能

}

/****************************************************************************** *

* 函数名: W5500_GPIO_Configuration

* 描述: W5500 GPIO初始化配置

* 输入: 无

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void W5500_GPIO_Configuration(void)

{

RCC->APB2ENR|=1<<4; //PORTC时钟使能

GPIOC->CRL&=0XFF00FFFF;

GPIOC->CRL|=0X00380000;

GPIOC->ODR|=3<<4; //PC4上拉,PC5输出高

SPI1_Init();

Ex_NVIC_Config(GPIO_C,4,FTIR); //下降沿触发

MY_NVIC_Init(2,0,EXTI4_IRQChannel,2); //抢占2,子优先级0,组2

}

/****************************************************************************** *

* 函数名: Write_W5500_1Byte

* 描述: 通过SPI1向指定地址寄存器写1个字节数据

* 输入: reg:16位寄存器地址,dat:待写入的数据

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Write_W5500_1Byte(u16 reg, u8 dat)

{

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

SPI1_ReadWriteByte(FDM1|RWB_WRITE|COMMON_R);//通过SPI1写控制字节,1个字节数据长度,写数据,选择通用寄存器

SPI1_ReadWriteByte(dat);//写1个字节数据

W5500_CS_High(); //置W5500的SCS为高电平

}

/****************************************************************************** *

* 函数名: Write_W5500_2Byte

* 描述: 通过SPI1向指定地址寄存器写2个字节数据

* 输入: reg:16位寄存器地址,dat:16位待写入的数据(2个字节)

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Write_W5500_2Byte(u16 reg, u16 dat)

{

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

SPI1_ReadWriteByte(FDM2|RWB_WRITE|COMMON_R);//通过SPI1写控制字节,2个字节数据长度,写数据,选择通用寄存器

SPI1_Send_Short(dat);//写16位数据

W5500_CS_High(); //置W5500的SCS为高电平

}

/****************************************************************************** *

* 函数名: Write_W5500_nByte

* 描述: 通过SPI1向指定地址寄存器写n个字节数据

* 输入: reg:16位寄存器地址,*dat_ptr:待写入数据缓冲区指针,size:待写入的数据长度* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Write_W5500_nByte(u16 reg, u8 *dat_ptr, u16 size)

{

u16 i;

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

SPI1_ReadWriteByte(VDM|RWB_WRITE|COMMON_R);//通过SPI1写控制字节,N个字节数据长度,写数据,选择通用寄存器

for(i=0;i

{

SPI1_ReadWriteByte(*dat_ptr++);//写一个字节数据

}

W5500_CS_High(); //置W5500的SCS为高电平

/****************************************************************************** *

* 函数名: Write_W5500_SOCK_1Byte

* 描述: 通过SPI1向指定端口寄存器写1个字节数据

* 输入: s:端口号,reg:16位寄存器地址,dat:待写入的数据

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Write_W5500_SOCK_1Byte(SOCKET s, u16 reg, u8 dat)

{

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

SPI1_ReadWriteByte(FDM1|RWB_WRITE|(s*0x20+0x08));//通过SPI1写控制字节,1个字节数据长度,写数据,选择端口s的寄存器

SPI1_ReadWriteByte(dat);//写1个字节数据

W5500_CS_High(); //置W5500的SCS为高电平

}

/****************************************************************************** *

* 函数名: Write_W5500_SOCK_2Byte

* 描述: 通过SPI1向指定端口寄存器写2个字节数据

* 输入: s:端口号,reg:16位寄存器地址,dat:16位待写入的数据(2个字节)

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Write_W5500_SOCK_2Byte(SOCKET s, u16 reg, u16 dat)

{

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

SPI1_ReadWriteByte(FDM2|RWB_WRITE|(s*0x20+0x08));//通过SPI1写控制字节,2个字节数据长度,写数据,选择端口s的寄存器

SPI1_Send_Short(dat);//写16位数据

W5500_CS_High(); //置W5500的SCS为高电平

/****************************************************************************** *

* 函数名: Write_W5500_SOCK_4Byte

* 描述: 通过SPI1向指定端口寄存器写4个字节数据

* 输入: s:端口号,reg:16位寄存器地址,*dat_ptr:待写入的4个字节缓冲区指针

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Write_W5500_SOCK_4Byte(SOCKET s, u16 reg, u8 *dat_ptr)

{

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

SPI1_ReadWriteByte(FDM4|RWB_WRITE|(s*0x20+0x08));//通过SPI1写控制字节,4个字节数据长度,写数据,选择端口s的寄存器

SPI1_ReadWriteByte(*dat_ptr++);//写第1个字节数据

SPI1_ReadWriteByte(*dat_ptr++);//写第2个字节数据

SPI1_ReadWriteByte(*dat_ptr++);//写第3个字节数据

SPI1_ReadWriteByte(*dat_ptr++);//写第4个字节数据

W5500_CS_High(); //置W5500的SCS为高电平

}

/****************************************************************************** *

* 函数名: Read_W5500_1Byte

* 描述: 读W5500指定地址寄存器的1个字节数据

* 输入: reg:16位寄存器地址

* 输出: 无

* 返回值: 读取到寄存器的1个字节数据

* 说明: 无

******************************************************************************* /

u8 Read_W5500_1Byte(u16 reg)

{

u8 i;

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

i=SPI1_ReadWriteByte(FDM1|RWB_READ|COMMON_R);//通过SPI1写控制字节,1个字节数据长度,读数据,选择通用寄存器

// i=Read_W5500_1Byte(0x00);

// SPI1_Send_Byte(0x00);//发送一个哑数据

i=SPI1_ReadWriteByte(0x00);//读取1个字节数据

W5500_CS_High();//置W5500的SCS为高电平

return i;//返回读取到的寄存器数据

}

/****************************************************************************** *

* 函数名: Read_W5500_SOCK_1Byte

* 描述: 读W5500指定端口寄存器的1个字节数据

* 输入: s:端口号,reg:16位寄存器地址

* 输出: 无

* 返回值: 读取到寄存器的1个字节数据

* 说明: 无

******************************************************************************* /

u8 Read_W5500_SOCK_1Byte(SOCKET s, u16 reg)

{

u8 i;

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

i=SPI1_ReadWriteByte(FDM1|RWB_READ|(s*0x20+0x08));//通过SPI1写控制字节,1个字节数据长度,读数据,选择端口s的寄存器

// i=SPI_I2S_ReceiveData(SPI1);

// SPI1_Send_Byte(0x00);//发送一个哑数据

i=SPI1_ReadWriteByte(0X00);//读取1个字节数据

W5500_CS_High();//置W5500的SCS为高电平

return i;//返回读取到的寄存器数据

}

/****************************************************************************** *

* 函数名: Read_W5500_SOCK_2Byte

* 描述: 读W5500指定端口寄存器的2个字节数据

* 输入: s:端口号,reg:16位寄存器地址

* 输出: 无

* 返回值: 读取到寄存器的2个字节数据(16位)

* 说明: 无

******************************************************************************* /

u16 Read_W5500_SOCK_2Byte(SOCKET s, u16 reg)

{

u16 i;

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址

i=SPI1_ReadWriteByte(FDM2|RWB_READ|(s*0x20+0x08));//通过SPI1写控制字节,2个字节数据长度,读数据,选择端口s的寄存器

// i=SPI_I2S_ReceiveData(SPI1);

// SPI1_Send_Byte(0x00);//发送一个哑数据

i=SPI1_ReadWriteByte(0x00);//读取高位数据

// SPI1_Send_Byte(0x00);//发送一个哑数据

i*=256;

i+=SPI1_ReadWriteByte(0x00);//读取低位数据

W5500_CS_High();//置W5500的SCS为高电平

return i;//返回读取到的寄存器数据

}

/****************************************************************************** *

* 函数名: Read_SOCK_Data_Buffer

* 描述: 从W5500接收数据缓冲区中读取数据

* 输入: s:端口号,*dat_ptr:数据保存缓冲区指针

* 输出: 无

* 返回值: 读取到的数据长度,rx_size个字节

* 说明: 无

******************************************************************************* /

u16 Read_SOCK_Data_Buffer(SOCKET s, u8 *dat_ptr)

{

u16 rx_size;

u16 offset, offset1;

u16 i;

u8 j;

rx_size=Read_W5500_SOCK_2Byte(s,Sn_RX_RSR);

if(rx_size==0) return 0;//没接收到数据则返回

if(rx_size>1460) rx_size=1460;

offset=Read_W5500_SOCK_2Byte(s,Sn_RX_RD);

offset1=offset;

offset&=(S_RX_SIZE-1);//计算实际的物理地址

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(offset);//写16位地址

j=SPI1_ReadWriteByte(VDM|RWB_READ|(s*0x20+0x18));//写控制字节,N个字节数据长度,读数据,选择端口s的寄存器

// j=SPI_I2S_ReceiveData(SPI1);

if((offset+rx_size)

{

for(i=0;i

{

// SPI1_Send_Byte(0x00);//发送一个哑数据

j=SPI1_ReadWriteByte(0X00);//读取1个字节数据

*dat_ptr=j;//将读取到的数据保存到数据保存缓冲区

dat_ptr++;//数据保存缓冲区指针地址自增1

}

}

else//如果最大地址超过W5500接收缓冲区寄存器的最大地址

{

offset=S_RX_SIZE-offset;

for(i=0;i

{

// SPI1_Send_Byte(0x00);//发送一个哑数据

j=SPI1_ReadWriteByte(0X00);//读取1个字节数据

*dat_ptr=j;//将读取到的数据保存到数据保存缓冲区

dat_ptr++;//数据保存缓冲区指针地址自增1

}

W5500_CS_High(); //置W5500的SCS为高电平

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(0x00);//写16位地址

j=SPI1_ReadWriteByte(VDM|RWB_READ|(s*0x20+0x18));//写控制字节,N个字节数据长度,读数据,选择端口s的寄存器

// j=SPI_I2S_ReceiveData(SPI1);

for(;i

{

// SPI1_Send_Byte(0x00);//发送一个哑数据

j=SPI1_ReadWriteByte(0X00);//读取1个字节数据

*dat_ptr=j;//将读取到的数据保存到数据保存缓冲区

dat_ptr++;//数据保存缓冲区指针地址自增1

}

}

W5500_CS_High(); //置W5500的SCS为高电平

offset1+=rx_size;//更新实际物理地址,即下次读取接收到的数据的起始地址

Write_W5500_SOCK_2Byte(s, Sn_RX_RD, offset1);

Write_W5500_SOCK_1Byte(s, Sn_CR, RECV);//发送启动接收命令

return rx_size;//返回接收到数据的长度

}

/****************************************************************************** *

* 函数名: Write_SOCK_Data_Buffer

* 描述: 将数据写入W5500的数据发送缓冲区

* 输入: s:端口号,*dat_ptr:数据保存缓冲区指针,size:待写入数据的长度

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Write_SOCK_Data_Buffer(SOCKET s, u8 *dat_ptr, u16 size)

{

u16 offset,offset1;

u16 i;

//如果是UDP模式,可以在此设置目的主机的IP和端口号

if((Read_W5500_SOCK_1Byte(s,Sn_MR)&0x0f) != SOCK_UDP)//如果Socket打开失败

{

UDP_DIPR[0] = Flash_Tab[2]; //UDP(广播)模式,目的主机IP地址

UDP_DIPR[1] = Flash_Tab[3];

UDP_DIPR[2] = Flash_Tab[4];

UDP_DIPR[3] = Flash_Tab[5];

//

UDP_DPORT[0] = Flash_Tab[8]; //UDP(广播)模式,目的主机端口号

UDP_DPORT[1] = Flash_Tab[7];

Write_W5500_SOCK_4Byte(s, Sn_DIPR, UDP_DIPR);//设置目的主机IP

Write_W5500_SOCK_2Byte(s, Sn_DPORTR, UDP_DPORT[0]*256+UDP_DPORT[1]);//设

置目的主机端口号

}

offset=Read_W5500_SOCK_2Byte(s,Sn_TX_WR);

offset1=offset;

offset&=(S_TX_SIZE-1);//计算实际的物理地址

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(offset);//写16位地址

SPI1_ReadWriteByte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

if((offset+size)

for(i=0;i

{

SPI1_ReadWriteByte(*dat_ptr++);//写入一个字节的数据

}

}

else//如果最大地址超过W5500发送缓冲区寄存器的最大地址

{

offset=S_TX_SIZE-offset;

for(i=0;i

{

SPI1_ReadWriteByte(*dat_ptr++);//写入一个字节的数据

}

W5500_CS_High(); //置W5500的SCS为高电平

W5500_CS_Low();//置W5500的SCS为低电平

SPI1_Send_Short(0x00);//写16位地址

SPI1_ReadWriteByte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

for(;i

{

SPI1_ReadWriteByte(*dat_ptr++);//写入一个字节的数据

}

}

W5500_CS_High(); //置W5500的SCS为高电平

offset1+=size;//更新实际物理地址,即下次写待发送数据到发送数据缓冲区的起始地址Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);

Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);//发送启动发送命令

}

/****************************************************************************** *

* 函数名: W5500_Hardware_Reset

* 描述: 硬件复位W5500

* 输入: 无

* 输出: 无

* 返回值: 无

* 说明: W5500的复位引脚保持低电平至少500us以上,才能重围W5500

******************************************************************************* /

void W5500_Hardware_Reset(void)

{

W5500_RST_Low();//复位引脚拉低

delay_ms(50);

W5500_RST_High();//复位引脚拉高

delay_ms(200);

// while((Read_W5500_1Byte(PHYCFGR)&LINK)==0);//等待以太网连接完成

}

/****************************************************************************** *

* 函数名: W5500_Init

* 描述: 初始化W5500寄存器函数

* 输入: 无

* 输出: 无

* 返回值: 无

* 说明: 在使用W5500之前,先对W5500初始化

******************************************************************************* /

void W5500_Init(void)

{

u8 i=0;

Write_W5500_1Byte(MR, RST);//软件复位W5500,置1有效,复位后自动清0

delay_ms(10);//延时10ms,自己定义该函数

//设置网关(Gateway)的IP地址,Gateway_IP为4字节unsigned char数组,自己定义

//使用网关可以使通信突破子网的局限,通过网关可以访问到其它子网或进入Internet Write_W5500_nByte(GAR, Gateway_IP, 4);

//设置子网掩码(MASK)值,SUB_MASK为4字节unsigned char数组,自己定义

//子网掩码用于子网运算

Write_W5500_nByte(SUBR,Sub_Mask,4);

//设置物理地址,PHY_ADDR为6字节unsigned char数组,自己定义,用于唯一标识网络设备的物理地址值

//该地址值需要到IEEE申请,按照OUI的规定,前3个字节为厂商代码,后三个字节为产品序号

//如果自己定义物理地址,注意第一个字节必须为偶数

Write_W5500_nByte(SHAR,Phy_Addr,6);

//设置本机的IP地址,IP_ADDR为4字节unsigned char数组,自己定义

//注意,网关IP必须与本机IP属于同一个子网,否则本机将无法找到网关

Write_W5500_nByte(SIPR,IP_Addr,4);

//设置发送缓冲区和接收缓冲区的大小,参考W5500数据手册

for(i=0;i<8;i++)

{

Write_W5500_SOCK_1Byte(i,Sn_RXBUF_SIZE, 0x02);//Socket Rx memory size=2k

Write_W5500_SOCK_1Byte(i,Sn_TXBUF_SIZE, 0x02);//Socket Tx mempry size=2k }

//设置重试时间,默认为2000(200ms)

//每一单位数值为100微秒,初始化时值设为2000(0x07D0),等于200毫秒

Write_W5500_2Byte(RTR, 0x07d0);

//设置重试次数,默认为8次

//如果重发的次数超过设定值,则产生超时中断(相关的端口中断寄存器中的Sn_IR 超时位(TIMEOUT)置“1”)

Write_W5500_1Byte(RCR,8);

//启动中断,参考W5500数据手册确定自己需要的中断类型

//IMR_CONFLICT是IP地址冲突异常中断,IMR_UNREACH是UDP通信时,地址无法到达的异常中断

//其它是Socket事件中断,根据需要添加

Write_W5500_1Byte(IMR,IM_IR7 | IM_IR6);

Write_W5500_1Byte(SIMR,S0_IMR);

Write_W5500_SOCK_1Byte(0, Sn_IMR, IMR_SENDOK | IMR_TIMEOUT | IMR_RECV | IMR_DISCON | IMR_CON);

}

/****************************************************************************** *

* 函数名: Detect_Gateway

* 描述: 检查网关服务器

* 输入: 无

* 输出: 无

* 返回值: 成功返回TRUE(0xFF),失败返回FALSE(0x00)

* 说明: 无

******************************************************************************* /

u8 Detect_Gateway(void)

{

u8 ip_adde[4];

ip_adde[0]=IP_Addr[0]+1;

ip_adde[1]=IP_Addr[1]+1;

ip_adde[2]=IP_Addr[2]+1;

ip_adde[3]=IP_Addr[3]+1;

//检查网关及获取网关的物理地址

Write_W5500_SOCK_4Byte(0,Sn_DIPR,ip_adde);//向目的地址寄存器写入与本机IP不同的IP值

Write_W5500_SOCK_1Byte(0,Sn_MR,MR_TCP);//设置socket为TCP模式

Write_W5500_SOCK_1Byte(0,Sn_CR,OPEN);//打开Socket

delay_ms(5);//延时5ms

if(Read_W5500_SOCK_1Byte(0,Sn_SR) != SOCK_INIT)//如果socket打开失败

{

Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//打开不成功,关闭Socket

return FALSE;//返回FALSE(0x00)

}

Write_W5500_SOCK_1Byte(0,Sn_CR,CONNECT);//设置Socket为Connect模式

do

{

u8 j=0;

j=Read_W5500_SOCK_1Byte(0,Sn_IR);//读取Socket0中断标志寄存器

if(j!=0)

Write_W5500_SOCK_1Byte(0,Sn_IR,j);

delay_ms(5);//延时5ms

if((j&IR_TIMEOUT) == IR_TIMEOUT)

{

return FALSE;

}

else if(Read_W5500_SOCK_1Byte(0,Sn_DHAR) != 0xff)

{

Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//关闭Socket

return TRUE;

}

}while(1);

}

/****************************************************************************** *

* 函数名: Socket_Init

* 描述: 指定Socket(0~7)初始化

* 输入: s:待初始化的端口

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void Socket_Init(SOCKET s)

{

//设置分片长度,参考W5500数据手册,该值可以不修改

Write_W5500_SOCK_2Byte(0, Sn_MSSR, 1460);//最大分片字节数=1460(0x5b4)

//设置指定端口

switch(s)

{

case 0:

//设置端口0的端口号

Write_W5500_SOCK_2Byte(0, Sn_PORT, S0_Port[0]*256+S0_Port[1]);

break;

case 1:

break;

case 2:

break;

case 3:

break;

case 4:

break;

case 5:

break;

case 6:

break;

case 7:

break;

default:

break;

}

}

/****************************************************************************** *

* 函数名: Socket_Connect

* 描述: 设置指定Socket(0~7)为客户端与远程服务器连接

* 输入: s:待设定的端口

* 输出: 无

* 返回值: 成功返回TRUE(0xFF),失败返回FALSE(0x00)

* 说明: 当本机Socket工作在客户端模式时,引用该程序,与远程服务器建立连接

* 如果启动连接后出现超时中断,则与服务器连接失败,需要重新调用该程序连接

* 该程序每调用一次,就与服务器产生一次连接

******************************************************************************* /

unsigned char Socket_Connect(SOCKET s)

{

Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//设置socket为TCP模式

Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket

delay_ms(5);//延时5ms

if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打开失败

{

Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket

return FALSE;//返回FALSE(0x00)

}

Write_W5500_SOCK_1Byte(s,Sn_CR,CONNECT);//设置Socket为Connect模式

return TRUE;//返回TRUE,设置成功

}

/****************************************************************************** *

* 函数名: Socket_Listen

* 描述: 设置指定Socket(0~7)作为服务器等待远程主机的连接

* 输入: s:待设定的端口

* 输出: 无

* 返回值: 成功返回TRUE(0xFF),失败返回FALSE(0x00)

* 说明: 当本机Socket工作在服务器模式时,引用该程序,等等远程主机的连接

* 该程序只调用一次,就使W5500设置为服务器模式

******************************************************************************* /

unsigned char Socket_Listen(SOCKET s)

{

Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//设置socket为TCP模式

Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket

delay_ms(5);//延时5ms

if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打开失败

{

Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket

return FALSE;//返回FALSE(0x00)

}

Write_W5500_SOCK_1Byte(s,Sn_CR,LISTEN);//设置Socket为侦听模式

delay_ms(5);//延时5ms

if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_LISTEN)//如果socket设置失败

{

Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//设置不成功,关闭Socket

return FALSE;//返回FALSE(0x00)

}

return TRUE;

//至此完成了Socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待Socket中断,

//以判断Socket的连接是否成功。参考W5500数据手册的Socket中断状态

//在服务器侦听模式不需要设置目的IP和目的端口号

}

/****************************************************************************** *

* 函数名: Socket_UDP

* 描述: 设置指定Socket(0~7)为UDP模式

* 输入: s:待设定的端口

* 输出: 无

* 返回值: 成功返回TRUE(0xFF),失败返回FALSE(0x00)

* 说明: 如果Socket工作在UDP模式,引用该程序,在UDP模式下,Socket通信不需要建立连接

* 该程序只调用一次,就使W5500设置为UDP模式

******************************************************************************* /

unsigned char Socket_UDP(SOCKET s)

{

Write_W5500_SOCK_1Byte(s,Sn_MR,MR_UDP);//设置Socket为UDP模式*/

Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket*/

delay_ms(5);//延时5ms

if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_UDP)//如果Socket打开失败

{

Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket

return FALSE;//返回FALSE(0x00)

}

else

return TRUE;

//至此完成了Socket的打开和UDP模式设置,在这种模式下它不需要与远程主机建立连接

//因为Socket不需要建立连接,所以在发送数据前都可以设置目的主机IP和目的Socket 的端口号

//如果目的主机IP和目的Socket的端口号是固定的,在运行过程中没有改变,那么也可以在这里设置

}

/****************************************************************************** *

* 函数名: W5500_Interrupt_Process

* 描述: W5500中断处理程序框架

* 输入: 无

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void W5500_Interrupt_Process(void)

{

unsigned char i,j;

IntDispose:

W5500_Interrupt=0;//清零中断标志

i = Read_W5500_1Byte(IR);//读取中断标志寄存器

Write_W5500_1Byte(IR, (i&0xf0));//回写清除中断标志

if((i & CONFLICT) == CONFLICT)//IP地址冲突异常处理

{

//自己添加代码

}

if((i & UNREACH) == UNREACH)//UDP模式下地址无法到达异常处理

{

//自己添加代码

}

i=Read_W5500_1Byte(SIR);//读取端口中断标志寄存器

if((i & S0_INT) == S0_INT)//Socket0事件处理

{

j=Read_W5500_SOCK_1Byte(0,Sn_IR);//读取Socket0中断标志寄存器

Write_W5500_SOCK_1Byte(0,Sn_IR,j);

if(j&IR_CON)//在TCP模式下,Socket0成功连接

{

S0_State|=S_CONN;//网络连接状态0x02,端口完成连接,可以正常传输数据}

if(j&IR_DISCON)//在TCP模式下Socket断开连接处理

{

Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//关闭端口,等待重新打开连接

Socket_Init(0); //指定Socket(0~7)初始化,初始化端口0

S0_State=0;//网络连接状态0x00,端口连接失败

}

if(j&IR_SEND_OK)//Socket0数据发送完成,可以再次启动S_tx_process()函数发送数据

{

S0_Data|=S_TRANSMITOK;//端口发送一个数据包完成

}

if(j&IR_RECV)//Socket接收到数据,可以启动S_rx_process()函数

{

S0_Data|=S_RECEIVE;//端口接收到一个数据包

}

if(j&IR_TIMEOUT)//Socket连接或数据传输超时处理

{

Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);// 关闭端口,等待重新打开连接

S0_State=0;//网络连接状态0x00,端口连接失败

}

}

if(Read_W5500_1Byte(SIR) != 0)

goto IntDispose;

}

/****************************************************************************** *

* 函数名: W5500_Initialization

* 描述: W5500初始货配置

* 输入: 无

* 输出: 无

* 返回值: 无

* 说明: 无

******************************************************************************* /

void W5500_Initialization(void)

{

W5500_Init(); //初始化W5500寄存器函数

Detect_Gateway(); //检查网关服务器

Socket_Init(0); //指定Socket(0~7)初始化,初始化端口0

}

/****************************************************************************** *

* 函数名: Load_Net_Parameters

* 描述: 装载网络参数

* 输入: 无

* 输出: 无

* 返回值: 无

* 说明: 网关、掩码、物理地址、本机IP地址、端口号、目的IP地址、目的端口号、端口工作模式

******************************************************************************* /

void Load_Net_Parameters(void)

{

Gateway_IP[0] = Flash_Tab[30];//加载网关参数

Gateway_IP[1] = Flash_Tab[31];

Gateway_IP[2] = Flash_Tab[32];

Gateway_IP[3] = Flash_Tab[33];

Sub_Mask[0]=Flash_Tab[25];//加载子网掩码

Sub_Mask[1]=Flash_Tab[26];

Sub_Mask[2]=Flash_Tab[27];

Sub_Mask[3]=Flash_Tab[28];

Phy_Addr[0]=Flash_Tab[18];//加载物理地址

Phy_Addr[1]=Flash_Tab[19];

Phy_Addr[2]=Flash_Tab[20];

Phy_Addr[3]=Flash_Tab[21];

Phy_Addr[4]=Flash_Tab[22];

Phy_Addr[5]=Flash_Tab[23];

IP_Addr[0]=Flash_Tab[10];//加载本机IP地址

看门狗程序

TMS320F2812 Watchdog范例程序 FILE: Example_28xWatchdog.c // // TITLE: DSP28 Watchdog interrupt test program. // // ASSUMPTIONS: // // This program requires the DSP28 header files. To compile the // program as is, it should reside in the DSP28/examples/watchdog // sub-directory. // // As supplied, this project is configured for "boot to H0" operation. // // DESCRIPTION: // This program exercises the watchdog on the F2812/F2810 parts. // // First the watchdog is connected to the WAKEINT interrupt of the // PIE block. The code is then put into an infinite loop. // // The user can select to feed the watchdog key register or not // by commenting one line of code in the infinite loop. // // If the watchdog key register is fed by the KickDog function // then the WAKEINT interrupt is not taken. If the key register // is not fed by the KickDog function then WAKEINT will be taken. // // Watch Variables: // LoopCount for the number of times through the infinite loop // WakeCount for the number of times through WAKEINT // //########################################################################### // // Ver | dd mmm yyyy | Who | Description of changes // =====|=============|======|=============================================== // 0.57| 29 May 2002 | L.H. | Initial Release //########################################################################### // Step 0. Include required header files // DSP28_Device.h: device specific definitions #include statements for // all of the peripheral .h definition files. // DSP28_Example.h is specific for the given example. #include "DSP28_Device.h"

驱动程序

linux 驱动程序设计实验 一实验目的 1.了解LINUX操作系统中的设备驱动程序的组成 2.编写简单的字符设备驱动程序并进行测试 3.编写简单的块设备驱动程序并进行测试 4.理解LINUX操作系统的设备管理机制 二准备知识 1. LINUX下驱动程序基础知识 Linux抽象了对硬件的处理,所有的硬件设备都可以像普通文件一样来看待:它们可以使用和操作文件相同的、标准的系统调用接口来完成打开、关闭、读写和I/O控制操作,而驱动程序的主要任务也就是要实现这些系统调用函数。在Linux操作系统下有两类主要的设备文件:一类是字符设备,另一类则是块设备。字符设备是以字节为单位逐个进行I/O操作的设备,在对字符设备发出读写请求时,实际的硬件I/O紧接着就发生了,一般来说字符设备中的缓存是可有可无的,而且也不支持随机访问。块设备则是利用一块系统内存作为缓冲区,当用户进程对设备进行读写请求时,驱动程序先查看缓冲区中的内容,如果缓冲区中的数据能满足用户的要求就返回相应的数据,否则就调用相应的请求函数来进行实际的I/O操作。块设备主要是针对磁盘等慢速设备设计的,其目的是避免耗费过多的CPU时间来等待操作的完成。一般说来,PCI卡通常都属于字符设备。 我们常见的驱动程序就是作为内核模块动态加载的,比如声卡驱动和网卡驱动等,这些驱动程序源码可以修改到内核中,也可以把他们编译成模块形势,在需要的时候动态加载. 而Linux最基础的驱动,如CPU、PCI总线、TCP/IP协议、APM (高级电源管理)、VFS等驱动程序则编译在内核文件中。有时也把内核模块就叫做驱动程序,只不过驱动的内容不一定是硬件罢了,比如ext3文件系统的驱动。当我们加载了设备驱动模块后,应该怎样访问这些设备呢?Linux是一种类Unix系统,Unix的一个基本特点是“一切皆为文件”,它抽象了设备的处理,将所有的硬件设备都像普通文件一样看待,也就是说硬件可以跟普通文件一样来打开、关闭和读写。 系统中的设备都用一个设备特殊文件代表,叫做设备文件,设备文件又分为Block (块)型设备文件、Character(字符)型设备文件和Socket (网络插件)型设备文件。Block设备文件常常指定哪些需要以块(如512字节)的方式写入的设备,比如IDE硬盘、SCSI硬盘、光驱等。而Character型设备文件常指定直接读写,没有缓冲区的设备,比如并口、虚拟控制台等。Socket(网络插件)型设备文件指定的是网络设备访问的BSD socket 接口。 设备文件都放在/dev目录下,比如硬盘就是用/dev/hd*来表示,/dev/hda表示第一个IDE 接口的主设备,/dev/hda1表示第一个硬盘上的第一个分区;而/dev/hdc 表示第二个IDE接口的主设备。对于Block和Character型设备,使用主(Major)和辅(minor)设备编号来描述设备。主设备编号来表示某种驱动程序,同一个设备驱动程序模块所控制的所有设备都有一

CiscoMDS9513设备配置安装手册

文档信息 文档修订记录

目录 第1章功能概述 (3) 1.1C ISCO MDS9513构建存储网络方案 (3) 1.2C ISCO MDS9513设备简介 (6) 第2章场地要求 (15) 2.1电源和冷却装置 (15) 2.2机房环境要求 (15) 2.3物理规格 (15) 2.4设备承重要求 (15) 第3章组件说明 (16) 3.1C ISCO MDS9513资源列表 (16) 3.2C ISCO MDS9513端口列表 (18) 3.3B LADE SERVER 连接 (18) 第4章组件安装 (21) 4.1C ISCO MDS9513安装配置原则 (21) 4.2C ISCO MDS9513配置操作步骤 (22) 第5章运营维护 (38) 5.1C ISCO MDS9513软件版本升级 (38) 5.2电源和风扇状态说明 (38) 5.3线卡工作状态说明 (38) 5.4引擎工作状态说明 (39) 5.5C ISCO MDS9513常用功能排错 (39) 5.6C ISCO MDS9513排错工具排错 (40)

第1章功能概述 1.1 Cisco MDS 9513 构建存储网络方案 数据中心的SAN网络采用Cisco MDS 9513交换机构架存储网络,连接后端存储盘 阵和主机、服务器及磁带库系统。 Cisco公司的MDS9513设备为模块化、高密度、高性价比的智能多层存储网络光纤 交换机,每台交换机提供可根据需要配置24端口或48端口1/2/4Gb FC板卡, MDS9513单机箱最达提供528个模块化配置的FC端口。 极具竞争力的经济性:Cisco MDS 9513 设备采用优化的端口连接设计,可提供4G 2G、 1G 速率自适应FC端口。 Cisco MDS 9513多层光纤通道交换机所提供的先进的管理工具可以最大限度地降低 总体拥有成本(TCO)。Cisco MDS 9513采用了虚拟SAN(VSAN)技术,这种技术可 以在一个单一的物理结构中建立多个基于硬件的独立环境,以便安全地共享物理基 础设施,从而进一步降低TCO。 智能化网络服务:Cisco MDS 9513采用了VSAN技术,用于基于硬件的智能化帧处 理的访问控制列表(ACL),以及各种先进的流量管理功能,例如转发拥塞控制(FCC) 等和覆盖整个交换结构的QoS,从而让用户可以方便地从各个独立的SAN孤岛移植 到覆盖整个企业的存储网络。 全面的安全框架:Cisco MDS 9513支持RADIUS身份认证、SNMPv3、角色访问控制、 SSH、SFTP、FC-SP、VSAN、硬件分区、LUN分区和ACL。 完善的诊断功能:提供了业界第一套智能化诊断、协议解码和网络分析工具,以及 集成的“Call Home”(自动通报)功能,从而可以提高可靠性,加快解决问题的 速度,降低服务成本。 统一的存储管理:Cisco MDS 9513内置了丰富的存储网络管理功能,所有功能都可 以通过CLI命令行界面或者图形界面Cisco Fabric Manager获得。Cisco Fabric Manager是一个集中式的管理工具,可以简化多个光纤通道交换机的管理。

软件看门狗和硬件看门狗

看门狗分硬件看门狗和软件看门狗。硬件看门狗是利用一个定时器电路,其定时输出连接到电路的复位端,程序在一定时间范围内对定时器清零(俗称“喂狗”),因此程序正常工作时,定时器总不能溢出,也就不能产生复位信号。如果程序出现故障,不在定时周期内复位看门狗,就使得看门狗定时器溢出产生复位信号并重启系统。软件看门狗原理上一样,只是将硬件电路上的定时器用处理器的内部定时器代替,这样可以简化硬件电路设计,但在可靠性方面不如硬件定时器,比如系统内部定时器自身发生故障就无法检测到。当然也有通过双定时器相互监视,这不仅加大系统开销,也不能解决全部问题,比如中断系统故障导致定时器中断失效。 看门狗本身不是用来解决系统出现的问题,在调试过程中发现的故障应该要查改设计本身的错误。加入看门狗目的是对一些程序潜在错误和恶劣环境干扰等因素导致系统死机而在无人干预情况下自动恢复系统正常工作状态。看门狗也不能完全避免故障造成的损失,毕竟从发现故障到系统复位恢复正常这段时间内怠工。同时一些系统也需要复位前保护现场数据,重启后恢复现场数据,这可能也需要一笔软硬件的开销。 图1:(a) 多任务系统看门狗示意图;(b) 相应的看门狗复位逻辑图。 在单任务系统中看门狗工作原理如上所述,容易实现。在多任务系统中情况稍为复杂。假如每个任务都像单任务系统那么做,如图1(a)所示,只要有一个任务正常工作并定期“喂狗”,看门狗定时器就不会溢出。除非所有的任务都故障,才能使得看门狗定时器溢出而复位,如图1(b)。 而往往我们需要的是只要有一个任务故障,系统就要求复位。或者选择几个关键的任务接受监视,只要一个任务出问题系统就要求复位,如图2(a)所示,相应的看门狗复位逻辑如图2(b)所示。 在多任务系统中通过创建一个监视任务TaskMonitor,它的优先级高于被监视的任务群Task1、Task2...Taskn。TaskMonitor在Task1~Taskn正常工作情况下,一定时间内对硬件看门狗定时器清零。如果被监视任务群有一个Task_x出现故障,TaskMonitor就不对看门狗定时器清零,也就达到被监视任务出现故障时系统自动重启的目的。另外任务TaskMonitor自身出故障时,也不能及时对看门狗定时器清零,看门狗也能自动复位重启。

驱动入口函数

这个驱动程序包含了三个函数:DriverEntry、HelloDDKUnload和HelloDDKDispatchRoutine。其中DriverEntry是驱动程序的入口函数,相当于C/C++程序的main函数,HelloDDKUnload函数是驱动卸载函数。而HelloDDKDispatchRuntine则是IRP的派遣函数,因为驱动程序主要是处理IO 请求,而IO请求大多是在派遣函数中处理的。 先来看看这个驱动程序的第一个函数:DriverEntry /**************************************************************** * 函数名称:DriverEntry * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象 * 参数列表: pDriverObject:从I/O管理器中传来的驱动对象 pRegistryPath:驱动程序在注册表中的路径 * 返回值:返回初始化驱动状态 ****************************************************************/ #pragma INITCODE extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath ) { NTSTATUS status; KdPrint( ( "Enter DriverEntry!\n" ) ); //注册其它驱动调用函数入口 pDriverObject->DriverUnload = ( PDRIVER_UNLOAD ) HelloDDKUnload; pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine; pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine; pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine; pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine; //创建驱动设备对象 status = CreateDeivce( pDriverObject ); KdPrint( ( "DriverEntry end!\n" ) ); return status; } 这个函数的第一句代码是一个#pragma预处理指令: #pragma INITCODE

Linux网络设备驱动

嵌入式培训专家
Linux网络设备驱动
主讲:宋宝华
https://www.doczj.com/doc/0312911005.html,

华清远见
今天的内容
vLinux网络设备驱动架构 vLinux网络设备驱动数据流程
? NON-NAPI模式数据接收流程 ? NAPI模式数据接收流程 ? 数据发送流程
vLinux网络协议栈的实现
? TCP/UDP/IP/MAC各层数据传递 ? 网络系统调用与socket

华清远见
Linux网络设备驱动架构

华清远见
net_device
struct net_device_ops { int (*ndo_open)(struct net_device *dev); int (*ndo_start_xmit) (struct sk_buff *skb, struct net_device *dev); int (*ndo_set_mac_address)(struct net_device *dev, void *addr); int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); void (*ndo_tx_timeout) (struct net_device *dev); ... }
struct net_device { struct net_device_stats stats; const struct net_device_ops *netdev_ops; const struct ethtool_ops *ethtool_ops; ... }
struct ethtool_ops { int (*get_settings)(struct net_device *, struct ethtool_cmd *); int (*set_settings)(struct net_device *, struct ethtool_cmd *); void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); int (*get_regs_len)(struct net_device *); ... }

字符设备驱动相关函数及数据结构简介

1.设备号 分为主次设备号,看上去像是两个号码,但在内核中用dev_t()一种结构表示,同时不应该自己去假设赋值设备号,而是使用宏()来取得. MAJOR(dev_t dev); MINOR(dev_t dev); 即使你有确定的主,次设备号也要用 dev=MKDEV(int major, int minor); 1.1分配设备号 静态分配 int register_chrdev_region(dev_t first, unsigned int count, char *name); first 是你要分配的起始设备编号. first 的次编号部分常常是0, 但是没有要求是那个效果. count 是你请求的连续设备编号的总数. 注意, 如果count 太大, 你要求的范围可能溢出到下一个次编号; 但是只要你要求的编号范围可用, 一切都仍然会正确工作. name 是应当连接到这个编号范围的设备的名子; 它会出现在/proc/devices 和sysfs 中 动态分配 int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); dev 是一个只输出的参数, 它在函数成功完成时持有你的分配范围的第一个数. fisetminor 应当是请求的第一个要用的次编号; 它常常是0. count 和name 参数如同给request_chrdev_region 的一样 >>>应该始终使用动态分配,但最好为定制设备号留有接口,以参数形式,以name_major=0做为默认值,可能 的操作如下: if(scull_major){ dev = MKDEV(scull_major, scull_minor); result = register_chrdev_region(dev, scull_nr_devs,"scull"); }else{ result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,"scull"); scull_major = MAJOR(dev); } if(result < 0){ printk(KERN_WARNING "scull: can't get major %d\n", scull_major); return result; } 1.2释放设备号 void unregister_chrdev_region(dev_t first, unsigned int count);

网络设备安装与调试

实习报告 实习性质:《网络设备安装与调试》课程实习学生姓名:xxx 专业班级:xxx 指导教师:刘宇、周通 实习时间:2015年6月29日— 2015年7月3日实习地点:1405机房 重庆工程职业技术学院

学生实习考核表

目录 1 实习目的 (1) 2实习概况 (1) 2.1实习要求 (1) 2.2 实习时间 (1) 2.3实习环境 (1) 2.4 开发环境 (1) 3 实习内容 (2) 3.1实验1交换机综合配置 (2) 3.1.1项目描述 (2) 3.1.2 规划描述 (2) 3.1.3实验要求 (4) 3.1.4配置命令 (4) 3.1.5 检测安装完成后的网络图 (8) 3.1.6链路聚合 (9) 3.1.7设置快速生成树协议和配置优先级 (9) 3.2实验2路由器综合配置 (10) 3.2.1项目描述 (10) 3.2.2规划描述 (10) 3.2.3实验要求 (11) 3.2.4配置命令 (12) 3.2.5验证三层交换机之间互通 (14) 3.3实验3邮件服务器配置 (15) 3.3.1 项目描述 (15) 3.3.2 规划描述 (15) 3.3.3 实验要求 (16) 3.3.4配置命令 (16) 3.3.5验证内外网互通 (20) 3.3.6配置动/静态NAPT (20)

通过本次《网络设备安装与调试》课程实习,让学生利用Cisco软件,对vlan 的划分,配置交换机和路由器使服务器与服务器之间实现互通。 2实习概况 2.1实习要求 (1)按时到机房参加实习; (2)独立动手完成实习相关内容; (3)按要求完成实习报告。 2.2 实习时间 2015年6月29日— 2015年7月3日 2.3实习环境 1405机房 2.4 开发环境 ●操作系统(Windows7) ●使用软件Cisco Packet Tracer 软件

常用网络设备设备

物理层设备 1.调制解调器 调制解调器的英文名称为modem,来源于Modulator/Demodulator,即调制器/解调器。 ⑴工作原理 调制解调器是由调制器与解调器组合而成的,故称为调制解调器。调制器的基本职能就是把从终端设备和计算机送出的数字信号转变成适合在电话线、有线电视线等模拟信道上传输的模拟信号;解调器的基本职能是将从模拟信道上接收到的模拟信号恢复成数字信号,交给终端计算机处理。 ⑵调制与解调方式 调制,有模拟调制和数字调制之分。模拟调制是对载波信号的参量进行连续地估值;而数字调制使用载波信号的某些离散状态来表征所传送的信息,在接收端对载波信号的离散参量进行检测。调制是指利用载波信号的一个或几个参数的变化来表示数字信号的一种过程。 调制方式相应的有:调幅、调频和调相三种基本方式。 调幅:振幅调制其载波信号将随着调制信号的振幅而变化。 调频:载波信号的频率随着调制信号而改变。 调相:相位调制有两相调制、四相调制和八相调制几种方式。 ⑶调制解调器的分类 按安装位置:调解解调器可以分为内置式和外置式 按传输速率分类:低速调制解调器,其传输速率在9600bps以下;中速调制解调器,其传输速率在9.6~19.2kbps之间;高速调制解调器,传输速率达到19.2~56kbps。 ⑷调制解调器的功能 ?差错控制功能:差错控制为了克服线路传输中出现的数据差错,实现调制解调器至远端调制解调器的无差错数据传送。 ?数据压缩功能:数据压缩功能是为了提高线路传输中的数据吞吐率,使数据更快地传送至对方。 ⑸调制解调器的安装 调制解调器的安装由两部分组成,线路的连接和驱动程序的安装。 线路连接: ?将电话线引线的一端插头插入调制解调器后面LINE端口。

STM32窗口看门狗程序

STM32窗口看门狗程序 窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位(WWDG->;CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG->;CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。

图 3.6.1.1中,T[6:0]就是WWDG_CR的低七位,W[6:0]即是WWDG->;CFR的低七位。T[6:0]就是窗口看门狗的计数器,而W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。 上窗口值(W[6:0])是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于0X40,否则窗口就不存在了。 窗口看门狗的超时公式如下: Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1; 其中: Twwdg:WWDG超时时间(单位为ms) Fpclk1:APB1的时钟频率(单位为Khz) WDGTB:WWDG的预分频系数 T[5:0]:窗口看门狗的计数器低6位 窗口看门狗寄存器介绍:

如何使用窗口看门狗: 1)使能WWDG时钟 2)设置WWDG_CFR和WWDG_CR两个寄存器 在时钟使能完后,我们设置WWDG的CFR和CR两个寄存器,对WWDG进行配置。包括使能窗口看门狗、开启中断、设置计数器的初始值、设置窗口值并设置分频数WDGTB 3)开启WWDG中断并分组 4)编写中断服务函数 软件例程: //---------------------------wdg.c----------------------- #include "wdg.h" #include "led.h" u8 wwdg_cnt=0x7f; //窗口看门狗计数器初值 void wwdg_init(u8 tr,u8 wr,u8 fprer) { RCC->;APB1ENR|=1;CFR|=fprer;CFR|=1;CFR&=0xff80; //窗口值清零 WWDG->;CFR|=wr; //设定窗口值 WWDG->;CR|=(wwdg_cnt|1;CR|=(cnt&0x7f); //喂狗值 } void WWDG_IRQHandler(void)

驱动程序安装方法

驱动程序安装方法 初识电脑的人,可能为安装驱动程序而头疼。因为对驱动程序了解得不多就会在安装过程中走不少弯路,下面就给大家介绍一下安装驱动程序的两种常用方法和一些实用技巧。 一、安装即插即用设备的驱动程序 安装前的准备工作很重要,一般我们拿到要安装的新硬件时,首先要查看外包装盒,了解产品的型号、盒内部件及产品对系统的最低要求等信息。紧接着就要打开包装盒,取出硬件产品、说明书和驱动盘(光盘或软盘),认真阅读说明书或驱动盘上的ReadMe 文件,一般说明书上写有安装方法和步骤,以及安装注意事项。除了阅读说明书外,还应记得硬件产品上印刷的各种信息以及板卡产品使用的主要芯片的型号。这些信息就是确定产品型号及厂家的重要依据,只有知道这些,才能在网上查找最新的驱动程序。最后按照说明书上介绍的方法来安装硬件。通常安装内置板卡、内置驱动器,使用串口或PS /2接口的设备都应关机断电后再操作,而安装USB设备、笔记本电脑的PC卡时可以带电热插拔。当然,如果是Win2000系统则均可热插拔。完成前面的准备工作之后,就可以启动Windows 来安装驱动程序了。通常情况下,Windows 能够自动检测到PCI 卡、AGP卡、ISA卡、USB设备以及多数打印机和扫描仪等外设,并提示用户插入安装盘。以YAMAHA724声卡为例,其在Win98下安装驱动程序的详细步骤如下。 1.Win98在启动过程中会自动检测即插即用设备,一旦发现了新设备,并且在INF目录下有该设备的.inf 文件,系统将自动安装驱动程序;如果这是一个新设备,INF目录下没有相应的.inf 文件,那么系统就会启动硬件向导。我们单击“下一步”让安装向导自动搜索设备驱动程序,然后再单击“下一步”。 2.在图3中只选中“指定位置”,插入驱动光盘,并单击“浏览”,根据说明书的介绍,选择简体中文版驱动程序所在的目录“E:\Lx_so u n d /Yamaha /Win9X”,点“确定”后单击“下一步”。需要注意的是:Win95的安装向导没有自动搜索功能,我们必须选择“从磁盘安装”,并指定驱动程序所在的位置。驱动程序所在的目录通常是驱动盘上的“Win95”、“Win9X”或“Windows98”目录。 3.硬件安装向导会在指定目录下查找与设备相符的.inf 文件,此例中,硬件向导将在指定目录下找到并向作户报告发现YAMAHA724声卡驱动程序,继续按“下一步”。 4.硬件安装向导显示Windows 准备安装的驱动程序的信息,单击“下一步”后,硬件向导便会根据.inf 文件的内容把指定的文件拷贝到相应的目录下,并在注册表中写入相应的信息,安装成功后显示出对话框。 5.对多数设备而言,到这里驱动程序就算安装完毕了。但如果你安装的是声卡那就还未结束,因为刚才的步骤只能装完声卡的主体部分。单击“完成”后,Windows 又会报告发现了两个新硬件,分别是声卡的DOS 仿真部件和声卡上的游戏控制端口。由于此时SBPCI9X.inf 文件已经被拷到“Windows /INF /Other”子目录下,所以Windows 能够自动安装好这两种设备的驱动程序。 6.驱动程序安装完毕后,我们需要检查设备能否正常工作。检查前还要进行额外的设置,例如使用网卡之前必须先安装和设置网络协议,用调制解调器上网之前要先“新建连接”等。此例中,在“控制面板”里打开“系统”→“设备管理器”→“声音、视频和游戏控制器”,可以看见下面多了三个设备,只要设备的小图标上没有黄色惊叹号,就表示驱动程序运行正常。 二、安装非即插即用设备的驱动程序

看门狗电路及原理

看门狗电路。在单片机中,为了能使得程序能够正常的运行。设定的及时根据程序所返回的值检测程序运行情况的定时电路。 在主程序中设定一定的值,把这个值在看门狗定时电路数值益处之前定时赋给看门狗赋给定时电路,让看门狗定时器复位。主程序的赋值周期要小于看门狗定时电路的运行周期。 看门狗 百科名片 单片机"看门狗" 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称"看门狗"(watchdog) 目录[隐藏] 应用 基本原理 看门狗使用注意 看门狗运用 设计思路 [编辑本段]应用 看门狗电路的应用,使单片机可以在无人状态下实现连续工作,其工作原理是:看门狗芯片和单片机的一个I/O引脚相连,该I/O引脚通过程序控制它定时地往看门狗的这个引脚上送入高电平(或低电平),这一程序语句是分散地放在单片机其他控制语句中间的,一旦单片机由于干扰造成程序跑飞后而陷入某一程序段进入死循环状态时,写看门狗引脚的程序便不能被执行,这个时候,看门狗电路就会由于得不到单片机送来的信号,便在它和单片机复位引脚相连的引脚上送出一个复位信号,使单片机发生复位,

即程序从程序存储器的起始位置开始执行,这样便实现了单片机的自动复位。 [编辑本段]基本原理 看门狗,又叫watchdog timer,是一个定时器电路, 一般有一个输入,叫喂狗(kicking the dog or service the dog),一个输出到MCU的RST端,MCU正常工作的时候,每隔一端时间输出一个信号到喂狗端,给WDT 清零,如果超过规定的时间不喂狗,(一般在程序跑飞时),WDT 定时超过,就会给出一个复位信号到MCU,使MCU复位. 防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。工作原理:在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。所以在使用有看门狗的芯片时要注意清看门狗。硬件看门狗是利用了一个定时器,来监控主程序的运行,也就是说在主程序的运行过程中,我们要在定时时间到之前对定时器进行复位如果出现死循环,或者说PC指针不能回来。那么定时时间到后就会使单片机复位。常用的WDT芯片如MAX813 ,5045, IMP 813等,价格4~10元不等. 软件看门狗技术的原理和这差不多,只不过是用软件的方法实现,我们还是以51系列来讲,我们知道在51单片机中有两个定时器,我们就可以用这两个定时器来对主程序的运行进行监控。我们可以对T0设定一定的定时时间,当产生定时中断的时候对一个变量进行赋值,而这个变量在主程序运行的开始已经有了一个初值,在这里我们要设定的定时值要小于主程序的运行时间,这样在主程序的尾部对变量的值进行判断,如果值发生了预期的变化,就说明T0中断正常,如果没有发生变化则使程序复位。对于T1我们用来监控主程序的运行,我们给T1设定一定的定时时间,在主程序中对其进行复位,如果不能在一定的时间里对其进行复位,T1 的定时中断就会使单片机复位。在这里T1的定时时间要设的大于主程序的运行时间,给主程序留有一定的的裕量。而T1的中断正常与否我们再由T0定时中断子程序来监视。这样就够成了一个循环,T0监视T1,T1监视主程序,主程序又来监视T0,从而保证系统的稳定运行。51 系列有专门的看门狗定时器,对系统频率进行分频计数,定时器溢出时,将引起复位.看门狗可设定溢出率,也可单独用来作为定时器使用。凌阳61的看门狗比较单一,一个是时间单一,第二是功能在实际的使用中只需在循环当中加入清狗的指令就OK了。AVR系列中,avr-libc 提供三个API 支持对器件内部Watchdog 的操作,它们分别是:wdt_reset() // Watchdog 复位wdt_enable(timeout) // Watchdog 使能wdt_disable() // Watchdog 禁止C8051Fxxx单片机内部也有一个21位的使用系统时钟的定时器,该定时器检测对其控制寄存器的两次特定写操作的时间间隔。如果这个时间间隔超过了编程的极限值,将产生一个WDT复位。-------------------------------------------------------------------------------- [编辑本段]看门狗使用注意

C51单片机看门狗电路及程序设计方案

C51单片机看门狗电路及 程序设计案 院系:信息工程学院 年级:2010级 电子一班禹豪 电子一班训虎 电子二班邓启新 一、引言 在由单片机构成的微型计算机系统中,程序的正常运行常常会因为来自外界的电磁场干扰等原因而被打断,从而造成程序的跑飞,而陷入死循环。由此导致单片机控制的系统无法继续工作,造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片或程序,俗称"看门狗"(watchdog) (1)看门狗电路基本原理 看门狗电路的应用,使单片机可以在无人状态下实现连续工作,其工作原理是:看门狗芯片和单片机的一个I/O引脚相连**,该I/O引脚通过程序控制它定时地往看门狗的这个引脚上送入高电平(或低电平),这一程序语句是分散地放在单片机其他控制语句中间的,一旦单片机由于干扰造成程序跑飞后而陷入某一程序段进入死循环状态时,写看门狗引脚的程序便不能被执行,这个时候,看门狗电路就会由于得不到单片机送来的信号,便在它和单片机复位引脚相连的引脚上送出一个复位信号,使单片机发生复位,即程序从程序存储器的起始位置开始执行,这样便实现了单片机的自动复位。 *此处设计原理实际上为下文中硬件看门狗设计思路。

(2)看门狗电路一般设计式 “看门狗”电路一般分为硬件看门狗与软件看门狗两种设计式。 硬件看门狗是利用了一个定时器,来监控主程序的运行,也就是说在主程序的运行过程中,我们要在定时时间到之前对定时器进行复位。如果出现死循环,或者说PC指针不能回来,那么定时时间到后就会使单片机复位。常用的WDT芯片如MAX813,5045,IMP 813等,价格4~10元不等. 软件看门狗技术的原理和硬件看门狗类似,只不过是用软件的法实现(即利用单片机部定时器资源,通过编程模拟硬件看门狗工作式),以51系列为例:因在51单片机中有两个定时器,在利用部定时器资源来对主程序的运行进行监控时。可以对T1(或T0)设定一定的定时时间(设定的定时值要小于主程序的运行时间),当产生定时中断的时候对一个变量进行赋值(此变量在主程序运行的开始已有一个初值)。当主程序运行至最后时对此变量的值进行判断,如果值发生了预期的变化,就说明T0中断正常,如果没有发生变化则使程序复位。 考虑到设计要求,本设计采用软件看门狗设计思路。 二、看门狗电路整体设计思路 根据设计要求,本设计利用C51单片机部自带的定时器1进行编程,并配合少量电路实现“看门狗“电路功能。整个设计分为软件部分与硬件部分,如下: (1)软件部分设计原理: 软件设计分为三部分:“看门狗“定时器设置程序、溢出中断服务程序和喂狗代码。 1.1设计思路: 1)在主程序开头,“看门狗“定时器设置程序设置定时器1计时50ms。 2)当定时达50ms时,定时器1产生溢出中断,溢出中断服务程序开始工作,将看门狗标志num加1。当num的值等于100时,说明看门狗定时器已经计时5s,此时,单片机I/O端口P1.0输出高电平,对程序进行复位。 3)在此过程中,喂狗代码将被穿插于程序中循环体末尾。当循环体结束时,喂狗代码执行,关闭定时器1、清空num并重新初始化定时器设置。若循环体进入死循环,喂狗代码无法执行,num将一直累加至100,此时程序复位。 注:喂狗代码放置位置可根据num预计数值进行调整:当num门限值较小,即看门狗计数时间较短时,喂狗代码可放于程序中各循环体之后或均匀分布于整个主程序中。当num门限值较大,即看门狗计数时间较长时,喂狗代码可放于程序主循环体末尾。但是需注意看门狗计数时间必须长于正常工作时间,以免非正常复位。 1.2软件设计流程图:

驱动名词解释

驱动 NTSTATUS NTSTATUS 是被定义为32位的无符号长整型。在驱动程序开发中,人们习惯用NTSTATUS 返回状态。其中0~0X7FFFFFFF,被认为是正确的状态,而0X80000000~0XFFFFFFFF被认为是错误的状态。 有一个非常有用的宏-----NT_SUCCESS,用来检测状态是否正确。 IN IN,OUT,INOUT是一个空的宏,只是用来说明这个参数是用于输入参数,还是输出的参数。 DriverEntry 操作系统在初始化驱动程序的时候会调用DriverEntry,通常会用这个函数来填充dispatch例程的指针,这就象注册回调函数一样。有的设备要创建设备的对象,或者还要创建一个设备名字,以及其他的初始化操作。它的原型: NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ){ } IN,OUT,INOUT是一个空的宏,只是用来说明这个参数是用于输入参数,还是输出的参数。NTSTATUS实际是个长整型可以在DDK头文件NTSTA TUS.H中找到NTSTATUS的代码列表。函数的第一个参数DriverObject是刚被初始化的驱动对象,就是操作系统为这个驱动分配的空间的指针。函数的第二个参数RegistryPath是驱动在注册表中的键值。如果驱动程序需要访问设备的服务键需要保存这个键值以备后用。 UNICODE_STRING UNICODE_STRING结构是通过使用各种本地安全认证(LSA)的功能来指定一个Unicode 字符串。 2结构体原型: typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer;} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; 3结构成员: Length 指定字符串的长度,以字节为单位指出的Buffer字符串的长度。如果是以NULL字符结尾(即'\0'),则不包括NULL字符的长度。 MaximumLength Buffer字符串的总长度。 MaximumLength和Length的关系可以参照: char c[10] = "123"; sizeof(c);和strlen(c);得出的结果。

电子书包网络设备安装调试指南

凌云诺亚舟 优学派电子书包网络设备使用指南 杨晨东 2014/1/17

凌云电子书包网络设备使用指南 一、基本设备介绍 1.路由器H3C RT-MSR900-AC-H3 H3C MSR 900路由器(AC),2WLAN FE,4LAN FE; 2.交换机H3C SMB-S1626-PWR 以太网交换机,24个10/100BASE-T自协商的以太网端口,全部带有POE供电功能 2个10/100/1000BASE-T自协商的以太网端口(Combo端口,电口优先) 1个Console端口; 3.AC(无线访问节点控制器)Ruckus ZoneDirector-1100 ZoneDirector 1100, 管理6个AP;ZD1100可以升级支持高达50的AP与AP许可升级。

4.AP(无线访问节点)Ruckus ZoneDirector-7363 RUCKUS 901-7363-WW00,智能网状网络,准入控制/负载平衡,8个BSSID,分别对应各种不同的QoS和安全策略,WEP、WPA-PSK(AES)、802.1X支持,零IT和动态PSK,强制门户和访客账户,RADIUS和活动地址簿支持。不带AC电源。 5.U学派U12 1280高清9寸大屏 ,3D场景互动桌面, 双核+Android4.1, 行业顶配,功能领先。 6.耗材准备 网线,室内抗干扰、高速超五类屏蔽双绞线,使用机压网线; 插线板,过载保护,铜芯线的插线板; UPS,二十四小时不间断电源,配置UPS支持服务器使用。 二、连接线路

1.网络拓扑图 2.拓扑简介 星型结构是最古老的一种连接方式,大家每天都使用的电话属于这种结构。星型结构是指各工作站以星型方式连接成网。网络有中央节点,其他节点(工作站、服务器)都与中央节点直接相连,这种结构以中央节点为中心,因此又称为集中式网络。这种结构便于集中控制,因为端用户之间的通信必须经过中心站。由于这一特点,也带来了易于维护和安全等优点。端用户设备因为故障而停机时也不会影响其它端用户间的通信。同时它的网络延迟时间较小,传输误差较低。 整个网络设备都连接在H3C SMB-S1626-PWR中心交换机上,由路由器划分VLAN,开启DHCP 服务和DHCP-Snooping,DHCP-Snooping会对DHCP报文进行侦听,并可以从接收到的DHCP Request 或DHCP Ack报文中提取并记录IP地址和MAC地址信息,建立和维护一张dhcp-snooping的绑定表,通过这张表来判定ip或者mac地址是否合法,完成交换机对假冒DHCP Server的屏蔽作用,确保客户端从合法的DHCP Server获取IP地址。 3.连线端口指南 a)首先是我们的AP,因需要POE供电所以插在带有的POE标示的LAN端口,另外一端连 接交换机的端口3/4,

相关主题
文本预览
相关文档 最新文档