FPGA / ARM / DSP Wishbone SoC


< WB+LINUX+USB+TCPIP+WEBServer >

 

 

 

 

 

Lab4 : TCP/IP LED/Dip-Switch

 


 

Introduction

 

  

Lab.4本實驗在ARM9 Linux Kernel, 應用ARM週邊模組的Ethernet Controller與Linux核心的 protocal stack, 進行以TCP/IP作遠端控制應用

 

實驗程式以Client/Server的形式, Client端發送命令要求, 設定Server端的Output(在此例以LED顯示), 或讀取Server端Input(在此例為DipSW)的狀態

 

此實驗Server端為ZX Integrator實驗器, Client端為PC,在此例為Ubuntu下是應用程式, 亦可為Windows或Cygwin下的應用程式, 另外也可以將Client端改成是另一個ZX Integrator作為此一Client, 或是對稱的Peer to Peer形式


 

 

Design Codes

 

  simplesvr.c

 

 

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/ioctl.h>

#include <sys/mman.h>

#include <asm/page.h>

#include <netinet/in.h>

 

#include <linux/fb.h>

 

//a framebuffer device structure;

typedef struct fbdev{

int fb;

unsigned long fb_mem_offset;

unsigned long fb_mem;

struct fb_fix_screeninfo fb_fix;

struct fb_var_screeninfo fb_var;

char dev[20];

} FBDEV, *PFBDEV;

 

#define TRUE 1

#define FALSE 0

#define MAX(x,y) ((x)>(y)?(x):(y))

#define MIN(x,y) ((x)<(y)?(x):(y))

 

#define LISTENPORT 7500

 

#define BACKLOG 10

 

#define MSG "Hello, how are you?"

 

 

//open & init a frame buffer

int fb_open(PFBDEV pFbdev)

{

printf("fb_open\n");

pFbdev->fb = open(pFbdev->dev, O_RDWR);

if(pFbdev->fb < 0)

{

printf("Error opening %s: %m. Check kernel config/n", pFbdev->dev);

return FALSE;

}

if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var)))

{

printf("ioctl FBIOGET_VSCREENINFO/n");

return FALSE;

}

if (-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix)))

{

printf("ioctl FBIOGET_FSCREENINFO/n");

return FALSE;

}

 

//map physics address to virtual address

pFbdev->fb_mem_offset = (unsigned long)(pFbdev->fb_fix.smem_start) & (~PAGE_MASK);

pFbdev->fb_mem = (unsigned long int)mmap(

     (void *)pFbdev->fb_fix.smem_start,

     pFbdev->fb_fix.smem_len + pFbdev->fb_mem_offset,

     PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,

     pFbdev->fb,

     0);

if (-1L == (long) pFbdev->fb_mem)

{

printf("mmap error! mem:%d offset:%d/n", pFbdev->fb_mem,

pFbdev->fb_mem_offset);

return FALSE;

}

 

return TRUE;

}

 

//close frame buffer

int fb_close(PFBDEV pFbdev)

{

close(pFbdev->fb);

pFbdev->fb=-1;

}

 

 

 

int main(int argc, char * argv[]) {

  FBDEV fbdev;

  int fid;

  int sock, conn;

  struct sockaddr_in my_addr, client_addr;

  int sockopt_on = 1;

  int sa_in_size = sizeof(struct sockaddr_in);

  char rdata[80],sdata[16];

  unsigned int led,dpsw;

  int i;

 

 

 

memset(&fbdev, 0, sizeof(FBDEV));

strcpy(fbdev.dev, "/dev/fb0");

if(fb_open(&fbdev)==FALSE)

{

printf("open frame buffer error/n");

return;

}

 

printf("id %s\n",fbdev.fb_fix.id);

printf("fb_mem %x\n",fbdev.fb_mem);

printf("fb_mem_offset %x\n",fbdev.fb_mem_offset);

printf("fb_fix.smem_start %x\n",fbdev.fb_fix.smem_start);

printf("fb_fix.smem_len %x\n",fbdev.fb_fix.smem_len);

 

  *(volatile unsigned int *)(fbdev.fb_mem + fbdev.fb_mem_offset +0x01f00004)=0xffffff;

for(i=0;i<24;i++)

{

  *(volatile unsigned int *)(fbdev.fb_mem + fbdev.fb_mem_offset +0x01f00000)=1<<i;

  usleep(100*1000);

}

 

  printf("starting....\n");

 

  //get a socket

  if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {

    perror("socket");

    exit(1);

  }

 

  //make it reusable

  if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&sockopt_on,sizeof(int)) == -1) {

    perror("setsockopt");

    exit(1);

  }

 

  //first zero the struct

  memset((char *) &my_addr, 0, sa_in_size);

 

  //now fill in the fields we need

  my_addr.sin_family = PF_INET;

  my_addr.sin_port = htons(LISTENPORT);

  my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

 

  //bind our socket to the port

  if (bind(sock,(struct sockaddr *)&my_addr, sa_in_size) == -1) {

    perror("bind");

    exit(1);

  }

 

  //start listening for incoming connections

  if (listen(sock,BACKLOG) == -1) {

    perror("listen");

    exit(1);

  }

 

  while(1)

  {

    //grab connections

    conn = accept(sock, (struct sockaddr *)&client_addr, &sa_in_size);

    if (conn == -1) {

      perror("accept");

      exit(1);

    }

 

    //log the connecter

    printf("got connection from %s\n", inet_ntoa(client_addr.sin_addr));

 

    dpsw=0;

    //do

    //{

      // receive cmd

      if (recv(conn, rdata, 80, 0) == -1) { perror("recv"); break; }

      //printf("The client says \"%s\"\n",rdata);

      led=strtoul(rdata,0,0);

      //printf("led:%x\n",led);

      *(volatile unsigned int *)(fbdev.fb_mem + fbdev.fb_mem_offset +0x01f00000)=led;

      usleep(100*1000);

 

      // send status

      dpsw=*(volatile unsigned int *)(fbdev.fb_mem + fbdev.fb_mem_offset +0x01f00008);

      sprintf(sdata,"0x%x",dpsw>>24);

      printf("dpsw:%x %s\n",dpsw,sdata);

      if (send(conn,sdata,strlen(sdata)+1,0) == -1) { perror("send"); break; }

     

    //} while(((dpsw&0xff)==0xff)||(led=0x000000));

    close(conn);

 

    fb_close(&fbdev);

    close(fid);

 

  }

 

  return 0;

}

 

 

 

 

  Makefile

 

 

 

CROSS=/usr/local/arm/3.4.1/bin/arm-linux-

all: simplesvr

simplesvr:

    $(CROSS)gcc -o simplesvr simplesvr.c

clean:

    rm -rf simplesvr simplesvr.o

 

 

 

 

  simplecln.c

 

 

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

 

#define PORT 7500

 

#define BUFLEN 100

 

 

int main(int argc, char * argv[]) {

  int sock;

  char buf[BUFLEN],sstr[BUFLEN];

  struct hostent * he;

  struct sockaddr_in server_addr;

  int bytecount;

 

  if (argc != 3) {

    fprintf(stderr,"usage: %s host led \n", argv[0]);

    exit(1);

  }

 

  //look up the host

  he = gethostbyname(argv[1]);

  if (he == NULL) {

    perror("gethostbyname");

    exit(1);

  }

 

  //get a socket

  if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {

    perror("socket");

    exit(1);

  } 

 

  //set the fields for the server address struct

  memset((char *) &server_addr, 0, sizeof(struct sockaddr_in));

  server_addr.sin_family = PF_INET;

  server_addr.sin_port = htons(PORT);

  server_addr.sin_addr = *((struct in_addr *)he->h_addr);

 

  //connect to the server

  if (connect(sock, (struct sockaddr *) &server_addr,

                     sizeof(struct sockaddr_in)) == -1) {

    perror("connect");

    exit(1);

  }

 

  strncpy(sstr,argv[2],BUFLEN-1);

  sstr[BUFLEN-1]=0;

 

  //send the reply

  if (send(sock,sstr,strlen(sstr)+1,0) == -1) {

    perror("send");

    exit(1);

  }

 

  //receive the greeting

  bytecount = recv(sock,buf,BUFLEN-1, 0);

  if (bytecount == -1) {

    perror("recv");

    exit(1);

  }

 

  buf[bytecount] = '\0';

  printf("DPSW:%s\n",buf);

 

 

  close(sock);

  return 0;

}

 

 

 

  Makefile

 

 

CRCROSS=/usr/local/arm/3.4.1/bin/arm-linux-

all: simplecln

simplesvr:

#    $(CROSS)gcc -o simplesvr simplesvr.c

     gcc -o simplecln simplecln.c

clean:

     rm -rf simplecln simplecln.o

 

 

 

 

 

 

 

文章標籤
全站熱搜
創作者介紹
創作者 zeppe 的頭像
zeppe

ZEPPE

zeppe 發表在 痞客邦 留言(0) 人氣(121)