Thông báo

Collapse
No announcement yet.

Giao thức TCP/IP và Web server với AVR

Collapse
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Nguyên văn bởi nacdanh90 Xem bài viết
    Vâng ạ! Em cảm ơn thầy. E quên mất con số 64 đó trong hình vẽ của thầy.hi. Nhưng e xem lại data sheets của enc28j60 đoạn SAMPLE RECEIVE PACKET LAYOUT phần Packetdata nó gồm: Destination Address,Source Address,type/Length, Data. Vậy thì trong hàm enc28j60PacketReceive thầy gán biến len=các bit từ 0..15 của RECEIVE STATUS VECTORS thì đây được coi là chiều dài của riêng phần data(+padding thêm vào cho đủ 64byte nếu data <64byte) chứ không tính chiều dài của các trường Destination Address,Source Address,type/Length ạ?Nếu theo như giải thích bên trên của thầy thì em hiểu như vậy!Ko biết có đúng không ạ?

    Em hỏi về vấn đề này hơi kĩ mong thầy và các anh thông cảm! Em chưa muốn chuyển sang tầng khác trong khi tầng đầu tiên chưa hiểu rõ bản chất!
    Biến len = (Destination Address + Source Address + type/Length + Data) được trả từ hàm enc28j60PacketReceive->ethGetFrame->ethService.
    Trong hàm ethService, biến len được trừ đi phần Ethernet Header (= Destination Address + Source Address + type/Length = 6 + 6 +2 = 14 bytes) và truyền sang hàm IPProcess:
    Code:
    IPProcess( len-ETH_HEADER_LEN, (struct ntIPHeader*)&ethBuffer[ETH_HEADER_LEN] );
    Vậy biến len trong hàm IPProcess và arpArpProcess đã được trừ đi 14 bytes ethernet header (tức là phần Destination Address,Source Address,type/Length).

    Comment


    • Vâng! Tại vì em thấy trong hình:
      TCP/IP over Ethernet: Layer 2
      Theo hình trên 64 byte(min) đó là gồm cả Destination Address + Source Address + type/Length+ CRC còn trong hình trên bài của thầy là 64byte min đó nó chỉ là độc phần data nên em thấy hơi mâu thuẫn nhau.

      hi. May quá có thầy giải thích làm em "sáng" ra nhiều vấn đề mà em thắc mắc.
      Tiện đây thầy cho em hỏi nốt một vấn đề này: biến len được trả về từ hàm enc28j60PacketReceive nó có gồm cả chiều dài của 4 byte CRC ko ạ? Theo như thầy hướng dẫn ở đầu thì Enc28j60 nó tự lược bỏ đi phần này. Nhưng trong hình trên thì cộng cả 4 byte CRC vào Ethernet Frame mới có chiều dài là 64byte.
      Last edited by nacdanh90; 28-03-2012, 00:42.

      Comment


      • Đã kiểm tra lại code.
        Trong hình vẽ minh họa tôi gõ nhầm 1 số nên giải thích cho bạn chưa chính xác, giờ xin đính chính lại:
        - Chiều dài phần data max là 1500 bytes, min là 46 bytes (chứ không phải 64, trong hình minh họa gõ nhầm). Đây là theo cấu trúc khung Ethernet II frame (đang dùng phổ biến hiện nay), bạn có thể tham khảo thêm trong tiêu chuẩn IEEE802.3 của IEEE, tại website chính thức của IEEE (http://standards.ieee.org/getieee802...8_section1.pdf).
        - Như vậy khi gửi, dữ liệu sẽ chêm vào cho đủ 46 bytes.
        - Giá trị len mà hàm enc28j60PacketReceive trả về như vậy là chiều dài frame ethernet gồm Destination Address + Source Address + type/Length + Data + CRC sẽ bằng 14 + 46 + 4 = 64 trong trường hợp này.
        - Như vậy bạn gửi giá trị len lên MT là giá trị này chứ không phải giá trị len trong giao thức IP (đã trừ đi phần ethernet header).

        Last edited by nttam79; 28-03-2012, 01:13. Lý do: Thêm ảnh minh họa

        Comment


        • Vâng ạ! Thắc mắc của em đã được thầy giải thích hết! Em làm thầy mất cả buổi tối rồi!hì Em cảm ơn thầy rất nhiều!
          Last edited by nacdanh90; 28-03-2012, 01:16.

          Comment


          • Nguyên văn bởi nttam79 Xem bài viết
            Bạn có thể dùng UDP hay TCP để gửi về cho máy tính có IP tĩnh (hay dựa vào domain name).
            Hi gửi như thế nào vậy anh Tâm?
            EM có tham khảo project avrnet (AVR Portal : AVRnet Ethernet development board), nhưng ở đây chỉ dùng trong mạng LAN thôi, còn khi gửi ra ngoài thì chưa được, mong anh debug dùm đoạn code sau:

            //************************************************** ***************************************
            void client_process ( void )
            {
            WORD dlength;
            // you can change rx,tx buffer size in includes.h
            BYTE rxtx_buffer[MAX_RXTX_BUFFER];

            // wait for send temparature flag is set, this flag set by time_base function (menu.c)
            if ( flag1.bits.send_gps == 0 )
            return;
            // AVR busy now and wait untill transfer data to web browser completed.
            if ( flag1.bits.syn_is_received )
            return;
            // AVR sent temparature to web server but not found web server on port 80
            //if ( flag1.bits.not_found_server )
            // return;
            // send SYN to initial connection
            if ( flag1.bits.syn_is_sent == 0 )
            {
            // start arp
            // server ip was not found on network
            if ( arp_who_is ( rxtx_buffer, (BYTE*)&server_mac, (BYTE*)&server_ip ) == 0 ) //nếu bỏ đoạn check này thì có đôi khi nó gửi ra được sever bên ngoài nhưng không phải lúc nào cũng chui ra được,
            {
            flag1.bits.send_gps = 0;
            lcd_gotoxy(14,2);
            lcd_print_p ( PSTR ( "ERR" ) );

            return;


            }


            // send SYN packet to initial connection
            tcp_send_packet (
            rxtx_buffer,
            (WORD_BYTES){TCP_port}, // destination port
            (WORD_BYTES){1200}, // source port
            TCP_FLAG_SYN_V, // flag
            1, // (bool)maximum segment size
            1, // (bool)clear sequence ack number
            0, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
            0, // tcp data length
            (BYTE*)&server_mac, // server mac address
            (BYTE*)&server_ip ); // server ip address
            flag1.bits.syn_is_sent = 1;
            }


            // get new packet
            dlength = enc28j60_packet_receive( (BYTE*)&rxtx_buffer, MAX_RXTX_BUFFER );

            // no new packet incoming
            if ( dlength == 0 )
            {
            // timeout occured, when SYN has been sent but no response from web server
            // reset send_gps and syn_is_sent flags
            if ( flag1.bits.Timeout )
            {
            flag1.bits.Timeout = 0;
            flag1.bits.send_gps = 0;
            flag1.bits.syn_is_sent = 0;
            lcd_gotoxy(14,2);
            lcd_print_p ( PSTR ( "Err" ) );
            }
            return;
            }

            // check ip packet send to avr or not?
            // accept ip packet only
            if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) == 0 )
            {
            return;
            }

            // check SYNACK flag, after AVR send SYN server response by send SYNACK to AVR
            if ( rxtx_buffer [ TCP_FLAGS_P ] == ( TCP_FLAG_SYN_V | TCP_FLAG_ACK_V ) )
            {
            // send ACK to answer SYNACK

            tcp_send_packet (
            (BYTE*)&rxtx_buffer,
            (WORD_BYTES){TCP_port}, // destination port
            (WORD_BYTES){1200}, // source port
            TCP_FLAG_ACK_V, // flag
            0, // (bool)maximum segment size
            0, // (bool)clear sequence ack number
            1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
            0, // tcp data length
            (BYTE*)&server_mac, // server mac address
            (BYTE*)&server_ip ); // server ip address

            // setup http request to server
            dlength = http_put_request_eng( (BYTE*)&rxtx_buffer );


            // send http request packet
            // send packet with PSHACK
            tcp_send_packet (
            (BYTE*)&rxtx_buffer,
            (WORD_BYTES){TCP_port}, // destination port
            (WORD_BYTES){1200}, // source port
            TCP_FLAG_ACK_V | TCP_FLAG_PSH_V, // flag
            0, // (bool)maximum segment size
            0, // (bool)clear sequence ack number
            0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
            dlength, // tcp data length
            (BYTE*)&server_mac, // server mac address
            (BYTE*)&server_ip ); // server ip address
            return;
            }
            // after AVR send http request to server, server response by send data with PSHACK to AVR
            // AVR answer by send ACK and FINACK to server
            if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_PSH_V) )
            {
            dlength = tcp_get_dlength( (BYTE*)&rxtx_buffer );

            // send ACK to answer PSHACK from server
            tcp_send_packet (
            (BYTE*)&rxtx_buffer,
            (WORD_BYTES){TCP_port}, // destination port
            (WORD_BYTES){1200}, // source port
            TCP_FLAG_ACK_V, // flag
            0, // (bool)maximum segment size
            0, // (bool)clear sequence ack number
            dlength, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
            0, // tcp data length
            (BYTE*)&server_mac, // server mac address
            (BYTE*)&server_ip ); // server ip address

            // send finack to disconnect from web server
            tcp_send_packet (
            (BYTE*)&rxtx_buffer,
            (WORD_BYTES){TCP_port}, // destination port
            (WORD_BYTES){1200}, // source port
            TCP_FLAG_FIN_V|TCP_FLAG_ACK_V, // flag
            0, // (bool)maximum segment size
            0, // (bool)clear sequence ack number
            0, // (bool)calculate new seq and seqack number
            0, // tcp data length
            (BYTE*)&server_mac, // server mac address
            (BYTE*)&server_ip ); // server ip address
            return;
            //menu_flag.bits.send_gps = 0;
            //send_syn = 0;
            }
            // answer FINACK from web server by send ACK to web server
            if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_FIN_V|TCP_FLAG_ACK_V) )
            {
            // send ACK with seqack = 1
            tcp_send_packet (
            (BYTE*)&rxtx_buffer,
            (WORD_BYTES){TCP_port}, // destination port
            (WORD_BYTES){1200}, // source port
            TCP_FLAG_ACK_V, // flag
            0, // (bool)maximum segment size
            0, // (bool)clear sequence ack number
            1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
            0, // tcp data length
            (BYTE*)&server_mac, // server mac address
            (BYTE*)&server_ip ); // server ip address
            // temparature has been sent
            // and wait for next schedule to send temparature
            flag1.bits.send_gps = 0;
            flag1.bits.syn_is_sent = 0;
            //lcd_clear();
            lcd_gotoxy(14,2);
            USART_trans(OK);
            lcd_print_p ( PSTR ( "OK " ) );

            }
            }
            |

            Comment


            • Hi anh Tâm, đoạn code sau để thiết lập kết nối với sever, không biết nếu sever nằm ở bên ngoài thì mình có cần xác định địc chỉ MAC của nó hay không? hay chỉ cần gửi đúng địa chỉ IP thôi vậy?

              // send SYN packet to initial connection
              tcp_send_packet (
              rxtx_buffer,
              (WORD_BYTES){TCP_port}, // destination port
              (WORD_BYTES){1200}, // source port
              TCP_FLAG_SYN_V, // flag
              1, // (bool)maximum segment size
              1, // (bool)clear sequence ack number
              0, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
              0, // tcp data length
              (BYTE*)&server_mac, // server mac address
              (BYTE*)&server_ip ); // server ip address
              flag1.bits.syn_is_sent = 1;
              }

              Mong anh hỗ trợ, xin cảm ơn rất nhiều.
              |

              Comment


              • Em chào thầy và các anh! Thầy và các anh đã làm về project này cho em hỏi về đoạn cảnh báo sau:
                ../ip.c:45: warning: pointer targets in passing argument 1 of 'send_string' differ in signedness
                Ý nghĩa của đoạn cảnh báo trên và cách sửa ra sao ạ ?

                Comment


                • Chào thầy Tâm và các bạn!
                  Mình có vấn đề muốn hỏi ý kiến mọi người. Đó là sau khi đã điều khiển on/off được thiết bị, em muốn điều khiển thêm động cơ DC (nhanh, chậm, trái, phải) thì nên bắt đầu thế nào?

                  Comment


                  • Bạn hàn máy chân port bật tắt led vào board điều khiển động cơ là được chứ gì đâu. vd: Led1 -> trái, Led2 phài, led3 nhanh, led4 chậm

                    Comment


                    • Anh Tâm ơi cho em hỏi. Phần này anh dùng địa chỉ IP để điều khiển là IP động hay IP tĩnh vậy

                      Comment


                      • Em chào thầy và các anh! Thầy và các anh đã làm qua giao thức TCP cho em hỏi một chút ạ! Em thầy ở gói tin Tcp để khởi tạo kết nối có một trường là Option. trường này theo thầy Tâm sẽ là 8bytes. trong đó có chứa MSS. nhưng em thấy trong wireshark lại là 12byte. trong đó có thêm mấy trường nữa ngoại trường MSS như : NOP, window scale. và em thấy header tcp của gói tin tcp syn là 32 byte chứ ko phải là 28 bytes? thầy và các anh có thể giải thích giúp em tại sao ko a?

                        Comment


                        • Nguyên văn bởi nacdanh90 Xem bài viết
                          Em chào thầy và các anh! Thầy và các anh đã làm qua giao thức TCP cho em hỏi một chút ạ! Em thầy ở gói tin Tcp để khởi tạo kết nối có một trường là Option. trường này theo thầy Tâm sẽ là 8bytes. trong đó có chứa MSS. nhưng em thấy trong wireshark lại là 12byte. trong đó có thêm mấy trường nữa ngoại trường MSS như : NOP, window scale. và em thấy header tcp của gói tin tcp syn là 32 byte chứ ko phải là 28 bytes? thầy và các anh có thể giải thích giúp em tại sao ko a?
                          Trường Option trong TCP Header không qui định chiều dài bắt buộc, miễn là phải chẵn 32 bit (nếu không phải chèn thêm Padding vào). Trường data offset sẽ cho ta biết chính xác chiều dài của Header, từ đó ta biết được option dài bao nhiêu. Vì vậy trường Option có thể là 8, 12 byte,... Nội dung chứa trong trường option thì tùy thuộc vào dịch vụ. Tương tự vậy Header TCP của gói syn có thể dài 32 byte (12 byte option).

                          Comment


                          • Nguyên văn bởi BMD2008 Xem bài viết
                            Anh Tâm ơi cho em hỏi. Phần này anh dùng địa chỉ IP để điều khiển là IP động hay IP tĩnh vậy
                            IP động hay tĩnh đều được. Trong file AVRnet.h có phần cấu hình địa chỉ IP, nếu muốn set IP tĩnh, bạn khai báo IP, subnet mask, gateway,... ở đây. Nếu địa chỉ IP set ở đây là 0.0.0.0 thì board sẽ nhận IP động từ DHCP server khi vừa boot lên (chưa hỗ trợ nhận IP động khi cắm cable mạng vào).

                            Comment


                            • Nguyên văn bởi nttam79 Xem bài viết
                              Trường Option trong TCP Header không qui định chiều dài bắt buộc, miễn là phải chẵn 32 bit (nếu không phải chèn thêm Padding vào). Trường data offset sẽ cho ta biết chính xác chiều dài của Header, từ đó ta biết được option dài bao nhiêu. Vì vậy trường Option có thể là 8, 12 byte,... Nội dung chứa trong trường option thì tùy thuộc vào dịch vụ. Tương tự vậy Header TCP của gói syn có thể dài 32 byte (12 byte option).
                              Vâng ạ! hi! Thầy giải thích giúp em một lỗi sau mà em chưa hiểu nguyên nhận: đầu tiên gửi bản tin SYN đến server ở trên internet (seqNum=x,window=700,mss=700,SYN set). em đã nhận đc một bản tin(seqNum=y, window=8192,SYN,ACK set,ACK number=x+1)->bản tin xác nhận của server sau khi server đã nhận đc bản tin đầu tiên em gửi. Em lại gửi tiếp bản tin thứ 2 đến server(seqNum=x+1,window=700,ACK set(SYN=0),ACK number=y+1). Em tưởng sau bước này nếu server nhận đc bản tin thứ 2 nó sẽ mở kết nối TCP nhưng sao nó lại gửi trả lại một bản tin (RST set,window=0 ) ả ! Thầy giải thích giúp em lỗi này với ạ! Và Khi nào server sẽ gửi bản tin RESET tcp ả
                              Last edited by nacdanh90; 18-04-2012, 19:38.

                              Comment


                              • thầy tâm ơi giúp em với nếu mình dùng máy tính từ xa điều khiển về thì chương trình như thế nào ạ. Em đang làm đồ án " thiết kế và thi công mạch điều khiển thiết bị qua internet" vậy nên từ nãy tới giờ em thấy mình toàn phải đi ngược vấn đề ko à, vì ở đây toàn thấy máy tính nhận dữ liệu

                                Điện tử viễn thông - Hutech

                                Comment

                                Về tác giả

                                Collapse

                                nttam79 Tìm hiểu thêm về nttam79

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X