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 Sangstbk Xem bài viết
    Em cám ơn anh Tâm rất nhiều, em chuyển sang codevision đã chạy rồi anh ạ. Em làm ứng dụng truyền dữ liệu nên chỉ làm đến lớp ICMP thôi ạ. Em đã ping được, đã đưa dữ liệu vào trong buffer của hàm IPSend để truyền đi (hix, em vẫn chưa test dữ liệu nhận sau khi gửi). Cám ơn anh nhiều
    Hay quá, bạn là người đầu tiên chuyển project này sang codevision thành công đó. Nếu được thì chia sẽ với mọi người nhé.

    Comment


    • Hi, cám ơn anh, em đang chuẩn hóa lại chút nữa, xong xuôi em sẽ post lên để mọi người cùng chia sẻ

      Có 1 vấn đề em thấy rất lạ là khi em dùng hàm IPSend

      void ipSend(unsigned long dstIp, unsigned char protocol, unsigned int len, unsigned char* ipData)
      {
      struct ntEthHeader* ethHeader;
      struct ntIPHeader* ipHeader;
      ipHeader = (struct ntIPHeader*)(ipData - IP_HEADER_LEN);
      ethHeader = (struct ntEthHeader*)(ipData - IP_HEADER_LEN - ETH_HEADER_LEN);
      len += IP_HEADER_LEN;

      ipHeader->desIPAddr = HTONL(dstIp);
      ipHeader->srcIPAddr = HTONL(IpMyConfig.ip);
      ipHeader->Protocol = protocol;
      ipHeader->Len = HTONS(len);
      ipHeader->verHdrLen = 0x45;
      ipHeader->ToS = 0;
      ipHeader->IDNumber = 0;
      ipHeader->Offset = 0;
      ipHeader->TTL = IP_TIME_TO_LIVE;
      ipHeader->Checksum = 0;

      ipHeader->Checksum = ipChecksum((unsigned char*)ipHeader, IP_HEADER_LEN);
      if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) )
      {
      arpIpOut((unsigned char*)ethHeader,0); // local send
      }
      else
      {
      arpIpOut((unsigned char*)ethHeader,IpMyConfig.gateway); // gateway send
      }
      len += ETH_HEADER_LEN;
      //#ifdef IP_DEBUG
      uart_putstr("Sending IP packet\r\nAddr: ");
      ipPrintAddr(dstIp);
      uart_putstr("\n\rMAC: ");
      ethPrintAddr(&(ethHeader->desAddr));
      uart_putstr("\n\r");
      //#endif
      ethSendFrame(len, (unsigned char*)ethHeader);
      }

      Em khai báo 1 biến unsigned long desAddress và truyền tham số vào hàm

      Tuy nhiên, khi em desAddress này lên trước và sau 2 lệnh:

      ipHeader->desIPAddr = HTONL(dstIp);
      ipHeader->srcIPAddr = HTONL(IpMyConfig.ip);

      thì giá trị lại đảo cho

      (VD: Bên trên: 192.168.1.11 thì put bên dưới lại là 11.1.168.192)

      Nhưng khi em ko dùng truyền tham số vào dstIp mà em sử dụng trực tiếp biến desAddress thì không xảy ra lỗi ấy

      Em sử dụng cách thứ 2 để không gặp lỗi ấy, cứ 5s em gọi hàm ipSend 1 lần và truyền đi. Tuy nhiên em dùng phần mềm Network monitor ở IP nhận thì không thấy dữ liệu truyền tới. Trong khi từ máy nhận ping đến vẫn reply bình thường. Em chưa biết cần thêm trường hay gì vào để bên nhận có thể nhận được. Mọi người giúp em với ạ. Xong cái này là hoàn thiện em sẽ post lên anh em cùng chia sẻ ạ

      Comment


      • Nguyên văn bởi nttam79 Xem bài viết
        Trong code của project trên thì không có code ghép data lớp ứng dụng lại, mà chỉ có code chia data ra. Vì trong project trên, AVR đóng vai trò HTTP server, nó gửi dữ liệu đi thì nhiều (nội dung website) nhưng nhận dữ liệu thì ít (chỉ nhận các bản tin HTTP request, gồm HTTPGet và HTTPPost).
        Tuy nhien việc ghép data lại cũng dễ thôi, em có thể tự viết phần này, dựa vào dữ liệu trong một phiên kết nối TCP và số sequence.
        Trong trường hợp em dùng UDP thì trong dữ liệu của em phải có đánh số thứ tự dữ liệu (do em tự qui định) vì trong giao thức UDP không có đánh số thứ tự các segment dữ liệu, nên thông thường ta phải dựa vào thông tin của giao thức lớp ứng dụng để ghép dữ liệu lại (RTP là một ví dụ).
        Chúc em thành công.
        Em hấp tấp xem cấu trúc gói UDP thì tưởng nhầm là max size của data UDp chỉ là 64*4 nên câu hỏi của em rất chi là ngô nghê. Em cứ nghĩ với những câu hỏi làm loãng topic như thế thì thầy sẽ không trả lời. Nhưng thầy vẫn giải đáp cặn kẽ.
        Em cảm ơn thầy ạ.

        Comment


        • Nguyên văn bởi nttam79 Xem bài viết
          Tôi cũng có làm về FPGA trên chip của Xilinx với ngôn ngữ VHDL và Verilog, nếu cần em cứ hỏi
          Anh Tâm đã làm trên fpga rùi ag? e đang tính làm trên board của xillinx. cho e hỏi là lập trình nó trên fpga thì cũng tương tự như trên vi điều khiển phải ko anh, nghĩa là tương ứng với các source file thì ta thiết kế một module trên đó. E không biết thế có đúng ko?

          Comment


          • Em đang định chuyển sang viết cho PIC bằng CCS từ code mà anh Tâm hướng dẫn, nhưng có một số chỗ thì chưa biết chuyển thế nào:
            - Cách lưu mảng dữ liệu vào flash ROM của PIC (so với AVR):
            Code:
            prog_char enc28j60_config[44] PROGMEM = {
            	ETXSTL, LO8(TXSTART_INIT), //start lo
            	ETXSTH, HI8(TXSTART_INIT), //start hi
            	ETXNDL, LO8(TXSTOP_INIT  ), //end lo
            	ETXNDH, HI8(TXSTOP_INIT  ), //end hi
            
            	ERXSTL, LO8(RXSTART_INIT), //start lo
            	ERXSTH, HI8(RXSTART_INIT), //start hi
            	ERXNDL, LO8(RXSTOP_INIT  ), //end lo
            	ERXNDH, HI8(RXSTOP_INIT  ), //end hi
            
            	MACON2, 	0x00,
            	MACON1, 	(MACON1_MARXEN | MACON1_RXPAUS | MACON1_TXPAUS),
            	MACON3, 	( MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN),
            	MAMXFLL, LO8(1518),
            	MAMXFLH, HI8(1518),
            	MABBIPG, 0x12, //half duplex
            	MAIPGL,  0x12,
            	MAIPGH,  0x0C, //half duplex
            
            	MAADR5, ENC28J60_MAC0,
            	MAADR4, ENC28J60_MAC1,
            	MAADR3, ENC28J60_MAC2,
            	MAADR2, ENC28J60_MAC3,
            	MAADR1, ENC28J60_MAC4,
            	MAADR0, ENC28J60_MAC5
            	};
            - Cách truyền tham số con trỏ hàm :
            Code:
            void   TCPCreateSession(unsigned int16  sourcePort, prog_void* appService);
            - Và cách lưu dữ liệu trang web vào bộ nhớ chương trình.

            Comment


            • Nguyên văn bởi chikichita Xem bài viết
              hixhix đang làm thêm phần điều khiển từ xa bằng RF mà ko biết phải làm thế nào cả, lên mạng tìm hiểu mua về cặp PT2262-PT2272 làm testboard cũng pó tay, ra nhật tảo mua cặp thu phát về xem mà thảm sầu vô biên, mạch toàn linh kiện dán không nhìn thấy mạch thế nào để tìm hiểu cả. Pótay.com rồi
              Đây là schematic mạch RF dùng cặp PT 2262-2272. Mình gửi cho mọi người làm để cùng phát triển topic này.
              2262-2272.zip

              Comment


              • Thầy ơi, có chỗ này em không hiểu, xin thầy giải đáp cho em:
                Em đang viết 1 giao thức chạy qua UDP, em thấy có 1 vấn đề là khi nhận được 1 bản tin và phải đáp ứng lại 1 bản tin thì bản tin nhận đc đang nằm trên buffer và bản tin đáp ứng phải đc viết nháp ở 1 vùng nhớ khác rồi copy về vùng nhớ bắt đầu bởi ethGetBuffer() + ETH_HEADER_LEN + IP_HEADER_LEN + 8. Mà RAM của ATmega32 khá nhỏ => phải viết trên ROM, nhưng ROM là bộ nhớ chỉ đọc, vậy viết nháp nó như thế nào ạ?
                Mà sao em vẫn dùng hàm strcat() với chuỗi prog_char mà không báo lỗi ạ?
                Xin thầy giúp em với.
                Em cám ơn thầy ạ.

                Comment


                • thanks bạn nhiều, bạn có thể gửi lại file capture đầy đủ ko vì chỉ mỗi file này mở ko lên dc , mấy ngày qua bận nhiều dự án cho công ty quá hết đi sóc trăng, đồng nai, rồi lại gia lai, làm mình không có thời gian làm tiếp nữa, hihi, chắc cuối tuần này sẽ cố gắng hoàn thành phần điều khiển từ xa cho cái mạch mình thêm sinh động.
                  Nguyên văn bởi mhl167 Xem bài viết
                  Đây là schematic mạch RF dùng cặp PT 2262-2272. Mình gửi cho mọi người làm để cùng phát triển topic này.
                  [ATTACH]50446[/ATTACH]
                  Last edited by chikichita; 22-08-2012, 17:15.

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

                  Comment


                  • Hồi đó mình vẽ bằng Eagle nên không mở được bằng Orcad. Mạch RF này mình làm đã chạy nhưng bạn nên thay đổi giá trị tụ pi và số vòng cuộn dây để được khoảng cách xa nhất nhé.
                    Mình cũng đang xem code của bạn và anh Tâm mà thấy hơi khó vì mình không rành phần giao thức mạng internet. Nên có gì bạn hướng dẫn giúp nhé.

                    Comment


                    • Các anh ơi, cho em hỏi vài điều:
                      1) Trong hàm httpHeaderGetField(), thầy Tâm tính headerLen = (rqst->header) - (rqst->body) - 4;
                      Em nghĩ kết quả của nó là số âm. Vậy sao vẫn dùng được ạ?
                      2) Biến lưu trong Program Memory (kiểu prog_char) thì dùng hàm nào để thay đổi giá trị của nó ạ? Em đọc thư viện pgmspace.h với user_manual mà không thấy nói gì đến. Liệu nó có thể thay đổi đựoc không ạ? Hay là thay đổi nó hoàn toàn giống với biến trong SRAM? Em dùng ATmega32.
                      Xin các anh chỉ giáo. Tks

                      Comment


                      • Nguyên văn bởi Sangstbk Xem bài viết
                        Có 1 vấn đề em thấy rất lạ là khi em dùng hàm IPSend
                        Em khai báo 1 biến unsigned long desAddress và truyền tham số vào hàm
                        Tuy nhiên, khi em desAddress này lên trước và sau 2 lệnh:
                        ipHeader->desIPAddr = HTONL(dstIp);
                        ipHeader->srcIPAddr = HTONL(IpMyConfig.ip);
                        thì giá trị lại đảo cho

                        (VD: Bên trên: 192.168.1.11 thì put bên dưới lại là 11.1.168.192)
                        Nhưng khi em ko dùng truyền tham số vào dstIp mà em sử dụng trực tiếp biến desAddress thì không xảy ra lỗi ấy
                        Macro HTONL() dùng để đảo thứ tự các byte trong 1 số long interger. Lý do phải dùng nó là trong bộ nhớ AVR, trình biên dịch AVR studio sắp thứ tự các byte ngược với thứ tự qui định trong IP header. Ví dụ trong IP header, các byte của địa chỉ IP sắp theo thứ tự là 192.168.1.10, thì khi lưu dưới dạng số long interger trong ATmega lại là theo thứ tự ngược lại.
                        Vấn đề em gặp chắc liên quan đến chỗ này. nhưng chắc em phải post code cả 2 trường hợp lên thì mới giải thích được, vì đoc mô tả vẫn chưa hiểu rõ lắm.

                        Comment


                        • Nguyên văn bởi joystick Xem bài viết
                          Anh Tâm đã làm trên fpga rùi ag? e đang tính làm trên board của xillinx. cho e hỏi là lập trình nó trên fpga thì cũng tương tự như trên vi điều khiển phải ko anh, nghĩa là tương ứng với các source file thì ta thiết kế một module trên đó. E không biết thế có đúng ko?
                          Anh có dùng FPGA nhưng cho các project khác, không phải project này và cũng không làm TCP/IP trên FPGA.
                          Nguyên văn bởi joystick Xem bài viết
                          Em đang định chuyển sang viết cho PIC bằng CCS từ code mà anh Tâm hướng dẫn, nhưng có một số chỗ thì chưa biết chuyển thế nào:
                          - Cách lưu mảng dữ liệu vào flash ROM của PIC (so với AVR):
                          - Cách truyền tham số con trỏ hàm :
                          Code:
                          void   TCPCreateSession(unsigned int16  sourcePort, prog_void* appService);
                          - Và cách lưu dữ liệu trang web vào bộ nhớ chương trình.
                          Khai biến thuộc bộ nhớ chương trình: cái này phụ thuộc trình biên dịch chứ không phải là do PIC hay AVR. Trong CCS thì hình như là: byte const str_[10]="....";
                          Với PIC anh thường dùng MPLAB với c18, c30,... chứ không dùng CCS, nên không chắc lắm.

                          Comment


                          • Nguyên văn bởi dhp11591 Xem bài viết
                            Các anh ơi, cho em hỏi vài điều:
                            1) Trong hàm httpHeaderGetField(), thầy Tâm tính headerLen = (rqst->header) - (rqst->body) - 4;
                            Em nghĩ kết quả của nó là số âm. Vậy sao vẫn dùng được ạ?
                            2) Biến lưu trong Program Memory (kiểu prog_char) thì dùng hàm nào để thay đổi giá trị của nó ạ? Em đọc thư viện pgmspace.h với user_manual mà không thấy nói gì đến. Liệu nó có thể thay đổi đựoc không ạ? Hay là thay đổi nó hoàn toàn giống với biến trong SRAM? Em dùng ATmega32.
                            Xin các anh chỉ giáo. Tks
                            1-Chỗ này dường như tôi sai: phải là headerLen = (rqst->body) - (rqst->header) - 4;
                            Vẫn được vì headerLen khai báo là unsigned và chỉ dùng để giới hạn số byte tìm kiếm, chỉ có là phải tìm lâu hơn thôi.
                            2-Biến lưu trong Program Memory về nguyên tắc là không thay đổi được (thực ra trong AVR vẫn có thể dùng lệnh ghi flash để thay đổi nó). Nếu đã muốn thay đổi thì không nên khai báo thuộc Program Memory.

                            Comment


                            • Nguyên văn bởi dhp11591 Xem bài viết
                              Thầy ơi, có chỗ này em không hiểu, xin thầy giải đáp cho em:
                              Em đang viết 1 giao thức chạy qua UDP, em thấy có 1 vấn đề là khi nhận được 1 bản tin và phải đáp ứng lại 1 bản tin thì bản tin nhận đc đang nằm trên buffer và bản tin đáp ứng phải đc viết nháp ở 1 vùng nhớ khác rồi copy về vùng nhớ bắt đầu bởi ethGetBuffer() + ETH_HEADER_LEN + IP_HEADER_LEN + 8. Mà RAM của ATmega32 khá nhỏ => phải viết trên ROM, nhưng ROM là bộ nhớ chỉ đọc, vậy viết nháp nó như thế nào ạ?
                              Mà sao em vẫn dùng hàm strcat() với chuỗi prog_char mà không báo lỗi ạ?
                              Xin thầy giúp em với.
                              Em cám ơn thầy ạ.
                              Không nên viết nháp gì cả: khi nhận bản tin đến trong buffer, em xử lý và lưu lại các giá trị cần thiết xong -> bản tin trả lời ghi dè lên luôn trên buffer.

                              Comment


                              • Em cảm ơn thầy ạ.
                                Em cũng vừa viết lại theo cách đó. Em đang viết SIP, viêt 9 lần rồi mà chưa thành công hẳn hoi.
                                Mà em cũng chưa hiểu, nếu lưu data vào PROGMEM thì làm sao cập nhật được ạ? Ý em là khi khai báo 1 mảng (1 vùng nhớ) cho 1 bộ đệm lưu những thứ cần thiết, thì phải khởi tạo luôn cho nó. Mà đã khởi tạo rồi thì không cập nhật được ạ. Em dịch, nó cứ báo lỗi read-only
                                Cuối cùng, em đành ngậm ngùi lưu qua EEPROM, chấp nhận cái giới hạn 100.000 lần ghi/xóa của nó để có cái đề mô
                                Vậy là đến giai đoạn bật wireshark bắt gói nghiền ngẫm như chuyên gia, có điều em nghiền 1 hồi mà vẫn chưa ngẫm ra tại sao bản tin của em lại có chỗ bị bôi vàng chóe????
                                Có phải do trong các URL, em viết thừa port 5060 của nó không ạ? Nhũng chỗ nào nên viết, nhưng chỗ nào không đựoc viết, xin thầy chỉ bảo cho em.

                                Hix, nếu post của em làm loãng 2pic, xin thầy và các anh thông cảm. Xin MOD đừng động đến

                                //-----------------------------------------
                                //Hóa ra header của SIP cũng kết thúc bằng 1 dòng trống, em không có cái đấy, wireshark nó chỉ cho mà lúc nãy không chịu đọc
                                Last edited by dhp11591; 24-08-2012, 18:25.

                                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