金艳霞 通信2班 [1**********]0
实验五 Linux 交叉编译平台
一、 实验目的
1. 掌握一些基本的linux 读写操作
2. 利用vcc 编译c 程序
3. 通过nfs 挂载到实验箱中,利用交叉编译执行文件
二.实验设备
1. Arm9试验箱
2. Pc 机
3. Linux 系统服务器
三.实验过程及实验结果
1. 连接电脑箱
2. 设置交叉编译环境
启动putty.exe
登陆192.168.1.116
3. 添加软件包至实验目录:
① [shiyan@localhost ~]$ cd /home/shiyan
② [shiyan@localhost ~]$ tar –zxvf arm-linux-gcc-3.4.4-glib-2.3.5-static.tar.gz tar -zxvf arm-linux-gcc-3.4.4-glib-2.3.5-static.tar.gz
③ [shiyan@localhost[1**********]0]
$export
PATH=$PATH:/home/shiyan/[1**********]0/opt/crosstool/arm-linux/gcc-3.4.4-glib-2.
3.5/arm-linux/bin
④ [shiyan@localhost [1**********]0]$ set
OSTYPE=linux-gnu
PATH=/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/shiyan/bin:/home/shiyan/opt/crosstool/arm-linux/gcc-3.4.4-glibc-2.3.5/arm-linux/bin:/home/shiyan/opt/crosstool/arm-linux/gcc-3.4.4-glibc-2.3.5/arm-linux/bin:/home/shiyan/opt/crosstool/arm-linux/gcc-3.4.4-glibc-2.3.5/arm-linux/bin
可以看出路径已添加
⑤ [shiyan@localhost [1**********]0]$ arm-linux-g再按tab
arm-linux-g++ arm-linux-gcc arm-linux-gcc-3.4.4 arm-linux-gccbug arm-linux-gcov
⑥ [shiyan@localhost [1**********]0]$ arm-linux-gcc
arm-linux-gcc: no input files
此时出错,无此文件
3. 测试程序
① 创建hello.c
[shiyan@localhost ~]$ vi hello.c
#include
int main()
{
printf("jin123");
return 0;
}
:wq
② 查看是否生成文件
[shiyan@matrix [1**********]0]$ ls
arm-linux-gcc-3.4.4-glib-2.3.5-static.tar.gz hello.c
已经生成
③ 打开hello.c
[shiyan@localhost ~]$ ./hello.c
-bash:/hello cannot execute binary file
表示无法在服务器上执行
④ 交叉编译hello.c
[shiyan@localhost ~]$ arm-linux-gcc -o hello hello.c
⑤ 将文件拷贝到nfs 下
[shiyan@localhost ~]$ cp hello /home/shiyan/nfs
⑥ 挂载服务器到板子上
/ $ mount –tnfs -o nolock 192.168.1.116:/home/shiyan/nfs/mnt/nfs
/ $cdmnt/nfs
⑦ 打开hello 文件
/ $./hello
结果输出:
Jin 123
四.实验总结
上述实验可以得出,交叉编译的二进制可以在板子上运行,却不能在服务器上运行,很好的认清了交叉编译的意义和功能。
实验六Armboot 下载运行及tcp 实验
一.实验目的
1. 掌握armboot 的编译
2. 掌握tftp 工具的使用
3. 掌握armboot 下载运行
4. 掌握windows 的 tcp 客户端的建立及通信过程
5. 掌握tcp 的基本原理
二.实验设备
1. Arm9试验箱
2. Pc 机
3. Linux 系统服务器
三.实验过程及实验结果
1) Armboot
① 编译armboot-1.1.0
cd /home/shiyan/arm-linux-2.6/armboot-1.1.0
[shiyan@matrix armboot-1.1.0]$ make
② 产生的armboot.bin 拷贝到tftp 的目录服务下
[shiyan@matrixarmboot-1.1.0]$
cparmboot.bin /home/shiyan/arm-linux-2.6/armboot-1.1.0/tftpboot/armboot
③ 打开arm9开发板,在五秒内按ESC ,检查网络环境
CPE>printenv
bootdelay=3
baudrate=38400
ethaddr=00:40:25:00:00:01
netmask=255.255.255.0
sererip=192.168.1.65
ipaddr=192.168.1.111
serverip=192.168.1.30
Environment size: 139/131068 bytes
④ 将armboot 的网络环境改为tftp 服务的网络地址
setenv serverip 192.168.1.220
CPE>saveenv
Un-Protected 1 sectors
Erasing sector 6 ... ok.
0x800e0000 o Flash...
done.
Protected 1 sectors
⑤ 将armboot.bin 文件通过tftp 传输到内存0x2000000H 中
CPE>tftp 0x2000000 armboot.bin
ARP broadcast 1
ARP broadcast 2
⑥ 运行
go 0x2000000
⑦ 检查网络环境
CPE> printenv
bootdelay=3
baudrate=38400
ethaddr=00:40:25:00:00:01
netmask=255.255.255.0
sererip=192.168.1.65
ipaddr=192.168.1.111
serverip=192.168.1.220
通过serverip 的改变可看出armboot 下载的正确性。
实验七 Mount 挂载实验
一.实验目的
1. 掌握一些基本的linux 读写操作(touch 指令)
2. 掌握Usb 挂载方法
3. 掌握配置nfs 的方法
二.实验设备
1.
2.
3.
4. Arm9试验箱 Pc 机 Linux 系统服务器 U 盘
三.实验过程及实验结果
A. 文件夹挂载
1. 服务器
[shiyan@matrix ~]$/etc/rc.d/init.d/nfs start
2. 板子挂载
/ $ ifconfig eth0 192.168.1.98
/ $ mount -t nfs -o nolock 192.168.1.220:/home/shiyan/nfs/mnt/nfs
/$ df
Filesystem 1k-bl ocks Used Availabl e Use% Mounted on
/dev/mtdblock1 1024 544 480 53% /mnt/mtd
192.168.1.220:/home/shiyan/nfs 515455456 59590720 429681056 12% /mnt/nfs
B. Usb 挂载
① 将u 盘插入arm9开发板,并启动
② 查看盘符信息
/ $ fdisk -l
③ 创建一个/mnt/usb文件夹
/ $ mkdir /mnt/usb
④ 把sda1盘符mount 到/mnt/usb文件上
/ $ mount /dev/sda1 /mnt/usb/
/ $ cd /mnt/usb
/mnt/usb $ ls
⑤ 创建文件,并输入字符串
/mnt/usb $ vi jin.txt
hello!
⑥ 解挂载
/mnt/usb $ unmount /mnt/usb/
/bin/sh: unmount: not found
⑦ 将u 盘拔出,插入电脑,观察该文件
结果正确
实验八RTC 时钟驱动实验
一.实验目的
1. 了解RTC 工作原理
2. 掌握RTC 时钟驱动编程
二.实验内容
1. 编写RTC 驱动程序
2. 通过insmod 加载驱动程序
3. 编写代码修改RTC 内部时间
三.实验设备
1. PC 机
2. Arm9实验箱客户端
3. Linux 操作系统服务端
四.实验过程及结果
1. 实验代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DRIVER_VERSION "0.01"
/* Register map */
/* rtc section */
// control and status registers
#define REG_CS1 0x00
#define TEST1 (1
#define STOP (1
#define TESTC (1
#define REG_CS2 0x01
#define TI_TP (1
#define AF (1
#define TF (1
#define AIE (1
#define TIE (1
// Time and date registers
#define REG_SC 0x02 // vl_seconds (0-59)
#define REG_MN 0x03 // minutes (0-59)
#define REG_HR 0x04 // hours (0-23)
#define REG_DT 0x05 // days (1-31)
#define REG_DW 0x06 // weekdays (0-6)
#define REG_MO 0x07 // century_months (1-12)
#define REG_YR 0x08 // years (0-99)
// Alarm registers
#define REG_MA 0x09 // minute_alarm
#define AE_M (1
#define REG_HA 0x0a // hour_alarm
#define AE_H (1
#define REG_DA 0x0b // day_alarm
#define AE_D (1
#define REG_WA 0x0c // weekday_alarm
#define AE_W (1
// CLKOUT control register
#define REG_CC 0x0d
#define FE (1
// Timer registers
#define REG_TC 0x0e // timer_control
#define TE (1
#define REG_TMR 0x0f // timer
#define RTC_SECTION_LEN 7
/* i2c configuration */
#define I2C_ADDR 0xa2
/////////////////////////////////////////////////////////////
#define DEFAULT_I2C_CLOCKDIV 180//for APB 108MHz
staticunsignedlong rtc_status;
staticvolatileunsignedlong rtc_irq_data;
staticunsignedlong rtc_freq = 1; /*FTRTC010 supports only 1Hz clock*/
staticstruct fasync_struct *rtc_async_queue;
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
extern spinlock_t rtc_lock;
MODULE_AUTHOR("GM Corp.");
MODULE_LICENSE("GM License");
externint GM_i2c_xfer(struct i2c_msg *msgs, int num, int clockdiv);
/* block read */
staticint i2c_read_regs(u8 reg, u8 buf[], unsigned len)
{
struct i2c_msg msgs[1];
//////////////
buf[0] = reg;
msgs[0].addr = I2C_ADDR>>1;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = buf;
if (GM_i2c_xfer(msgs, 1, DEFAULT_I2C_CLOCKDIV) != 1)
return -1;
//////////////
msgs[0].addr = I2C_ADDR>>1;
msgs[0].flags = 1;
msgs[0].len = len+1;
msgs[0].buf = buf;
if (GM_i2c_xfer(msgs, 1, DEFAULT_I2C_CLOCKDIV) != 1)
return -1;
return 0;
}
/* block write */
staticint i2c_set_regs(u8 reg, u8 const buf[], unsigned len)
{
u8 i2c_buf[10];
struct i2c_msg msgs[1];
i2c_buf[0] = reg;
memcpy(&i2c_buf[1], &buf[0], len);
msgs[0].addr = I2C_ADDR>>1;
msgs[0].flags = 0;
msgs[0].len = len+1;
msgs[0].buf = i2c_buf;
if (GM_i2c_xfer(msgs, 1, DEFAULT_I2C_CLOCKDIV) != 1)
return -1;
return 0;
}
staticint set_time(struct rtc_time const *tm)
{
int sr;
u8 regs[RTC_SECTION_LEN] = { 0, };
printk("stop RTC\n");
regs[0] = STOP;
regs[1] = 0x00; // disable interrupt and clear all flags
sr = i2c_set_regs(REG_CS1, regs, 2);
if (sr
printk("%s: stop RTC failed\n", __func__);
return sr;
}
printk("set_time Date(y/m/d):%d/%d/%d
Time(h/m/s):%d/%d/%d\n",tm->tm_year,tm->tm_mon,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
regs[REG_SC-REG_SC] = BIN2BCD(tm->tm_sec);
regs[REG_MN-REG_SC] = BIN2BCD(tm->tm_min);
regs[REG_HR-REG_SC] = BIN2BCD(tm->tm_hour);
regs[REG_DT-REG_SC] = BIN2BCD(tm->tm_mday);
regs[REG_MO-REG_SC] = BIN2BCD(tm->tm_mon);
regs[REG_YR-REG_SC] = BIN2BCD(tm->tm_year-100);
regs[REG_DW-REG_SC] = BIN2BCD(tm->tm_wday & 7);
/* write RTC registers */
sr = i2c_set_regs(REG_SC, regs, RTC_SECTION_LEN);
if (sr
printk("%s: writing RTC section failed\n", __func__);
return sr;
}
printk("start RTC\n");
regs[0] = 0x00;
sr = i2c_set_regs(REG_CS1, regs, 1);
if (sr
printk("%s: start RTC failed\n", __func__);
return sr;
}
return 0;
}
staticvoid read_time (struct rtc_time *tm)
{
int sr;
u8 regs[RTC_SECTION_LEN] = { 0, };
sr = i2c_read_regs(REG_SC, regs, RTC_SECTION_LEN);
if (sr
printk("%s: reading RTC section failed\n", __func__);
return;
}
tm->tm_sec = BCD2BIN(regs[REG_SC-REG_SC]&0x7f);
tm->tm_min = BCD2BIN(regs[REG_MN-REG_SC]&0x7f);
tm->tm_hour = BCD2BIN(regs[REG_HR-REG_SC]&0x3f);
tm->tm_mday = BCD2BIN(regs[REG_DT-REG_SC]&0x3f);
tm->tm_wday = BCD2BIN(regs[REG_DW-REG_SC]&0x07);
tm->tm_mon = BCD2BIN(regs[REG_MO-REG_SC]&0x1f); /* rtc starts at 1 */
tm->tm_year = BCD2BIN(regs[REG_YR-REG_SC])+100;
printk("read_time Date(YY/MM/DD):%d/%d/%d
Time(hh/mm/ss):%d/%d/%d\n",tm->tm_year,tm->tm_mon,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
}
staticunsigned AIE_stat=0;
/*ijsung: arch-indep function*/
staticint rtc_open(struct inode *inode, struct file *file) {
if (test_and_set_bit (1, &rtc_status)) return -EBUSY; rtc_irq_data = 0; return 0; }
staticint rtc_release(struct inode *inode, struct file *file) {
unsignedchar buf[7]; rtc_status = 0; return 0; }
staticint rtc_fasync (int fd, struct file *filp, int on) {
return fasync_helper (fd, filp, on, &rtc_async_queue); }
staticunsignedint rtc_poll(struct file *file, poll_table *wait) {
poll_wait (file, &rtc_wait, wait);
return (rtc_irq_data) ? 0 : POLLIN | POLLRDNORM; }
static loff_t rtc_llseek(struct file *file, loff_t offset, int origin) {
return -ESPIPE; }
ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) {
DECLARE_WAITQUEUE(wait, current); unsignedlong data; ssize_t retval;
if (count
add_wait_queue(&rtc_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE); for (;;) {
spin_lock_irq (&rtc_lock); data = rtc_irq_data; if (data != 0) {
rtc_irq_data = 0; break; }
spin_unlock_irq (&rtc_lock);
if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto out; }
if (signal_pending(current)) { retval = -ERESTARTSYS; goto out; }
schedule(); }
spin_unlock_irq (&rtc_lock);
data -= 0x100; /* the first IRQ wasn't actually missed */ retval = put_user(data, (unsignedlong *)buf); if (!retval)
retval = sizeof(unsignedlong); out:
set_current_state(TASK_RUNNING); remove_wait_queue(&rtc_wait, &wait); return retval; }
staticint rtc_ioctl(struct inode *inode, struct file *file, unsignedint cmd, unsignedlong arg) {
struct rtc_time tm, tm2; unsignedchar buf[7]; switch (cmd) {
case RTC_AIE_OFF:
printk("Not Support\n"); return 0;
case RTC_AIE_ON:
printk("Not Support\n"); return 0;
case RTC_ALM_READ:
printk("Not Support\n"); return 0;
case RTC_ALM_SET:
printk("Not Support\n"); return 0;
case RTC_RD_TIME: read_time(&tm); break;
case RTC_SET_TIME: {
unsigned usertime;
unsignedchar buf[7];
if (!capable(CAP_SYS_TIME)) return -EACCES;
if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm))) return -EFAULT; set_time(&tm); } return 0;
case RTC_IRQP_READ:
return put_user(rtc_freq, (unsignedlong *)arg); case RTC_IRQP_SET:
if (arg != 1) return -EINVAL; return 0;
case RTC_EPOCH_READ:
return put_user (1970, (unsignedlong *)arg); default:
return -EINVAL; }
return copy_to_user ((void *)arg, &tm, sizeof (tm)) ? -EFAULT : 0; }
staticstruct file_operations rtc_fops = { owner: THIS_MODULE, llseek: rtc_llseek, read: rtc_read, poll: rtc_poll, ioctl: rtc_ioctl, open: rtc_open, release: rtc_release, fasync: rtc_fasync, };
staticstruct miscdevice ftrtc010rtc_miscdev = { RTC_MINOR, "rtc", &rtc_fops };
staticint rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) {
// unsigned alarm_time; unsignedchar buf[7]; char *p = page; int len;
struct rtc_time tm; read_time(&tm);
//printk("RTC ... %d\n",xtime.tv_sec);
p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n" "rtc_date\t: %04d-%02d-%02d\n" "rtc_epoch\t: %04d\n",
tm.tm_hour + 1, tm.tm_min, tm.tm_sec,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 2000); // read_alarm(&tm);
// p += sprintf(p, "alrm_time\t: %2dth day of week day\n" // "alrm_date\t: N/A for Platform\n", // tm.tm_wday);
p += sprintf(p, "alrm_time\t: Not Support\n" "alrm_date\t: Not Support\n");
p += sprintf(p, "alarm_IRQ\t: %s\n", AIE_stat ? "yes" : "no" ); len = (p - page) - off; if (len
*eof = (len
staticint __init rtc_init(void) {
misc_register (&ftrtc010rtc_miscdev);
create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL); printk("PCF8563 Real Time Clock driver\n"); return 0; }
staticvoid __exit rtc_exit(void) {
remove_proc_entry ("driver/rtc", NULL); misc_deregister (&ftrtc010rtc_miscdev); }
module_init(rtc_init); module_exit(rtc_exit);
2. 挂载usb
/ $ ifconfig eth0 192.168.1.99
/ $ mount -t nfs -o nolock 192.168.1.220:/home/shiyan/nfs /mnt/nfs / $ fdisk –l
/ $ mkdir /mnt/usb
/ $ mount /dev/sda1 /mnt/usb/ / $ cd /mnt/usb
3. 找到u 盘中的pcf8563.ko
/mnt/usb $ ls
4. 加载pcf8563.ko
/mnt/usb $ insmod pcf8563.ko
5. 更改日期并写入
6. 重启检验日期
与当前时间相符
实验九视频采集RTP 发送及远程视频监控实验
一.实验目的
1. 理解视频传输原理
2. 掌握在IP 网络中实现视频传输的方法 3. 理解远程控制原理
4. 掌握在windows 下TCP 客户端建立及通信过程
二.实验内容
1. 搭建点对点视频传输模式 2. 开启视频采集
3. 开启Windows 下tcp 客户端,完成控制命令
三.实验设备
1. 硬件:基于双核处理器架构的网络音视频传输教学实验系统;
对接线; 串口连接线; 网线;
集线器(HUB ),PC 机;
2. 软件:H.264流媒体软件
设备端视频采集程序 设备端视频传输程序 串口操作软件
四.实验步骤及结果 A. 视频采集
1. 连接好实验箱,打开串口通信端,远程mount 到home/nfs文件夹 / $ mount -t nfs -o nolock 192.168.1.116:/home/shiyan/nfs /mnt/nfs
2. 挂载服务器下nfs 与板子的/mnt/nfs,进入/mnt/nfs文件夹 / $ cd /mnt/nfs
3. 输入ls 命令,目录下文件 /mnt/nfs $ ls
123321 clientxxww readme tcpserver StartLog0 ffgpio.ko server tcpserver19
a gpio_test serverfxf tcpserver_arm_11 bo hello serverxw tcpserver_hdt client nfs1 tcpclient tcpserver_zn client_arm ok tcpclient19 tcpsever
client_arm_17 program_20_1.c tcpclient_29 tw2835_menu client_arm_st20 program_20_2.c tcpclient_arm_11 xianshi client_dalan programyk tcpclient_hdt yk clientxw programyq tcpclient_zn yq 4. 运行tw2835_menu进行视频采集 /mnt/nfs $ ./tw2835_menu&
5. 进入挂载目录并查看文件 /mnt/nfs $ cd nfs1 /mnt/nfs/nfs1 $ ls
dev_app.app hello vedio.confTCPS1 dev_app3 ffgpio.ko tw2835_menu dev_app gpio_test tw2835_pic 6. 运行dev_app到板子IP192.168.1.9 /mnt/nfs/nfs1 $ ./dev_app 192.168.1.9 7. 开启H.264流媒体播放器进行视频接受 a) 用解码器解码,并允许注册
.bat
b) 打开H.264流媒体播放器,点击开启视频接收
B. 远程视频监控
1. 重复以上实验1~4步
2. 进入已挂载目录/mnt/nfs/nfs1,看到多个程序 /mnt/nfs $ cd nfs1 /mnt/nfs/nfs1 $ ls
StartLog0 dev_app.app hello vedio.conf TCPS1 dev_app3 image.info www boot.sh ffgpio.ko tw2835_menu 3. 运行TCPS1
/mnt/nfs/nfs1 $ ./ TCPS1
4. 程序进入等待状态,等待TCP 连接到来
5. 开启H.264流媒体播放器,点击“开始视频接收”,屏幕变黑
6. 点击“控制功能”,输入设备端ip 地址192.168.1.68,点击连接
7. 设备端出现下列字样,表示连接成功
Servergetconnectionfrom192.168.1.68 8. 点击“开启视频监控”,获得视频数据
实验十一Tcp 网络编程
一、实验目的
1. 了解网络编程原理 2. 了解套接字的使用 二、实验原理
嵌入式Linux 的网络通信程序是基于套接字模式的。Socket 实际是网络传输层供给应用层的接口。常见的Socket 有三种类型。 1.流式Sockct 流式套接字提供可靠的,面向连接的通信流,它使用TCP 协议,从而保证了数据传输的正确性和顺序性。Socket 编程采用客户/服务器模式。因此编程分为服务器端和客户端。服务器端:首先建立Socket ,返回该Socket 的描述符;配置Socket 的端口和IP 地址;建立监听函数,检测是否有客户端向服务器端发送请求,若有则接收该请求,将其放到接收队列中;从接收队列中接收一个请求;并向客户端发送确认连接信息。客户端:建立一个Socket ,返回该Socket 的描述符,配置Socket 端口和IP 地址;向服务器发送连接请求,并接收服务器发回的确认连接信息。双方通信结束后,关闭其Socket 。2. 数据报Socket ,数据通过相互独立的报文进行传输,数据报套接字定义了一种无连接的服务,是无序的,并且不保证是可靠的,无差错的。它使用数据报协议UDP 。 3.原始Socket 使用Socket 编程时可以开发客户机和服务器端应用程序,它们可以在本地网络上进行通信,也可以通过Internet 在全球范围内进行通信。编写并运行Socket 的客户端和服务器端程序,双方通过套接字建立了服务连接请求,并且通过一些方法提高Socket 的性能。
三、实验步骤
编写服务器端源程序和客户端源程序
1. 代码:
program_20_1.c
#include #include #include #include #include #include #include #include #include #include #include #include
int main(int argc, char *argv[]) {
int sockfd,new_fd;
struct sockaddr_in server_addr; struct sockaddr_in client_addr; int portnumber;
const char hello[]="Hello and Bye\n";
// for setsockopt() SO_REUSEADDR, below int yes = 1; int addrlen;
if(argc!=2) {
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); }
if((portnumber=atoi(argv[1]))
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); }
/* 服务器端开始建立socket 描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); exit(1); }
printf("Server-socket() is OK...\n");
// "address already in use" error message
if( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int))== -1 )
{
perror("Server-setsockopt() error lol!");
exit(1);
}
printf("Server-setsockopt() is OK...\n");
/* 服务器端填充 sockaddr 结构 */
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
memset(&(server_addr.sin_zero), '\0', 8);
/* 捆绑sockfd 描述符 */
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}
printf("Server-bind() is OK...\n");
/* 监听sockfd 描述符 */
if(listen(sockfd,5)==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
printf("Server-listen() is OK...\n");
while(1)
{
/* 服务器阻塞, 直到客户程序建立连接 */
addrlen = sizeof(client_addr);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&addrlen))==-1)
{
printf("Accept error:%s\n\a",strerror(errno));
exit(1);
}else{
printf("Server-accept() is OK...\n");
}
printf("New connection from %s on socket %d\n", inet_ntoa(client_addr.sin_addr), new_fd); if(write(new_fd,hello,strlen(hello))==-1)
{
printf("Write Error:%s\n",strerror(errno));
exit(1);
}else{
printf("Write something to the client, then close it.\n"); }
close(new_fd);
}
close(sockfd);
exit(0);
}
program_20_2.c /TCPClient示例/
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr;
struct hostent *host;
int portnumber,nbytes;
if(argc!=3)
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{
herror ("Get host name error\n");
exit(1);
}
if((portnumber=atoi(argv[2]))
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1);
}
/* 客户程序开始建立 sockfd 描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); exit(1);
}
/* 客户程序填充服务端的资料 */
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*((struct in_addr *)host->h_addr); /* 客户程序发起连接请求 */
if(connect(sockfd,(struct sockaddr *)(&server_addr),\
sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Connect Error:%s\a\n",strerror(errno)); exit(1);
}
/* 连接成功了 */
if((nbytes=read(sockfd,buffer,1024))==-1)
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
buffer[nbytes]='\0';
printf("I have received:%s\n",buffer);
/* 结束通讯 */
close(sockfd);
exit(0);
}
2. 步骤
① 交叉编译服务端程序
[shiyan@matrix ~]$ cd /home/shiyan
[shiyan@localhost ~]$ gcc -o clientjin program_20_1.c
[shiyan@localhost ~]$ arm-linux-gcc -o serverjin program_20_2.c
[shiyan@localhost ~]$ cp /home/shiyan/serverjin /home/shiyan/nfs
② 执行
[shiyan@localhost ~]$
./clientjin 3456
③ 打开实验箱,并挂载
/ $ ifconfig eth0 192.168.1.55 up
/ $ ping 192.168.1.116
/ $ mount -t nfs -o nolock 192.168.1.116:/home/shiyan/nfs /mnt/nfs / $ cd mnt/nfs
/mnt/nfs $ ls
④ 执行客户端程序
/mnt/nfs $ ./serverjin 192.168.1.116 3456
接受到数据,实验成功
实验十二 WEB 服务器程序
一. 实验目的
1. 掌握httpd 工具制作web 服务器的基本流程
2. 掌握实验设备的连接和调试
二. 实验内容
1. 运行实验箱
2. 通过路由器将实验箱和pc 机连接
3. 在pc 机上运行浏览器,看是否运行网页服务器
三.实验设备
1. Pc 机
2. 嵌入式实验箱
3. Pc 机操作系统
四.实验步骤
1. 连接好实验箱,挂载nfs 文件
/ $ ifconfig eth0 192.168.1.55
/ $ ping 192.168.1.116
/ $ mount -t nfs -o nolock 192.168.1.116:/home/shiyan/nfs /mnt/nfs
3. 进入nfs1/www文件夹查看可执行文件thttpd
/ $ cd mnt/nfs/nfs1
/mnt/nfs /nfs1 $ ls
/mnt/nfs /nfs1/www $ ls
4. 运行web 服务器
/mnt/nfs /nfs1/www $ ./thttpd –c ./thttpd.conf /mnt/nfs /nfs1/www $ cd thttpd/
/mnt/nfs /nfs1
/www/thttpd $ ls
5. 查看网络文件
/mnt/nfs /nfs1/www/thttpd $ cd html /mnt/nfs /nfs1/www/thttpd/html $ ls
/mnt/nfs /nfs1
/www/thttpd/html $ cat index.html
6. 打开浏览器输入192.168.1.55 ,进入web 页面
金艳霞 通信2班 [1**********]0
实验五 Linux 交叉编译平台
一、 实验目的
1. 掌握一些基本的linux 读写操作
2. 利用vcc 编译c 程序
3. 通过nfs 挂载到实验箱中,利用交叉编译执行文件
二.实验设备
1. Arm9试验箱
2. Pc 机
3. Linux 系统服务器
三.实验过程及实验结果
1. 连接电脑箱
2. 设置交叉编译环境
启动putty.exe
登陆192.168.1.116
3. 添加软件包至实验目录:
① [shiyan@localhost ~]$ cd /home/shiyan
② [shiyan@localhost ~]$ tar –zxvf arm-linux-gcc-3.4.4-glib-2.3.5-static.tar.gz tar -zxvf arm-linux-gcc-3.4.4-glib-2.3.5-static.tar.gz
③ [shiyan@localhost[1**********]0]
$export
PATH=$PATH:/home/shiyan/[1**********]0/opt/crosstool/arm-linux/gcc-3.4.4-glib-2.
3.5/arm-linux/bin
④ [shiyan@localhost [1**********]0]$ set
OSTYPE=linux-gnu
PATH=/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/shiyan/bin:/home/shiyan/opt/crosstool/arm-linux/gcc-3.4.4-glibc-2.3.5/arm-linux/bin:/home/shiyan/opt/crosstool/arm-linux/gcc-3.4.4-glibc-2.3.5/arm-linux/bin:/home/shiyan/opt/crosstool/arm-linux/gcc-3.4.4-glibc-2.3.5/arm-linux/bin
可以看出路径已添加
⑤ [shiyan@localhost [1**********]0]$ arm-linux-g再按tab
arm-linux-g++ arm-linux-gcc arm-linux-gcc-3.4.4 arm-linux-gccbug arm-linux-gcov
⑥ [shiyan@localhost [1**********]0]$ arm-linux-gcc
arm-linux-gcc: no input files
此时出错,无此文件
3. 测试程序
① 创建hello.c
[shiyan@localhost ~]$ vi hello.c
#include
int main()
{
printf("jin123");
return 0;
}
:wq
② 查看是否生成文件
[shiyan@matrix [1**********]0]$ ls
arm-linux-gcc-3.4.4-glib-2.3.5-static.tar.gz hello.c
已经生成
③ 打开hello.c
[shiyan@localhost ~]$ ./hello.c
-bash:/hello cannot execute binary file
表示无法在服务器上执行
④ 交叉编译hello.c
[shiyan@localhost ~]$ arm-linux-gcc -o hello hello.c
⑤ 将文件拷贝到nfs 下
[shiyan@localhost ~]$ cp hello /home/shiyan/nfs
⑥ 挂载服务器到板子上
/ $ mount –tnfs -o nolock 192.168.1.116:/home/shiyan/nfs/mnt/nfs
/ $cdmnt/nfs
⑦ 打开hello 文件
/ $./hello
结果输出:
Jin 123
四.实验总结
上述实验可以得出,交叉编译的二进制可以在板子上运行,却不能在服务器上运行,很好的认清了交叉编译的意义和功能。
实验六Armboot 下载运行及tcp 实验
一.实验目的
1. 掌握armboot 的编译
2. 掌握tftp 工具的使用
3. 掌握armboot 下载运行
4. 掌握windows 的 tcp 客户端的建立及通信过程
5. 掌握tcp 的基本原理
二.实验设备
1. Arm9试验箱
2. Pc 机
3. Linux 系统服务器
三.实验过程及实验结果
1) Armboot
① 编译armboot-1.1.0
cd /home/shiyan/arm-linux-2.6/armboot-1.1.0
[shiyan@matrix armboot-1.1.0]$ make
② 产生的armboot.bin 拷贝到tftp 的目录服务下
[shiyan@matrixarmboot-1.1.0]$
cparmboot.bin /home/shiyan/arm-linux-2.6/armboot-1.1.0/tftpboot/armboot
③ 打开arm9开发板,在五秒内按ESC ,检查网络环境
CPE>printenv
bootdelay=3
baudrate=38400
ethaddr=00:40:25:00:00:01
netmask=255.255.255.0
sererip=192.168.1.65
ipaddr=192.168.1.111
serverip=192.168.1.30
Environment size: 139/131068 bytes
④ 将armboot 的网络环境改为tftp 服务的网络地址
setenv serverip 192.168.1.220
CPE>saveenv
Un-Protected 1 sectors
Erasing sector 6 ... ok.
0x800e0000 o Flash...
done.
Protected 1 sectors
⑤ 将armboot.bin 文件通过tftp 传输到内存0x2000000H 中
CPE>tftp 0x2000000 armboot.bin
ARP broadcast 1
ARP broadcast 2
⑥ 运行
go 0x2000000
⑦ 检查网络环境
CPE> printenv
bootdelay=3
baudrate=38400
ethaddr=00:40:25:00:00:01
netmask=255.255.255.0
sererip=192.168.1.65
ipaddr=192.168.1.111
serverip=192.168.1.220
通过serverip 的改变可看出armboot 下载的正确性。
实验七 Mount 挂载实验
一.实验目的
1. 掌握一些基本的linux 读写操作(touch 指令)
2. 掌握Usb 挂载方法
3. 掌握配置nfs 的方法
二.实验设备
1.
2.
3.
4. Arm9试验箱 Pc 机 Linux 系统服务器 U 盘
三.实验过程及实验结果
A. 文件夹挂载
1. 服务器
[shiyan@matrix ~]$/etc/rc.d/init.d/nfs start
2. 板子挂载
/ $ ifconfig eth0 192.168.1.98
/ $ mount -t nfs -o nolock 192.168.1.220:/home/shiyan/nfs/mnt/nfs
/$ df
Filesystem 1k-bl ocks Used Availabl e Use% Mounted on
/dev/mtdblock1 1024 544 480 53% /mnt/mtd
192.168.1.220:/home/shiyan/nfs 515455456 59590720 429681056 12% /mnt/nfs
B. Usb 挂载
① 将u 盘插入arm9开发板,并启动
② 查看盘符信息
/ $ fdisk -l
③ 创建一个/mnt/usb文件夹
/ $ mkdir /mnt/usb
④ 把sda1盘符mount 到/mnt/usb文件上
/ $ mount /dev/sda1 /mnt/usb/
/ $ cd /mnt/usb
/mnt/usb $ ls
⑤ 创建文件,并输入字符串
/mnt/usb $ vi jin.txt
hello!
⑥ 解挂载
/mnt/usb $ unmount /mnt/usb/
/bin/sh: unmount: not found
⑦ 将u 盘拔出,插入电脑,观察该文件
结果正确
实验八RTC 时钟驱动实验
一.实验目的
1. 了解RTC 工作原理
2. 掌握RTC 时钟驱动编程
二.实验内容
1. 编写RTC 驱动程序
2. 通过insmod 加载驱动程序
3. 编写代码修改RTC 内部时间
三.实验设备
1. PC 机
2. Arm9实验箱客户端
3. Linux 操作系统服务端
四.实验过程及结果
1. 实验代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DRIVER_VERSION "0.01"
/* Register map */
/* rtc section */
// control and status registers
#define REG_CS1 0x00
#define TEST1 (1
#define STOP (1
#define TESTC (1
#define REG_CS2 0x01
#define TI_TP (1
#define AF (1
#define TF (1
#define AIE (1
#define TIE (1
// Time and date registers
#define REG_SC 0x02 // vl_seconds (0-59)
#define REG_MN 0x03 // minutes (0-59)
#define REG_HR 0x04 // hours (0-23)
#define REG_DT 0x05 // days (1-31)
#define REG_DW 0x06 // weekdays (0-6)
#define REG_MO 0x07 // century_months (1-12)
#define REG_YR 0x08 // years (0-99)
// Alarm registers
#define REG_MA 0x09 // minute_alarm
#define AE_M (1
#define REG_HA 0x0a // hour_alarm
#define AE_H (1
#define REG_DA 0x0b // day_alarm
#define AE_D (1
#define REG_WA 0x0c // weekday_alarm
#define AE_W (1
// CLKOUT control register
#define REG_CC 0x0d
#define FE (1
// Timer registers
#define REG_TC 0x0e // timer_control
#define TE (1
#define REG_TMR 0x0f // timer
#define RTC_SECTION_LEN 7
/* i2c configuration */
#define I2C_ADDR 0xa2
/////////////////////////////////////////////////////////////
#define DEFAULT_I2C_CLOCKDIV 180//for APB 108MHz
staticunsignedlong rtc_status;
staticvolatileunsignedlong rtc_irq_data;
staticunsignedlong rtc_freq = 1; /*FTRTC010 supports only 1Hz clock*/
staticstruct fasync_struct *rtc_async_queue;
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
extern spinlock_t rtc_lock;
MODULE_AUTHOR("GM Corp.");
MODULE_LICENSE("GM License");
externint GM_i2c_xfer(struct i2c_msg *msgs, int num, int clockdiv);
/* block read */
staticint i2c_read_regs(u8 reg, u8 buf[], unsigned len)
{
struct i2c_msg msgs[1];
//////////////
buf[0] = reg;
msgs[0].addr = I2C_ADDR>>1;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = buf;
if (GM_i2c_xfer(msgs, 1, DEFAULT_I2C_CLOCKDIV) != 1)
return -1;
//////////////
msgs[0].addr = I2C_ADDR>>1;
msgs[0].flags = 1;
msgs[0].len = len+1;
msgs[0].buf = buf;
if (GM_i2c_xfer(msgs, 1, DEFAULT_I2C_CLOCKDIV) != 1)
return -1;
return 0;
}
/* block write */
staticint i2c_set_regs(u8 reg, u8 const buf[], unsigned len)
{
u8 i2c_buf[10];
struct i2c_msg msgs[1];
i2c_buf[0] = reg;
memcpy(&i2c_buf[1], &buf[0], len);
msgs[0].addr = I2C_ADDR>>1;
msgs[0].flags = 0;
msgs[0].len = len+1;
msgs[0].buf = i2c_buf;
if (GM_i2c_xfer(msgs, 1, DEFAULT_I2C_CLOCKDIV) != 1)
return -1;
return 0;
}
staticint set_time(struct rtc_time const *tm)
{
int sr;
u8 regs[RTC_SECTION_LEN] = { 0, };
printk("stop RTC\n");
regs[0] = STOP;
regs[1] = 0x00; // disable interrupt and clear all flags
sr = i2c_set_regs(REG_CS1, regs, 2);
if (sr
printk("%s: stop RTC failed\n", __func__);
return sr;
}
printk("set_time Date(y/m/d):%d/%d/%d
Time(h/m/s):%d/%d/%d\n",tm->tm_year,tm->tm_mon,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
regs[REG_SC-REG_SC] = BIN2BCD(tm->tm_sec);
regs[REG_MN-REG_SC] = BIN2BCD(tm->tm_min);
regs[REG_HR-REG_SC] = BIN2BCD(tm->tm_hour);
regs[REG_DT-REG_SC] = BIN2BCD(tm->tm_mday);
regs[REG_MO-REG_SC] = BIN2BCD(tm->tm_mon);
regs[REG_YR-REG_SC] = BIN2BCD(tm->tm_year-100);
regs[REG_DW-REG_SC] = BIN2BCD(tm->tm_wday & 7);
/* write RTC registers */
sr = i2c_set_regs(REG_SC, regs, RTC_SECTION_LEN);
if (sr
printk("%s: writing RTC section failed\n", __func__);
return sr;
}
printk("start RTC\n");
regs[0] = 0x00;
sr = i2c_set_regs(REG_CS1, regs, 1);
if (sr
printk("%s: start RTC failed\n", __func__);
return sr;
}
return 0;
}
staticvoid read_time (struct rtc_time *tm)
{
int sr;
u8 regs[RTC_SECTION_LEN] = { 0, };
sr = i2c_read_regs(REG_SC, regs, RTC_SECTION_LEN);
if (sr
printk("%s: reading RTC section failed\n", __func__);
return;
}
tm->tm_sec = BCD2BIN(regs[REG_SC-REG_SC]&0x7f);
tm->tm_min = BCD2BIN(regs[REG_MN-REG_SC]&0x7f);
tm->tm_hour = BCD2BIN(regs[REG_HR-REG_SC]&0x3f);
tm->tm_mday = BCD2BIN(regs[REG_DT-REG_SC]&0x3f);
tm->tm_wday = BCD2BIN(regs[REG_DW-REG_SC]&0x07);
tm->tm_mon = BCD2BIN(regs[REG_MO-REG_SC]&0x1f); /* rtc starts at 1 */
tm->tm_year = BCD2BIN(regs[REG_YR-REG_SC])+100;
printk("read_time Date(YY/MM/DD):%d/%d/%d
Time(hh/mm/ss):%d/%d/%d\n",tm->tm_year,tm->tm_mon,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
}
staticunsigned AIE_stat=0;
/*ijsung: arch-indep function*/
staticint rtc_open(struct inode *inode, struct file *file) {
if (test_and_set_bit (1, &rtc_status)) return -EBUSY; rtc_irq_data = 0; return 0; }
staticint rtc_release(struct inode *inode, struct file *file) {
unsignedchar buf[7]; rtc_status = 0; return 0; }
staticint rtc_fasync (int fd, struct file *filp, int on) {
return fasync_helper (fd, filp, on, &rtc_async_queue); }
staticunsignedint rtc_poll(struct file *file, poll_table *wait) {
poll_wait (file, &rtc_wait, wait);
return (rtc_irq_data) ? 0 : POLLIN | POLLRDNORM; }
static loff_t rtc_llseek(struct file *file, loff_t offset, int origin) {
return -ESPIPE; }
ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) {
DECLARE_WAITQUEUE(wait, current); unsignedlong data; ssize_t retval;
if (count
add_wait_queue(&rtc_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE); for (;;) {
spin_lock_irq (&rtc_lock); data = rtc_irq_data; if (data != 0) {
rtc_irq_data = 0; break; }
spin_unlock_irq (&rtc_lock);
if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto out; }
if (signal_pending(current)) { retval = -ERESTARTSYS; goto out; }
schedule(); }
spin_unlock_irq (&rtc_lock);
data -= 0x100; /* the first IRQ wasn't actually missed */ retval = put_user(data, (unsignedlong *)buf); if (!retval)
retval = sizeof(unsignedlong); out:
set_current_state(TASK_RUNNING); remove_wait_queue(&rtc_wait, &wait); return retval; }
staticint rtc_ioctl(struct inode *inode, struct file *file, unsignedint cmd, unsignedlong arg) {
struct rtc_time tm, tm2; unsignedchar buf[7]; switch (cmd) {
case RTC_AIE_OFF:
printk("Not Support\n"); return 0;
case RTC_AIE_ON:
printk("Not Support\n"); return 0;
case RTC_ALM_READ:
printk("Not Support\n"); return 0;
case RTC_ALM_SET:
printk("Not Support\n"); return 0;
case RTC_RD_TIME: read_time(&tm); break;
case RTC_SET_TIME: {
unsigned usertime;
unsignedchar buf[7];
if (!capable(CAP_SYS_TIME)) return -EACCES;
if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm))) return -EFAULT; set_time(&tm); } return 0;
case RTC_IRQP_READ:
return put_user(rtc_freq, (unsignedlong *)arg); case RTC_IRQP_SET:
if (arg != 1) return -EINVAL; return 0;
case RTC_EPOCH_READ:
return put_user (1970, (unsignedlong *)arg); default:
return -EINVAL; }
return copy_to_user ((void *)arg, &tm, sizeof (tm)) ? -EFAULT : 0; }
staticstruct file_operations rtc_fops = { owner: THIS_MODULE, llseek: rtc_llseek, read: rtc_read, poll: rtc_poll, ioctl: rtc_ioctl, open: rtc_open, release: rtc_release, fasync: rtc_fasync, };
staticstruct miscdevice ftrtc010rtc_miscdev = { RTC_MINOR, "rtc", &rtc_fops };
staticint rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) {
// unsigned alarm_time; unsignedchar buf[7]; char *p = page; int len;
struct rtc_time tm; read_time(&tm);
//printk("RTC ... %d\n",xtime.tv_sec);
p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n" "rtc_date\t: %04d-%02d-%02d\n" "rtc_epoch\t: %04d\n",
tm.tm_hour + 1, tm.tm_min, tm.tm_sec,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 2000); // read_alarm(&tm);
// p += sprintf(p, "alrm_time\t: %2dth day of week day\n" // "alrm_date\t: N/A for Platform\n", // tm.tm_wday);
p += sprintf(p, "alrm_time\t: Not Support\n" "alrm_date\t: Not Support\n");
p += sprintf(p, "alarm_IRQ\t: %s\n", AIE_stat ? "yes" : "no" ); len = (p - page) - off; if (len
*eof = (len
staticint __init rtc_init(void) {
misc_register (&ftrtc010rtc_miscdev);
create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL); printk("PCF8563 Real Time Clock driver\n"); return 0; }
staticvoid __exit rtc_exit(void) {
remove_proc_entry ("driver/rtc", NULL); misc_deregister (&ftrtc010rtc_miscdev); }
module_init(rtc_init); module_exit(rtc_exit);
2. 挂载usb
/ $ ifconfig eth0 192.168.1.99
/ $ mount -t nfs -o nolock 192.168.1.220:/home/shiyan/nfs /mnt/nfs / $ fdisk –l
/ $ mkdir /mnt/usb
/ $ mount /dev/sda1 /mnt/usb/ / $ cd /mnt/usb
3. 找到u 盘中的pcf8563.ko
/mnt/usb $ ls
4. 加载pcf8563.ko
/mnt/usb $ insmod pcf8563.ko
5. 更改日期并写入
6. 重启检验日期
与当前时间相符
实验九视频采集RTP 发送及远程视频监控实验
一.实验目的
1. 理解视频传输原理
2. 掌握在IP 网络中实现视频传输的方法 3. 理解远程控制原理
4. 掌握在windows 下TCP 客户端建立及通信过程
二.实验内容
1. 搭建点对点视频传输模式 2. 开启视频采集
3. 开启Windows 下tcp 客户端,完成控制命令
三.实验设备
1. 硬件:基于双核处理器架构的网络音视频传输教学实验系统;
对接线; 串口连接线; 网线;
集线器(HUB ),PC 机;
2. 软件:H.264流媒体软件
设备端视频采集程序 设备端视频传输程序 串口操作软件
四.实验步骤及结果 A. 视频采集
1. 连接好实验箱,打开串口通信端,远程mount 到home/nfs文件夹 / $ mount -t nfs -o nolock 192.168.1.116:/home/shiyan/nfs /mnt/nfs
2. 挂载服务器下nfs 与板子的/mnt/nfs,进入/mnt/nfs文件夹 / $ cd /mnt/nfs
3. 输入ls 命令,目录下文件 /mnt/nfs $ ls
123321 clientxxww readme tcpserver StartLog0 ffgpio.ko server tcpserver19
a gpio_test serverfxf tcpserver_arm_11 bo hello serverxw tcpserver_hdt client nfs1 tcpclient tcpserver_zn client_arm ok tcpclient19 tcpsever
client_arm_17 program_20_1.c tcpclient_29 tw2835_menu client_arm_st20 program_20_2.c tcpclient_arm_11 xianshi client_dalan programyk tcpclient_hdt yk clientxw programyq tcpclient_zn yq 4. 运行tw2835_menu进行视频采集 /mnt/nfs $ ./tw2835_menu&
5. 进入挂载目录并查看文件 /mnt/nfs $ cd nfs1 /mnt/nfs/nfs1 $ ls
dev_app.app hello vedio.confTCPS1 dev_app3 ffgpio.ko tw2835_menu dev_app gpio_test tw2835_pic 6. 运行dev_app到板子IP192.168.1.9 /mnt/nfs/nfs1 $ ./dev_app 192.168.1.9 7. 开启H.264流媒体播放器进行视频接受 a) 用解码器解码,并允许注册
.bat
b) 打开H.264流媒体播放器,点击开启视频接收
B. 远程视频监控
1. 重复以上实验1~4步
2. 进入已挂载目录/mnt/nfs/nfs1,看到多个程序 /mnt/nfs $ cd nfs1 /mnt/nfs/nfs1 $ ls
StartLog0 dev_app.app hello vedio.conf TCPS1 dev_app3 image.info www boot.sh ffgpio.ko tw2835_menu 3. 运行TCPS1
/mnt/nfs/nfs1 $ ./ TCPS1
4. 程序进入等待状态,等待TCP 连接到来
5. 开启H.264流媒体播放器,点击“开始视频接收”,屏幕变黑
6. 点击“控制功能”,输入设备端ip 地址192.168.1.68,点击连接
7. 设备端出现下列字样,表示连接成功
Servergetconnectionfrom192.168.1.68 8. 点击“开启视频监控”,获得视频数据
实验十一Tcp 网络编程
一、实验目的
1. 了解网络编程原理 2. 了解套接字的使用 二、实验原理
嵌入式Linux 的网络通信程序是基于套接字模式的。Socket 实际是网络传输层供给应用层的接口。常见的Socket 有三种类型。 1.流式Sockct 流式套接字提供可靠的,面向连接的通信流,它使用TCP 协议,从而保证了数据传输的正确性和顺序性。Socket 编程采用客户/服务器模式。因此编程分为服务器端和客户端。服务器端:首先建立Socket ,返回该Socket 的描述符;配置Socket 的端口和IP 地址;建立监听函数,检测是否有客户端向服务器端发送请求,若有则接收该请求,将其放到接收队列中;从接收队列中接收一个请求;并向客户端发送确认连接信息。客户端:建立一个Socket ,返回该Socket 的描述符,配置Socket 端口和IP 地址;向服务器发送连接请求,并接收服务器发回的确认连接信息。双方通信结束后,关闭其Socket 。2. 数据报Socket ,数据通过相互独立的报文进行传输,数据报套接字定义了一种无连接的服务,是无序的,并且不保证是可靠的,无差错的。它使用数据报协议UDP 。 3.原始Socket 使用Socket 编程时可以开发客户机和服务器端应用程序,它们可以在本地网络上进行通信,也可以通过Internet 在全球范围内进行通信。编写并运行Socket 的客户端和服务器端程序,双方通过套接字建立了服务连接请求,并且通过一些方法提高Socket 的性能。
三、实验步骤
编写服务器端源程序和客户端源程序
1. 代码:
program_20_1.c
#include #include #include #include #include #include #include #include #include #include #include #include
int main(int argc, char *argv[]) {
int sockfd,new_fd;
struct sockaddr_in server_addr; struct sockaddr_in client_addr; int portnumber;
const char hello[]="Hello and Bye\n";
// for setsockopt() SO_REUSEADDR, below int yes = 1; int addrlen;
if(argc!=2) {
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); }
if((portnumber=atoi(argv[1]))
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); }
/* 服务器端开始建立socket 描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); exit(1); }
printf("Server-socket() is OK...\n");
// "address already in use" error message
if( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int))== -1 )
{
perror("Server-setsockopt() error lol!");
exit(1);
}
printf("Server-setsockopt() is OK...\n");
/* 服务器端填充 sockaddr 结构 */
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
memset(&(server_addr.sin_zero), '\0', 8);
/* 捆绑sockfd 描述符 */
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}
printf("Server-bind() is OK...\n");
/* 监听sockfd 描述符 */
if(listen(sockfd,5)==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
printf("Server-listen() is OK...\n");
while(1)
{
/* 服务器阻塞, 直到客户程序建立连接 */
addrlen = sizeof(client_addr);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&addrlen))==-1)
{
printf("Accept error:%s\n\a",strerror(errno));
exit(1);
}else{
printf("Server-accept() is OK...\n");
}
printf("New connection from %s on socket %d\n", inet_ntoa(client_addr.sin_addr), new_fd); if(write(new_fd,hello,strlen(hello))==-1)
{
printf("Write Error:%s\n",strerror(errno));
exit(1);
}else{
printf("Write something to the client, then close it.\n"); }
close(new_fd);
}
close(sockfd);
exit(0);
}
program_20_2.c /TCPClient示例/
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr;
struct hostent *host;
int portnumber,nbytes;
if(argc!=3)
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{
herror ("Get host name error\n");
exit(1);
}
if((portnumber=atoi(argv[2]))
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1);
}
/* 客户程序开始建立 sockfd 描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); exit(1);
}
/* 客户程序填充服务端的资料 */
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*((struct in_addr *)host->h_addr); /* 客户程序发起连接请求 */
if(connect(sockfd,(struct sockaddr *)(&server_addr),\
sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Connect Error:%s\a\n",strerror(errno)); exit(1);
}
/* 连接成功了 */
if((nbytes=read(sockfd,buffer,1024))==-1)
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
buffer[nbytes]='\0';
printf("I have received:%s\n",buffer);
/* 结束通讯 */
close(sockfd);
exit(0);
}
2. 步骤
① 交叉编译服务端程序
[shiyan@matrix ~]$ cd /home/shiyan
[shiyan@localhost ~]$ gcc -o clientjin program_20_1.c
[shiyan@localhost ~]$ arm-linux-gcc -o serverjin program_20_2.c
[shiyan@localhost ~]$ cp /home/shiyan/serverjin /home/shiyan/nfs
② 执行
[shiyan@localhost ~]$
./clientjin 3456
③ 打开实验箱,并挂载
/ $ ifconfig eth0 192.168.1.55 up
/ $ ping 192.168.1.116
/ $ mount -t nfs -o nolock 192.168.1.116:/home/shiyan/nfs /mnt/nfs / $ cd mnt/nfs
/mnt/nfs $ ls
④ 执行客户端程序
/mnt/nfs $ ./serverjin 192.168.1.116 3456
接受到数据,实验成功
实验十二 WEB 服务器程序
一. 实验目的
1. 掌握httpd 工具制作web 服务器的基本流程
2. 掌握实验设备的连接和调试
二. 实验内容
1. 运行实验箱
2. 通过路由器将实验箱和pc 机连接
3. 在pc 机上运行浏览器,看是否运行网页服务器
三.实验设备
1. Pc 机
2. 嵌入式实验箱
3. Pc 机操作系统
四.实验步骤
1. 连接好实验箱,挂载nfs 文件
/ $ ifconfig eth0 192.168.1.55
/ $ ping 192.168.1.116
/ $ mount -t nfs -o nolock 192.168.1.116:/home/shiyan/nfs /mnt/nfs
3. 进入nfs1/www文件夹查看可执行文件thttpd
/ $ cd mnt/nfs/nfs1
/mnt/nfs /nfs1 $ ls
/mnt/nfs /nfs1/www $ ls
4. 运行web 服务器
/mnt/nfs /nfs1/www $ ./thttpd –c ./thttpd.conf /mnt/nfs /nfs1/www $ cd thttpd/
/mnt/nfs /nfs1
/www/thttpd $ ls
5. 查看网络文件
/mnt/nfs /nfs1/www/thttpd $ cd html /mnt/nfs /nfs1/www/thttpd/html $ ls
/mnt/nfs /nfs1
/www/thttpd/html $ cat index.html
6. 打开浏览器输入192.168.1.55 ,进入web 页面