WEB failsafe mode implements on WRTNode(MT7620N)

来源:互联网 发布:java 替换大括号 编辑:程序博客网 时间:2024/06/05 06:15

一、发现页面文件大于1446以后,就不能显示完全,几经周折,在uipopt.h中发现了这样几处定义:

/**
 * The TCP maximum segment size.
 *
 * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
 */
#define UIP_TCP_MSS     (UIP_BUFSIZE - UIP_LLH_LEN - 40)
 
/**
 * The size of the uIP packet buffer.
 *
 * The uIP packet buffer should not be smaller than 60 bytes, and does
 * not need to be larger than 1500 bytes. Lower size results in lower
 * TCP throughput, larger size results in higher TCP throughput.
 *
 * \hideinitializer
 */
#define UIP_BUFSIZE     1500
 
/**
 * The link level header length.
 *
 * This is the offset into the uip_buf where the IP header can be
 * found. For Ethernet, this should be set to 14. For SLIP, this
 * should be set to 0.
 *
 * \hideinitializer
 */
#define UIP_LLH_LEN     14

这样算下来,不就正是UIP_TCP_MSS的值么:)也就是ip segment的大小。实践发现,改大UIP_BUFSIZE后,没有效果:(

所以,只好修改html、css、png文件的大小,保证他们都小于1446才行。按理说,大于分片大小之后,应该会出现分片重组,重组的代码似乎还有问题…


终于,在net/uip-0.9/httpd.h中发现了问题所在:

struct httpd_state {
  unsigned char state;
  unsigned short count;
  unsigned char* dataptr;
  unsigned int upload;
  unsigned int upload_total;
};

由于批量替换修改的原因,将dataptr的指针类型修改成了unsigned*型,显然是有问题的,果断改成unsigned char*


二、利用perl脚本生成fsdata:

原始的脚本有些问题,自己进行了一些修改,如下:

#!/usr/bin/perl
 
open(OUTPUT, "> fsdata.c");
 
chdir("html");
open(FILES, "find . -type f |");
 
while($file = <FILES>) {
 
    # Do not include files in CVS directories nor backup files.
    if($file =~ /(CVS|~)/) {
        next;
    }
    
    chop($file);
 
    print "Adding file $file\n";
    
    open(HEADER, "> /tmp/header") || die $!;
    if($file =~ /404.html/) {
      print(HEADER "HTTP/1.0 404 File not found\r\n");
    } else {
      print(HEADER "HTTP/1.0 200 OK\r\n");
    }
    print(HEADER "Server: uIP/0.9\r\n");
    if($file =~ /\.html$/) {
    print(HEADER "Content-type: text/html; charset=UTF-8\r\n");
    } elsif($file =~ /\.css$/) {
    print(HEADER "Content-type: text/css; charset=UTF-8\r\n");
    } elsif($file =~ /\.gif$/) {
    print(HEADER "Content-type: image/gif\r\n");
    } elsif($file =~ /\.png$/) {
    print(HEADER "Content-type: image/png\r\n");
    } elsif($file =~ /\.jpg$/) {
    print(HEADER "Content-type: image/jpeg\r\n");
    } else {
    print(HEADER "Content-type: text/plain; charset=UTF-8\r\n");
    }
    print(HEADER "\r\n");
    close(HEADER);
 
    unless($file =~ /\.plain$/ || $file =~ /cgi/) {
    system("cat /tmp/header $file > /tmp/file");
    } else {
    system("cp $file /tmp/file");
    }
    
    # now the FILE contains header & body data
    open(FILE, "/tmp/file");
    
    #system("cat /tmp/file");
 
    # delete the tmp files    
    unlink("/tmp/file");
    unlink("/tmp/header");
 
    
 
    # manfeel , delete leading dot (eg: ./img/logo.gif) 
    $file =~ s/\.//;
    $fvar = $file;
 
    $fvar =~ s-/-_-g;
    # manfeel
    # print "fvar = $fvar\n";
 
    $fvar =~ s-\.-_-g;
    # print "fvar = $fvar\n";
 
    print(OUTPUT "static const char data".$fvar."[] = {\n");
    print(OUTPUT "\t/* $file */\n");
 
    # manfeel , we don't need the filename in this format
    #for($j = 0; $j < length($file); $j++) {
    #printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
    #}
    #printf(OUTPUT "0,\n");
    
    
    $i = 0;        
    $flen = 0;
    while(read(FILE, $data, 1)) {
        if($i == 0) {
            print(OUTPUT "\t");
        }
        printf(OUTPUT "0x%02X, ", unpack("C", $data));
        $i++;
        $flen++;
        if($i == 128) {
            print(OUTPUT "\n");
            $i = 0;
        }
    }
    print(OUTPUT "0x00 };\n\n");
    close(FILE);
    push(@fvars, $fvar);
    push(@files, $file);
    push(@flens, $flen);
    #printf("file len = $flen\n");
}
 
for($i = 0; $i < @fvars; $i++) {
    $file = $files[$i];
    $fvar = $fvars[$i];
    $flen = $flens[$i];
 
    if($i == 0) {
        $prevfile = "NULL";
    } else {
        $prevfile = "file" . $fvars[$i - 1];
    }
    print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{\n\t$prevfile, \n\t\"$file\", ");
    print(OUTPUT "\n\tdata$fvar , ");
    print(OUTPUT "\n\t(int) sizeof(data$fvar) - 1 /*$flen*/ \n}};\n\n");
    # print(OUTPUT "\n\t$flen \n}};\n\n");
}
 
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define FS_NUMFILES $i");

 

三、修改唯一指示灯,刷入固件时能够闪烁显示其工作状态。

查看WRTNode的电路图,发现唯一的LED连在SPI_HOLD上,对应的是GPIO38

image

LED初始化代码如下:

#define LED_GPIO38 (0x4000)
 
// manfeel , 2014-06-08 for WRTNode
void led_init()
{
    printf("WRTNode LED init.\n");
    // WRTNode has only one LED connected in GPIO38
    ra_or(PRGIO_ADDR+0x4c, LED_GPIO38); // set LED as output
    LEDON();
}
 
void led_control(int led_bit, int state)
{
    
    if(1 == state)    // off
    {
            ra_or(PRGIO_ADDR+0x48, LED_GPIO38);//set 1 
    }
    else    // on
    {
             ra_and(PRGIO_ADDR+0x48, ~(LED_GPIO38));//set 0
    }
}
 
void LEDON(void)
{
    led_control(READY_LED_BIT, 0);
}
 
void LEDOFF(void)
{
    led_control(READY_LED_BIT, 1);    
}

四、加入boot、httpd命令,并优先从USB启动,如果启动USB失败,则再从SPI启动,如果还是失败,则最终进入UBoot刷机模式。

if(BootType == '3') { 
    char *argv[2]; 
    sprintf(addr_str, "0x%X", CFG_KERN_ADDR); 
    argv[1] = &addr_str[0]; 
    printf("   \n3: System Boot system code via Flash.\n"); 
    LEDON(); 
    // manfeel , first we try to boot from USB 
    do_bootd(cmdtp, 0, 1, NULL); 
    // if fail, then boot from spi flash 
    do_bootm(cmdtp, 0, 2, argv); 
    // manfeel , if boot failed,then do_bootm will return here 
    // so we can start web failsafe mode here! 
 
    //eth_initialize(gd->bd); 
    // manfeel , by anyway now, recved flag should be 1 
    set_recv_flag(1); 
    NetLoopHttpd(); 
    return 0;
}
0 0
原创粉丝点击