首页
|
新闻
|
新品
|
文库
|
方案
|
视频
|
下载
|
商城
|
开发板
|
数据中心
|
座谈新版
|
培训
|
工具
|
博客
|
论坛
|
百科
|
GEC
|
活动
|
主题月
|
电子展
注册
登录
论坛
博客
搜索
帮助
导航
默认风格
uchome
discuz6
GreenM
»
MCU 单片机技术
»
ARM
» STM32NET学习笔记 ARP和Ethernet部分
返回列表
回复
发帖
发新话题
发布投票
发布悬赏
发布辩论
发布活动
发布视频
发布商品
STM32NET学习笔记 ARP和Ethernet部分
发短消息
加为好友
yuyang911220
当前离线
UID
1029342
帖子
9914
精华
0
积分
4959
阅读权限
90
在线时间
286 小时
注册时间
2014-5-22
最后登录
2017-7-24
论坛元老
UID
1029342
性别
男
1
#
打印
字体大小:
t
T
yuyang911220
发表于 2015-3-28 10:17
|
只看该作者
STM32NET学习笔记 ARP和Ethernet部分
嵌入式以太网开发是一个很有挑战性的工作。通过几个月的学习,个人觉得大致有两条途径。第一条途径,
通过高级语言熟悉socket编程
,例如C#或C++,熟悉bind,listen,connect,accept等函数,在嵌入式系统中应用 lwIP协议栈。第二种途径,通过分析嵌入式以太网代码,
结合TCPIP协议栈规范逐步实践协议栈代码
。第一种途径效率高,开发周期短,编写出来的代码性能稳定,第二种途径花的时间长,开发出来的代码功能不完善,
但是由于紧紧结合TCPIP规范,可以了解的内容较多,适合学习
。本文通过分析和修改AVRNET源码并移植到STM32平台,逐步实现TCPIP协议栈的各个子部分,包括ETHERNET部分,ARP部分,IP部分,ICMP部分,UDP部分,TCP部分和HTTP部分。
【
STM32NET学习笔记——索引
】【
代码仓库
】
本文先实现ethernet部分和ARP部分。
1.2 其他说明
【硬件平台】 STM32+ENC28J60
【编译平台】 IAR 6.5
【IP地址】在实践之前,需要通过ipconfig命令查看PC机的IP地址和MAC地址,AVR的IP地址设定必须和PC机在同一个网段中。例如 :
PC机IP:192.168.1.102
AVR IP: 192.168.1.115
【局域网访问 】
如果有STM32开发板或者其他CPU的开发板的话,可以把开发板的以太网端口连接到路由器LAN端口,只要保证开发板的IP地址和PC机的IP地址在同一个网段。
【广域网访问 】
如果有固定的电信网IP地址的话,可以在路由器中设置静态端口映射,把某个端口映射成局域网内的IP地址和端口号。若没有固定IP地址的话,可使用
花生壳软件虚拟一个域名
。
1.3 代码仓库
【
代码仓库
】——CSDN Code代码仓库。
2.初始化
以太网协议栈的实现离不开以太网驱动芯片。以太网驱动如何实现请参考——
ENC28J60学习笔记
。TCPIP的实现离不开两个基本地址,IP地址和MAC地址。在本例中通过以下代码定义和实现。
struct.h头文件中 相关定义:
[cpp]
view plain
copy
// MAC地址结构体
#pragma pack(1)
typedef
struct _MAC_ADDR
{
BYTE byte[6];
}MAC_ADDR;
// IP地址结构体
#pragma pack(1)
typedef
struct _IP_ADDR
{
BYTE byte[4];
}IP_ADDR;
main.c函数中的初始化代码:
[cpp]
view plain
copy
// 初始化MAC地址
stm32_mac.byte[0] = 'S';
stm32_mac.byte[1] = 'T';
stm32_mac.byte[2] = 'M';
stm32_mac.byte[3] = 'N';
stm32_mac.byte[4] = 'E';
stm32_mac.byte[5] = 'T';
// 初始化IP地址,固定IP地址
stm32_ip.byte[0] = 192;
stm32_ip.byte[1] = 168;
stm32_ip.byte[2] = 1;
stm32_ip.byte[3] = 115;
MAC地址和IP地址均为自定义的结构体,结构体中为一个字节数组。严格来说,MAC地址不能胡乱定义,应严格遵守相关规范,如果条件允许的话可以使用
带有全球唯一的MAC地址的EEPROM芯片
。
3.实现ETHERNET
TCPIP是一系列协议的组合,其中最有名的为TCP协议和IP协议。但是千万不要忽视最底层的协议结构——ETHERNET。ETHERNET包括14个字节,称之为以太网首部,其中前六个字节为目标MAC地址,紧着的6个字节为源MAC地址,最后的两个字节为协议类型。以太网的实现通信时必须要知道双方的MAC地址,发送方不明确接收方的地址便通过ARP协议寻找目标MAC地址,如果依然没有结果则可只能把该报文转发给路由器,让路由器处理该报文。协议类型只需关心两种,0800的IP协议和0806的ARP协议。
ethernet.h中相关宏定义
[cpp]
view plain
copy
// 协议类型 ARP报文
#define ETH_TYPE_ARP_V 0x0806
#define ETH_TYPE_ARP_H_V 0x08
#define ETH_TYPE_ARP_L_V 0x06
// 协议类型 以太网报文
#define ETH_TYPE_IP_V 0x0800
#define ETH_TYPE_IP_H_V 0x08
#define ETH_TYPE_IP_L_V 0x00
// 以太网报文头部长度 14
#define ETH_HEADER_LEN 14
// 目标MAC地址
#define ETH_DST_MAC_P 0
// 源MAC地址
#define ETH_SRC_MAC_P 6
// 协议类型
#define ETH_TYPE_H_P 12
#define ETH_TYPE_L_P 13
ethernet.c中相关函数
[cpp]
view plain
copy
void eth_generate_header ( BYTE *rxtx_buffer, WORD_BYTES type, BYTE *dest_mac )
{
BYTE i;
// 配置以太网报文 目标MAC地址和源MAC地址
for ( i=0; i<sizeof(MAC_ADDR); i++)
{
rxtx_buffer[ ETH_DST_MAC_P + i ] = dest_mac
;
// avr_mac为全局变量
rxtx_buffer[ ETH_SRC_MAC_P + i ] = stm32_mac.byte
;
}
// 配置协议类型 IP报文或ARP报文
rxtx_buffer[ ETH_TYPE_H_P ] = type.byte.high;
rxtx_buffer[ ETH_TYPE_L_P ] = type.byte.low;
}
eth_generate_header函数实现了填充以太网首部的功能,
第一个输入参数为发送接收缓冲区。第二个参数为IP类型,在AVRNET项目中传入的参数不是0800的IP协议类型就是0806的ARP协议类型。第三个参数为目标MAC地址,由于本机MAC地址作为了全局变量,可以在函数内部填充到缓冲区中。
收藏
分享
评分
继承事业,薪火相传
回复
引用
订阅
TOP
返回列表
电商论坛
Pine A64
资料下载
方案分享
FAQ
行业应用
消费电子
便携式设备
医疗电子
汽车电子
工业控制
热门技术
智能可穿戴
3D打印
智能家居
综合设计
示波器技术
存储器
电子制造
计算机和外设
软件开发
分立器件
传感器技术
无源元件
资料共享
PCB综合技术
综合技术交流
EDA
MCU 单片机技术
ST MCU
Freescale MCU
NXP MCU
新唐 MCU
MIPS
X86
ARM
PowerPC
DSP技术
嵌入式技术
FPGA/CPLD可编程逻辑
模拟电路
数字电路
富士通半导体FRAM 铁电存储器“免费样片”使用心得
电源与功率管理
LED技术
测试测量
通信技术
3G
无线技术
微波在线
综合交流区
职场驿站
活动专区
在线座谈交流区
紧缺人才培训课程交流区
意见和建议