Tiếp theo, để có thể chạy thử giao thức DHCP, chúng ta cần modify source cũ một tí để bổ sung giao thức này vào:
1-Mở file “timer.h” sửa define cho prescale của timer thành 1024 để timer chạy đúng, ngắt 1s/lần (với thạch anh 12MHz nha các bạn):
2-Mở file “udp.c”, sửa hàm udpSend để bổ sung source port vào trong hàm, thêm lệnh gọi hàm của giao thức DHCP vào hàm UDPProcess:
(Nhớ cập nhật khai báo hàm bên file header nha)
3-Thêm một số include (khi dịch báo lỗi thì các bạn cũng tự tìm ra mà thêm vào thôi, chỉ luôn cho đỡ mắc công kiếm):
#include <avr/pgmspace.h>//// vào “tcp.h”
#include "dhcp.h"//// vào “ntAVRnet.h”
#include "udp.h" và #include "icmp.h" vào “ip.h”
4-Sửa hàm IPProcess, thêm các lệnh gọi hàm của giao thức UDP, TCP vào:
5-Mở hàm ngắt timer 1 (trong file timer.h), thêm vào các hàm cập nhật thời gian của giao thức TCP và DHCP vào:
6-Thêm vào hàm main trong file “ntAVRnet.h”
Bây giờ nếu lúc đầu mạch của ta chưa có địa chỉ IP (IP address là 0.0.0.0) thì nó sẽ khởi tạo giao thức DHCP để nhận địa chỉ IP.
Để thử, ta chỉnh lại các thông số cấu hình IP trong file “ntAVRnet.h” như sau:
Bây giờ ta có thể biên dịch, nối cáp mạng và mở nguồn, đợi board nhận địa chỉ IP (nhớ kết nối cổng COM để còn biết nó nhận được địa chỉ bao nhiêu nhé).
Phần code này chỉ khởi động DHCP lúc mới reset mạch thôi nhé, chưa hỗ trợ hot plug cáp mạng . Các bạn có thể tự sửa code để thêm phần này vào.
1-Mở file “timer.h” sửa define cho prescale của timer thành 1024 để timer chạy đúng, ngắt 1s/lần (với thạch anh 12MHz nha các bạn):
Code:
#define TIMER1PRESCALE TIMER_CLK_DIV1024
Code:
//---------------------------------------------------------------------------- // Writen by NTTam - PTITHCM //---------------------------------------------------------------------------- #include "packet.h" #include "ip.h" #include "uart.h" #include "dhcp.h" //#define UDP_DEBUG //---------------------------------------------------------------------------- //Ham gui di mot goi UDP void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned int srcPort, unsigned int len, unsigned char* udpData) { struct ntUDPHeader* udpHeader; udpHeader = (struct ntUDPHeader*)(udpData - UDP_HEADER_LEN); len += UDP_HEADER_LEN; udpHeader->desPort = HTONS(dstPort); udpHeader->srcPort = HTONS(srcPort); udpHeader->Len = HTONS(len); udpHeader->Checksum = 0; ipSend(dstIp, IP_PROTO_UDP, len, (unsigned char*)udpHeader); } //-------------------------------------------------------------------------------------- //Ham xu ly goi UDP nhan duoc, duoc goi boi ham xu ly goi IP (IPProcess) // Hien chua co ung dung chay UDP nen ham nay trong void UDPProcess(unsigned int len, struct ntIPHeader* packet) { dhcpIn((len - IP_HEADER_LEN - UDP_HEADER_LEN), (struct netDhcpHeader*)((char*)packet + IP_HEADER_LEN + UDP_HEADER_LEN)); #ifdef UDP_DEBUG printf("Rx UDP Packet\r\n"); #endif } //--------------------------------------------------------------------------------------
3-Thêm một số include (khi dịch báo lỗi thì các bạn cũng tự tìm ra mà thêm vào thôi, chỉ luôn cho đỡ mắc công kiếm):
#include <avr/pgmspace.h>//// vào “tcp.h”
#include "dhcp.h"//// vào “ntAVRnet.h”
#include "udp.h" và #include "icmp.h" vào “ip.h”
4-Sửa hàm IPProcess, thêm các lệnh gọi hàm của giao thức UDP, TCP vào:
Code:
void IPProcess(unsigned int len, struct ntIPHeader* packet) { // check IP addressing, stop processing if not for me and not a broadcast if( (HTONL(packet->desIPAddr) != ipGetConfig()->ip) && (HTONL(packet->desIPAddr) != (ipGetConfig()->ip|ipGetConfig()->netmask)) && (HTONL(packet->desIPAddr) != 0xFFFFFFFF) && (ipGetConfig()->ip != 0x00000000) ) return; // handle ICMP packet if( packet->Protocol == IP_PROTO_ICMP ) { #ifdef IP_DEBUG printf("IP->Rx: ICMP/IP packet\r\n"); //icmpPrintHeader((icmpip_hdr*)packet); #endif icmpIpIn((struct ntIPHeader*)packet); } else if( packet->Protocol == IP_PROTO_UDP ) { #ifdef IP_DEBUG printf("IP->Rx: UDP/IP packet\r\n"); //debugPrintHexTable(NetBufferLen-14, &NetBuffer[14]); #endif UDPProcess(len, ((struct ntIPHeader*)packet) );//// } else if( packet->Protocol == IP_PROTO_TCP ) { #ifdef IP_DEBUG printf("IP->Rx: TCP/IP packet\r\n"); #endif TCPProcess((unsigned char *)packet,len-((packet->verHdrLen & 0x0F)<<2));//// } else { #ifdef IP_DEBUG printf("IP->Rx: IP packet\r\n"); #endif } } //--------------------------------------------------------------------------------------
Code:
TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) { //Tai nap gia tri timer 1 TCNT1 = 0xFFFF - TIMER1_INTERVAL; //Cap nhat watchdog timer if((time_watchdog++) > 120){ time_watchdog = 0; ethInit(); } Counter1s++; arpTimer(); TCPCheckTimeOut();//// dhcpTimer();//// }
Code:
int main() { SystemInit(); printf("\r\nNTTam AVR network testing with enc28j60.\r\n"); printf("Initializing Network Interface and Stack\r\n"); printf("Ethernet chip init\r\n"); IpMyConfig.ethaddr.addr[0] = ETHADDR0; IpMyConfig.ethaddr.addr[1] = ETHADDR1; IpMyConfig.ethaddr.addr[2] = ETHADDR2; IpMyConfig.ethaddr.addr[3] = ETHADDR3; IpMyConfig.ethaddr.addr[4] = ETHADDR4; IpMyConfig.ethaddr.addr[5] = ETHADDR5; IpMyConfig.ip = IPADDRESS; IpMyConfig.netmask = NETMASK; IpMyConfig.gateway = GATEWAY; netInit(IpMyConfig.ip, IpMyConfig.netmask, IpMyConfig.gateway); PrintIPConfig(); printf("Getting IP Address....\r\n"); if(IpMyConfig.ip == 0x00000000){ dhcpInit(); } while(1) { ethService(); dhcpService(); } return 0; }
Để thử, ta chỉnh lại các thông số cấu hình IP trong file “ntAVRnet.h” như sau:
Code:
#define IPDOT(a,b,c,d) ((unsigned long)((unsigned char)a)<<24)+((unsigned long)((unsigned char)b)<<16)+((unsigned long)((unsigned char)c)<<8)+(unsigned char)d//((a<<24)|(b<<16)|(c<<8)|(d)) //#define IPADDRESS IPDOT(192,168,1,10) #define IPADDRESS IPDOT(0,0,0,0) #define NETMASK IPDOT(0,0,0,0) #define GATEWAY IPDOT(0,0,0,0)
Phần code này chỉ khởi động DHCP lúc mới reset mạch thôi nhé, chưa hỗ trợ hot plug cáp mạng . Các bạn có thể tự sửa code để thêm phần này vào.
Comment