Witam.
Złożyłem układ: ENC28J60 + Atmega32 (bez bufora, konwersji napięć, połączenie bezpośrednie przez SPI), zaprogramowana przykładowym kodem serwerka który wyświetla stronę i pozwala za jej pomocą włączać i wyłączać diodę.
Układ działa, ale bardzo łatwo zawiesić. Na dwa sposoby:
poprzez kilkakrotne odświeżenie strony, np. wciskając F5 na stronie
lub
poprzez wpisanie w kod:
odświeża on stronę co sekundę, działa przez kilka godzin, po czym, strona już się nie wyświetla, problem pojawia się także jeśli za dużo tekstu wpiszę w kod strony. Procesor działa, na ENC widać aktywność.
Jeśli wpiszę np. 60 sekund to układ działa dłuuuugo.
Jest możliwość sprawdzenia czy to nie jest może przepełnienie bufora, jakoś go czyścić do kilka minut?
Nie wiem gdzie jest przyczyna i jak to sprawdzić... czy ktoś ma jakieś pomysły?
Poniżej zamieszczam kod:
Złożyłem układ: ENC28J60 + Atmega32 (bez bufora, konwersji napięć, połączenie bezpośrednie przez SPI), zaprogramowana przykładowym kodem serwerka który wyświetla stronę i pozwala za jej pomocą włączać i wyłączać diodę.
Układ działa, ale bardzo łatwo zawiesić. Na dwa sposoby:
poprzez kilkakrotne odświeżenie strony, np. wciskając F5 na stronie
lub
poprzez wpisanie w kod:
<meta http-equiv='refresh' content='1'/>odświeża on stronę co sekundę, działa przez kilka godzin, po czym, strona już się nie wyświetla, problem pojawia się także jeśli za dużo tekstu wpiszę w kod strony. Procesor działa, na ENC widać aktywność.
Jeśli wpiszę np. 60 sekund to układ działa dłuuuugo.
Jest możliwość sprawdzenia czy to nie jest może przepełnienie bufora, jakoś go czyścić do kilka minut?
Nie wiem gdzie jest przyczyna i jak to sprawdzić... czy ktoś ma jakieś pomysły?
Poniżej zamieszczam kod:
#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include <avr/pgmspace.h>
#include "ip_arp_udp_tcp.h"
#include "enc28j60.h"
#include "timeout.h"
#include "avr_compat.h"
#include "net.h"
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
static uint8_t myip[4] = {192,168,1,3};
#define MYWWWPORT 80
#define MYUDPPORT 1200
#define BUFFER_SIZE 550
static uint8_t buf[BUFFER_SIZE+1];
static char password[]="secret";
uint8_t verify_password(char *str)
{
if (strncmp(password,str,5)==0){
return(1);
}
return(0);
}
int8_t analyse_get_url(char *str)
{
uint8_t loop=1;
uint8_t i=0;
while(loop){
if(password[i]){
if(*str==password[i]){
str++;
i++;
}else{
return(-1);
}
}else{
loop=0;
}
}
if (*str == '/'){
str++;
}else{
return(-3);
}
// check the first char, garbage after this is ignored (including a slash)
if (*str < 0x3a && *str > 0x2f){
// is a ASCII number, return it
return(*str-0x30);
}
return(-2);
}
uint16_t moved_perm(uint8_t *buf)
{
uint16_t plen;
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 301 Moved Permanently\r\nLocation: "));
plen=fill_tcp_data(buf,plen,password);
plen=fill_tcp_data_p(buf,plen,PSTR("/\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"));
plen=fill_tcp_data_p(buf,plen,PSTR("<h1>301 Moved Permanently</h1>\n"));
plen=fill_tcp_data_p(buf,plen,PSTR("add a trailing slash to the url\n"));
return(plen);
}
//////////////////////////////////kod strony internetowej/////////////////////////////////////
uint16_t print_webpage(uint8_t *buf,uint8_t on_off)
{
uint16_t plen;
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"));
plen=fill_tcp_data_p(buf,plen,PSTR("<meta http-equiv='refresh' content='10;url=http://192.168.1.3/secret/' />"));
plen=fill_tcp_data_p(buf,plen,PSTR("<font size=\"7\"><center><p>Output is: "));
if (on_off){
plen=fill_tcp_data_p(buf,plen,PSTR("<font color=\"#00FF00\"> ON</font>"));
}else{
plen=fill_tcp_data_p(buf,plen,PSTR("<font color=\"red\"> OFF</font>"));
}
plen=fill_tcp_data_p(buf,plen,PSTR(" <small><a href=\".\">[refresh_status]</a></small></p>\n<p><a href=\"."));
if (on_off){
plen=fill_tcp_data_p(buf,plen,PSTR("/0\">Switch off</a><p>"));
}else{
plen=fill_tcp_data_p(buf,plen,PSTR("/1\">Switch on</a><p>"));
}
return(plen);
}
//////////////////////////////////koniec kodu strony internetowej/////////////////////////////////////
int main(void){
uint16_t plen;
uint16_t dat_p;
uint8_t i=0;
int8_t cmd;
_delay_loop_1(50); // 12ms
DDRD&= ~(1<<DDD2);
enc28j60Init(mymac);
_delay_loop_1(50); // 12ms
DDRB|= (1<<DDB1);
PORTB|= (1<<PORTB1);
DDRD|= (1<<DDD7);
PORTD &= ~(1<<PORTD7);// transistor off
enc28j60PhyWrite(PHLCON,0x476);
_delay_loop_1(50); // 12ms
PORTB &= ~(1<<PORTB1);
i=1;
init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);
while(1){
plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
if(plen==0){
continue;}
if(eth_type_is_arp_and_my_ip(buf,plen)){
make_arp_answer_from_request(buf);
continue;}
// check if ip packets are for us:
if(eth_type_is_ip_and_my_ip(buf,plen)==0){
continue;}
if (i){
PORTB|= (1<<PORTB1); /* set output to Vcc, LED off */
i=0;
}else{
PORTB &= ~(1<<PORTB1); /* set output to GND, LED on */
i=1;
}
if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
// a ping packet, let's send pong
make_echo_reply_from_request(buf,plen);
continue;
}
// tcp port www start, compare only the lower byte
if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT){
if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){
make_tcp_synack_from_syn(buf);
// make_tcp_synack_from_syn does already send the syn,ack
continue;
}
if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
init_len_info(buf); // init some data structures
// we can possibly have no data, just ack:
dat_p=get_tcp_data_pointer();
if (dat_p==0){
if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){
// finack, answer with ack
make_tcp_ack_from_any(buf);
}
// just an ack with no data, wait for next packet
continue;
}
if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
// head, post and other methods:
//
// for possible status codes see:
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
goto SENDTCP;
}
if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
plen=fill_tcp_data_p(buf,plen,PSTR("<p>Usage: http://host_or_ip/password</p>\n"));
goto SENDTCP;
}
cmd=analyse_get_url((char *)&(buf[dat_p+5]));
// for possible status codes see:
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
if (cmd==-1){
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
goto SENDTCP;
}
if (cmd==1){
PORTD|= (1<<PORTD7);// transistor on
}
if (cmd==0){
PORTD &= ~(1<<PORTD7);// transistor off
}
if (cmd==-3){
// redirect to add a trailing slash
plen=moved_perm(buf);
goto SENDTCP;
}
// if (cmd==-2) or any other value
// just display the status:
plen=print_webpage(buf,(PORTD & (1<<PORTD7)));
//
SENDTCP:
make_tcp_ack_from_any(buf); // send ack for http get
make_tcp_ack_with_data(buf,plen); // send data
continue;
}
}
}
return (0);
}
