打印
[STM32F1]

STM32F103+DM9051_UIP_SPI to 以太网 【调试记录】

[复制链接]
楼主: qq280572
手机看帖
扫描二维码
随时随地手机跟帖
21
qq280572|  楼主 | 2015-10-20 17:29 | 只看该作者 回帖奖励 |倒序浏览
5-2 uIP基本结构

    uIP的代码编写需要遵守一定的结构,而且这种结构最好保持稳定(保持不变)。这个结构主要做以下几个部分任务。

1. 初始化系統、驱动、uIP protocol
2. 取的DHCP IP,或固定IP
3. 获得以太网数据报
4. 处理ARP报文
5. 处理IP报文
6. 定期处理TCPUDP连接
7. 定期更新ARP缓冲区
相关代码參考如下:

int main(void)
{
#ifndef __DHCPC_H__
        uip_ipaddr_t ipaddr;
#endif //__DHCPC_H__
  int i;
  struct timer periodic_timer, arp_timer;
  USART_Configuration();
  
  /* Setting polling and arp timer */
  timer_set(&periodic_timer, CLOCK_SECOND / 2);        //500ms
  timer_set(&arp_timer, CLOCK_SECOND * 10);        // 10sec
  
  /* Init ethernet driver */
  tapdev_init();
  /* Init uIP portocol */
  uip_init();
  uip_arp_init();        // Clear arp table.
#ifdef __DHCPC_H__
        /* setup the dhcp renew timer the make the first request */
        timer_set(&dhcp_timer, CLOCK_SECOND * 600);
        /* Init Dhcpc */
        dhcpc_init(&uip_ethaddr, 6);
        //dhcpc_request();
#else
  uip_ipaddr(ipaddr, 192,168,7,51);                //Setting Host IP address
  uip_sethostaddr(ipaddr);
  uip_ipaddr(ipaddr, 192,168,7,1);                //Setting Default Gateway
  uip_setdraddr(ipaddr);
  uip_ipaddr(ipaddr, 255,255,255,0);        //Setting Network Mask
  uip_setnetmask(ipaddr);
  
  /* Display system information */
  printf("\r\n---------------------------------------------\r\n");
  printf("Network chip: DAVICOM DM9051 \r\n");
  printf("MAC Address: %02X:%02X:%02X:%02X:%02X:%02X \r\n", uip_ethaddr.addr[0], uip_ethaddr.addr[1],
                                                uip_ethaddr.addr[2], uip_ethaddr.addr[3], uip_ethaddr.addr[4], uip_ethaddr.addr[5]);
  uip_gethostaddr(ipaddr); //get host IP
  printf("Host IP Address: %d.%d.%d.%d \r\n", uip_ipaddr1(ipaddr), uip_ipaddr2(ipaddr), uip_ipaddr3(ipaddr), uip_ipaddr4(ipaddr));
  uip_getnetmask(ipaddr); //get Get netmask
  printf("Network Mask: %d.%d.%d.%d \r\n", uip_ipaddr1(ipaddr), uip_ipaddr2(ipaddr), uip_ipaddr3(ipaddr), uip_ipaddr4(ipaddr));
  uip_getdraddr(ipaddr); // get getway
  printf("Gateway IP Address: %d.%d.%d.%d \r\n", uip_ipaddr1(ipaddr), uip_ipaddr2(ipaddr), uip_ipaddr3(ipaddr), uip_ipaddr4(ipaddr));
  printf("---------------------------------------------\r\n");
#endif //__DHCPC_H__
  
  httpd_init(); //Init TCP task
  /*Initial and start system tick time = 1ms */
  SysTick_Config(SystemCoreClock / 1000);  
  
  while(1) {
    uip_len = tapdev_read(); //reveive packet, and return uip_len
       
    if(uip_len > 0) {
      if(BUF->type == htons(UIP_ETHTYPE_IP)) {
                                //uip_arp_ipin();   //Removed by Spenser
                                uip_input();                // uip_process(UIP_DATA)
                               
                                /* If the above function invocation resulted in data that
                                   should be sent out on the network, the global variable
                                   uip_len is set to a value > 0. */
                                if(uip_len > 0) {
                                  uip_arp_out();
                                  tapdev_send();
                                }
      } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
                                uip_arp_arpin();
                                /* If the above function invocation resulted in data that
                                   should be sent out on the network, the global variable
                                   uip_len is set to a value > 0. */
                                if(uip_len > 0) {
                                  tapdev_send();
                                }
      }
    } else if(timer_expired(&periodic_timer)) {
                timer_reset(&periodic_timer);
               
                for(i = 0; i < UIP_CONNS; i++) {
                                uip_periodic(i);
                                /* If the above function invocation resulted in data that
                                   should be sent out on the network, the global variable
                                   uip_len is set to a value > 0. */
                                if(uip_len > 0) {
                                  uip_arp_out();
                                  tapdev_send();
                                }
      }
#if UIP_UDP
      for(i = 0; i < UIP_UDP_CONNS; i++) {
                                uip_udp_periodic(i);
                                /* If the above function invocation resulted in data that
                                   should be sent out on the network, the global variable
                                   uip_len is set to a value > 0. */
                                if(uip_len > 0) {
                                  uip_arp_out();
                                  tapdev_send();
                                }
      }
#endif /* UIP_UDP */
      
      /* Call the ARP timer function every 10 seconds. */
      if(timer_expired(&arp_timer)) {
                                timer_reset(&arp_timer);
                                uip_arp_timer();
      }
    }
#ifdef __DHCPC_H__
                else if (timer_expired(&dhcp_timer)) {
            // for now turn off the led when we start the dhcp process
            dhcpc_renew();
            timer_reset(&dhcp_timer);
    }
#endif //__DHCPC_H__
  }
}

简单說明一下uip buffer调试驱动 :
    1.#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
    指向uIP缓冲区,强制类型转化为uip_eth_hdr结构体,uip_eth_hdr即为以太网首部结构,6字节目标MAC地址 6字节源MAC地址 2字节类型。

    2. tapdev_init();tapdev_read();tapdev_send();
    三个函数为以太网操作函数,只有tapdev_read有返回值,其他函数即无输入参数也无返回参数。这三个函数便是DM9051操作的三个封装,DM9051发送或接收直接操作uIP的两个全局变量uip_bufuip_lentapdev.c具体代码如下:

/* Init DM9051 */
void tapdev_init(void)
{
  DM9051_init();
}
/* received data return uip_len */
unsigned int tapdev_read(void)
{
  return DM9051_rx();
}
/* send data */
void tapdev_send(void)
{
  DM9051_tx();       
}

5-3 uIP配置部分

5-3-1. IP地址配置
IP地址设置包括,本地IP地址,网关地址和子网掩码。可参考6-2

5-3-1. MAC地址配置

MAC的地址较为特殊,由于DM9051本身没有唯一的EUI-48(俗称MAC地址)地址,所以EUI-48地址需要手动配置。该地址不但应用于DM9051也应用于uIP。相关设定MAC Address代码如下介绍:

首先在uip-conf.h,定义emacETHADDR 设定MAC address:

#define emacETHADDR0   0x00
#define emacETHADDR1   0x60
#define emacETHADDR2   0x6e
#define emacETHADDR3   0x90
#define emacETHADDR4   0x51
#define emacETHADDR5   0x02
#if UIP_FIXEDETHADDR // if open UIP_FIXEDETHADDR
const struct uip_eth_addr uip_ethaddr = {{emacETHADDR0,
                                          emacETHADDR1,
                                          emacETHADDR2,
                                          emacETHADDR3,
                                          emacETHADDR4,
                                          emacETHADDR5}};
#else
struct uip_eth_addr uip_ethaddr = {{0,0x6A,0x60,0x90,0x51,0}};
#endif
另外补充:DM9051 默认先从EEPROM读取MAC地址,如无挂载EEPROM,则通过软件设定。IP地址也是先透过DHCP获取,如获取不到则采取代码设定固定值。
5-4 uip-conf.h部分

uip-conf部分说明三点

1. 如果不熟悉请保留默认参数,例如UIP_CONF_MAX_CONNECTIONS
2. 如果设置UIP_CONF_LOGGING1,请添加void uip_log(char *m){}
3. 必须包含用户任务头文件,且放在该头文件的最后。例如添加#include "example1.h"。这样做的主要目的是定义uip_tcp_appstate_tUIP_APPCALL两个关键参数。具体代码如下:
#ifndef __UIP_CONF_H  
#define __UIP_CONF_H  
#include <inttypes.h>  
typedef uint8_t u8_t;  
typedef uint16_t u16_t;  
typedef unsigned short uip_stats_t;  
/* 最大TCP连接数 */
#define UIP_CONF_MAX_CONNECTIONS 10  
/* 最大端口监听数 */
#define UIP_CONF_MAX_LISTENPORTS 10  
/* uIP 缓存大小*/
#define UIP_CONF_BUFFER_SIZE 1500  
/* CPU字节顺序 */
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN  
/* 日志开关  */
#define UIP_CONF_LOGGING 1  
/* UDP支援开关*/
#define UIP_CONF_UDP 0  
/* UDP校验和开关 */
#define UIP_CONF_UDP_CHECKSUMS 1  
/* uIP统计开关 */
#define UIP_CONF_STATISTICS 1
// 加入用户任务头文件,请修改
#include "example1.h"
#endif  
5-5一个简单有效的Clock Tick

uIP协议栈处理过程需要一个定时配合,该定时器实际为一个软件定时器,定时器说明uIP处理若干周期性任务,例如处理TCP连接重传,定时更新ARP缓冲表等。
设计定时器的方法很多,在这里推荐uIP原作者的timer模块。timer模块的原理类似于MCU硬件中的比较匹配原理,timer模块中有一个全部变量counter,每次MCU发生某个定时器中断时累加1,如果某个任务需要使用定时器服务,在该任务中声明一个timer(在该任务中为全局变量),并记录此时的counter值。
判断溢出可查询当前的counter和被记录的counter的差值,如果差值超过间隔值那么软件定时器timer溢出(类似于发生比较匹配中断)。
软件定时器的主要作用有两个。第一,更新TCPUDP连接,第二,更新ARP缓冲区(ARP)虽然uIP在功能上比LwIP简单的多,但是LwIP也有类似的部分(或者说完全一样)。详细代码修改clock-arch.c如下:
#include "clock-arch.h"
#include "stm32f10x.h"
extern __IO int32_t g_RunTime;
/*---------------------------------------------------------------------------*/
clock_time_t
clock_time(void)
{
        return g_RunTime;
}
/*---------------------------------------------------------------------------*/
修改clock-arch.h如下

typedef int clock_time_t;
#define CLOCK_CONF_SECOND 100
作用是:clock_time 用于配置系统产生滴答的间隔,我的开发板系统时钟跑的是72MHz,即每隔720,000,000/100产生一次系统滴答,一个系统滴答是10ms, CLOCK_SECOND (这里定义为100) clock tick即为1S

使用stm32 System Tick中断代码,stm32f10x_it.c修改如下:
__IO int32_t g_RunTime = 0;
void SysTick_Handler(void)
{
  static uint8_t s_count = 0;
  if (++s_count >= 10)
   {
      s_count = 0;
      g_RunTime++;    /* every 10ms add 1 */
      if (g_RunTime == 0x80000000)
      {
         g_RunTime = 0;
      }
    }
}

使用特权

评论回复
22
qq280572|  楼主 | 2015-10-20 17:42 | 只看该作者
6.案例——最简单的TCP echo程序

    先来一个最简单的TCP程序。uIP作为serverIP地址为192.168.1.15PC机做clientIP地址为192.168.1.10X
    1】在网络调试助手中,选择以太网通信种类为client(表示PC机为Client)IP地址输入192.168.1.15,端口号输入1234。最后点击连接。
    2】在发送区域输入任意内容,点击发送数据。
    3】观察返回结果,是否和发送数据相同。
    为了实现该功能新建example1.cexample1.两个文件。代码如下:
#include "example1.h"  
#include "uip.h"  
#include <string.h>  
#include <stdio.h>  
#include <stdint.h>  
void example1_init(void)  
{  
    uip_listen(HTONS(1234));  
}  
void example1_appcall(void)  
{  
    if( uip_newdata() )  
    {  
        // 输出远程IP端口号  
        printf("remote ip addr:%d.%d.%d.%d\r\n",  
               (uip_conn->ripaddr[0]) & 0X00ff,  
               (uip_conn->ripaddr[0]) >> 8,  
               (uip_conn->ripaddr[1]) & 0X00ff,  
               (uip_conn->ripaddr[1]) >> 8  
                   );  
        printf("remote ip port:%d\r\n",HTONS(uip_conn->rport));  
        // TCP ECHO  
        uip_send(uip_appdata,uip_len);  
    }  
}   
3 TCP Echo实验结果
代码做如下分析:
1. uip_listen(HTONS(1234));侦听1234端口,
2. uip_newdata()即查询uip_buf中是否有新数据,如果返回1的话,表示接收到新数据。
3. uip_send(uip_appdata,uip_len);uip_send为发送数据报函数
4. uip_appdata指向用户数据,所谓用户数据即TCP负载数据,例如网络调试助手发送XX,那么uip_appdata指向xukai871105.
5. uip_len为用户数据长度,若串口调试助手发送XX,那么uip_len11
7.web页面控制
1. 打开IE浏览器,地址栏输入DM9051IP地址:
回车后打开下面控制页面:
2. 网頁下可以看到MCUIP基本訊息(:MACIP address),最下面有LED Test可通过网页控制STM32板上的LED
LED Test說明,在按下 ON 的時候,GPIOF6 腳位LED 燈會亮,按下OFF後會滅掉,Flash 代表閃爍,會從GPIOF6 ~9 LED順序亮滅,网址列上會顯示LED1LED01代表亮,0但表滅,2代表閃爍。

3. 具体code如下介紹:
(1). 稍微介绍一下web相关,另外标出端口、IPGPIO/LED的修改位置
void main()中,系統初始化完成後加入httpd_init(); 來初始化webserver port,預設web 80 port
(2). 在初始化完成後,在uip-conf.h最下面將#include "webserver.h"的注釋拿掉,這樣UIP_APPCALL 就能對應到 httpd_appcall
(3). 首先我們先在main.c初始 LEDGPIO PIN,代码如下:
void LedInit(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOF, ENABLE);
       
        /*初始化 GPIOFPin_6为推挽输出*/
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOF,&GPIO_InitStructure);
       
        /*初始化 GPIOFPin_7为推挽输出*/
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOF,&GPIO_InitStructure);
       
        /*初始化 GPIOFPin_8为推挽输出*/
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOF,&GPIO_InitStructure);
       
        /*初始化 GPIOFPin_9为推挽输出*/
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOF,&GPIO_InitStructure);
}
初始化完成后,在webserver目录下新增web_led.cweb_led.h档,代码參考如下:
(1). 首先設定LED 亮灭delay 时间:
void Delay(uint32_t times)
{
        while(times--)
        {
                uint32_t i;
                for (i=0; i<0xffff; i++);
        }
}
(2). 接下來設定LED 亮滅順序,我們使用ascii码來判斷亮滅,
void Set_LED_mode(char lkkcode)
{
        //int i;
        /* 0代表LED6, 1代表LED6, 2代表LED6~9依序閃爍 */
        if(lkkcode == ('0'))
        {
                GPIO_ResetBits(GPIOF,GPIO_Pin_6);
        }else if (lkkcode == '1'){
                GPIO_SetBits(GPIOF,GPIO_Pin_6);
        }else if(lkkcode == '2')
        {
                //for(i = 0 ; i< 30 ; ++i)
                {
                        GPIO_SetBits(GPIOF,GPIO_Pin_6);
                        Delay(25);
                        GPIO_ResetBits(GPIOF,GPIO_Pin_6);
                        Delay(25);
                       
                        GPIO_SetBits(GPIOF,GPIO_Pin_7);
                        Delay(25);
                        GPIO_ResetBits(GPIOF,GPIO_Pin_7);
                        Delay(25);
                       
                        GPIO_SetBits(GPIOF,GPIO_Pin_8);
                        Delay(25);
                        GPIO_ResetBits(GPIOF,GPIO_Pin_8);
                        Delay(25);
                       
                        GPIO_SetBits(GPIOF,GPIO_Pin_9);
                        Delay(25);
                        GPIO_ResetBits(GPIOF,GPIO_Pin_9);
                        Delay(25);
                }
        }
}
(3). 设定好初始化LED GPIO后,在网址列输入IP后会显预设的示网页,网页内容为html放在app/webserver/ httpd-fs目录下,主要为index.html,如想要修改显示使用者网页有两种方式:
(4). 修改代码参考如下:
1. 直接修改index.html。
2. 将使用者的html 放入httpd-fs目录下,然后在handle_input修改
3. 判断LED亮灭,s->inputbuf array中填入ascii码或其他使用者想实现的判断,如s->inputbuf[3] = 'L','E','D'。
static PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);
  PSOCK_READTO(&s->sin, ISO_space);
  if(strncmp(s->inputbuf, http_get, 4) != 0) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);
  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  if(s->inputbuf[1] == ISO_space) {               
    //strncpy(s->filename, http_index_html, sizeof(s->filename)); //修改成想要顯示的html檔,如下:
        strncpy(s->filename, http_webMain_html, sizeof(s->filename));
  }
/* Control led , 0 = OFF, 1 = ON, 2 = Flash */
#if 1 //Joseph add
  else if (s->inputbuf[3] == 'L','E','D' && ((s->inputbuf[4] == '0') ||
                                                (s->inputbuf[4] == '1') || (s->inputbuf[4] == '2'))){
         
    Set_LED_mode(s->inputbuf[4]);
    s->inputbuf[4]= 0;
    //strncpy(s->filename, "/home.html", 10);
                strncpy(s->filename, http_webMain_html, sizeof(s->filename));
        }
#endif
        else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
  }
  /*  httpd_log_file(uip_conn->ripaddr, s->filename);*/  
  s->state = STATE_OUTPUT;
  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);
    if(strncmp(s->inputbuf, http_referer, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      /*      httpd_log(&s->inputbuf[9]);*/
    }
  }
  PSOCK_END(&s->sin);
}
(5).上面介绍完网頁和控制LED燈后,接著說明如何在网頁上显示目前的MACIP address等,在httpd-cgi.c档下新增sys_ stats function,代码參考如下:
static unsigned short generate_sys_stats(void *arg)
{
  struct httpd_state *s = (struct httpd_state *)arg;
  return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
                 "<tr> <td >MAC Address :</td> <td style=\"text-align: left\">%02x:%02x:%02x:%02x:%02x:%02x</td> </tr> \
                                <tr> <td >IP Address : </td> <td style=\"text-align: left\"> %d.%d.%d.%d </td> </tr> \
                                        <tr> <td >Network Mask : </td> <td style=\"text-align: left\"> %d.%d.%d.%d </td> </tr> \
                                                <tr><td >Getway : </td> <td style=\"text-align: left\"> %d.%d.%d.%d </td> </tr>\r\n",
                        /* MAC address */
                        (unsigned int)uip_ethaddr.addr[0], (unsigned int)uip_ethaddr.addr[1],
                                (unsigned int)uip_ethaddr.addr[2], (unsigned int)uip_ethaddr.addr[3],
                                        (unsigned int)uip_ethaddr.addr[4], (unsigned int)uip_ethaddr.addr[5],
                        /* IP address */
                        (uip_hostaddr[0]&0xff), ((uip_hostaddr[0] >> 8)&0xff),
                                (uip_hostaddr[1]&0xff), ((uip_hostaddr[1] >> 8)&0xff),
                        /* network mask */
                        (uip_netmask[0]&0xff), ((uip_netmask[0] >> 8)&0xff),
                                (uip_netmask[1]&0xff), ((uip_netmask[1] >> 8)&0xff),
                        /* Getway address */
                        (uip_draddr[0]&0xff), ((uip_draddr[0] >> 8)&0xff),
                                (uip_draddr[1]&0xff), ((uip_draddr[1] >> 8)&0xff)
                                );
}
static PT_THREAD(sys_stats(struct httpd_state *s, char *ptr))
{
  
  PSOCK_BEGIN(&s->sout);
  //for(s->count = 0; s->count < UIP_CONNS; ++s->count) {
    if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
      PSOCK_GENERATOR_SEND(&s->sout, generate_sys_stats, s);
    }
  //}
  PSOCK_END(&s->sout);

使用特权

评论回复
23
qq280572|  楼主 | 2015-10-20 17:48 | 只看该作者
本帖最后由 qq280572 于 2015-10-20 18:02 编辑

8.测试结果
接上网线后:
首先设置PCIPDM9051 在同一段内;

1. 运行-cmd
输入  ping 192.168.x.x                         测试是否能ping通;
输入  ping 192.168.x.x  -n 100     测试连通丢包率;ctrl+c停止;


2. 查看确认物理地址
输入        arp  -a 192.168.x.x                回车;显示物理地址。










3. 速率测试结果:
注:所用工具软件为:网络调试助手+IPOP



A. 利用网络调试助手循环发送文档,让输出达到最大值从而测试DM9051的最大速率;
B. 由结果可以看出速率,而平均235Kb/s的速率算是比较稳定的了。
4. 使用iperf頻寬测试结果大約有8 . 5M多:

9.移植相关

移植第一步:实现在unix/tapdev.c里面的三个函数。首先是tapdev_init函数,该函数用于初始化网卡(也就是我们的DM9051),通过这个函数实现网卡初始化。其次,是tapdev_read函数,该函数用于从网卡读取一包数据,将读到的数据存放在uip_buf里面,数据长度返回给uip_len。最后,是tapdev_send函数,该函数用于向网卡发送一包数据,将全局缓存区uip_buf里面的数据发送出去(长度为uip_len)。其实这三个函数就是实现最底层的网卡操作。


第二步,因为uIP协议栈需要使用时钟,为TCPARP的定时器服务,因此我们需要STM32提供一个定时器做时钟,提供10ms计时(假设clock-arch.h里面的CLOCK_CONF_SECOND100),通过clock-arch.c里面的clock_time函数返回给uIP使用。


第三步,配置uip-conf.h里面的宏定义选项。主要用于设置TCP最大连接数、TCP监听端口数、CPU大小端模式等,这个大家根据自己需要配置即可。
通过以上3步的修改,我们基本上就完成了uIP的移植。


1,写网卡驱动程序,与具体硬件相关。这一步比较费点时间,不过好在大部分网卡芯片的驱动程序都有代码借鉴或移植。驱动需要提供三个函数:

tapdev_init():网卡初始化函数,初始化网卡的工作模式。
tapdev_read(void):读包函数。将网卡收到的数据放入全局缓存区uip_buf 中,返回包的长度,赋给uip_len
void tapdev_send(void):发包函数。将全局缓存区uip_buf 里的数据(长度放在uip_len 中)发送出去。


2.uipopt.h/uip-conf.h 是配置文件,用来设置本地的IP 地址、网关地址、MAC 地址、全局缓冲区的大小、支持的最大连接数、侦听数、ARP 表大小等。可以根据需要配置。




全文完。






使用特权

评论回复
24
gejigeji521| | 2015-10-20 21:45 | 只看该作者
可以试试能否运行个Linux。然后弄个web服务器。

使用特权

评论回复
25
wahahaheihei| | 2015-10-20 22:05 | 只看该作者
这个还是需要网线啊。需要布线的就不能太密集了。

使用特权

评论回复
26
qq280572|  楼主 | 2015-10-21 09:39 | 只看该作者
gejigeji521 发表于 2015-10-20 21:45
可以试试能否运行个Linux。然后弄个web服务器。

Linux上也是有应用实例的 :
         Samsung S5PV210 Linux (ARM Cortex-A8)
         TI  BeagleBone Linux (ARM Cortex-A8)
         MTK 6735 等都有在使用中;
不过Linux上面用SPI接口会比较少一点,一般都用USB转以太网。

使用特权

评论回复
27
qq280572|  楼主 | 2015-10-21 09:42 | 只看该作者
wahahaheihei 发表于 2015-10-20 22:05
这个还是需要网线啊。需要布线的就不能太密集了。

两层板子,主要是芯片与变压器之间注意点就行了。

使用特权

评论回复
28
wahahaheihei| | 2015-10-22 22:16 | 只看该作者
可以运行个小系统,然后玩个网络。

使用特权

评论回复
29
gejigeji521| | 2015-10-22 22:22 | 只看该作者
uip-conf.h里面的宏定义内容,在移植的时候是需要修改的地方了、

使用特权

评论回复
30
冰河w| | 2015-10-25 18:40 | 只看该作者
楼主大神啊,这种模块售价多少

使用特权

评论回复
31
qq280572|  楼主 | 2015-10-26 09:58 | 只看该作者
冰河w 发表于 2015-10-25 18:40
楼主大神啊,这种模块售价多少

模块我们主要提供设计、测试使用;如需要自己做模块,PCB工程文件也可以提供。

使用特权

评论回复
32
qq280572|  楼主 | 2015-10-28 11:49 | 只看该作者
gejigeji521 发表于 2015-10-22 22:22
uip-conf.h里面的宏定义内容,在移植的时候是需要修改的地方了、

没错哦。

使用特权

评论回复
33
qq280572|  楼主 | 2015-11-5 09:58 | 只看该作者
顶!d=====( ̄▽ ̄*)b

使用特权

评论回复
34
qq280572|  楼主 | 2015-12-23 15:20 | 只看该作者

顶!d=====( ̄▽ ̄*)b

使用特权

评论回复
35
qq280572|  楼主 | 2016-1-22 11:12 | 只看该作者
https://bbs.21ic.com/icview-1275542-1-1.html
已有强人把协议栈移植到芯唐M0系列,大家可以参考下。

使用特权

评论回复
36
598330983| | 2016-2-13 11:34 | 只看该作者
网卡介绍的那个帖子失踪了。

使用特权

评论回复
37
qq280572|  楼主 | 2016-2-15 14:48 | 只看该作者
598330983 发表于 2016-2-13 11:34
网卡介绍的那个帖子失踪了。

哪? 芯片介绍的话此帖子内容应该够详细了,如需要资料可以在一楼下载。

使用特权

评论回复
38
rogerliu1104| | 2016-2-19 14:13 | 只看该作者
不错的帖子!

使用特权

评论回复
39
侨峰之我行| | 2016-4-7 15:17 | 只看该作者
收藏下

使用特权

评论回复
40
qq280572|  楼主 | 2016-5-17 16:25 | 只看该作者
增加一份开发指导资料。

DM9051於STM平台开发指导.rar

4.66 MB

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则