20145329《信息安全系统设计基础》实验二 固件设计

北京电子科技学院(BESTI)

实 验 报 告

课程:信息安全系统设计基础 班级:1453

姓名:吉东云。马月 学号:20145329、20145337

指导教师:娄嘉鹏老师 实验日期: 2016-11-8 10:10~12:40

必修/选修:必修 实验序号:(二)

实验名称:

实验目的与要求:

  • 学习、读懂 02_pthread 03_tty中的代码。

实验仪器:

  • 名称 型号 数量
  • 计算机 Lenovo 1
  • Linux环境 Redhat 9.0 1
  • 开发板 UP-NETARM2410-CL 1

一. 实验内容

学习、读懂 02_pthread 03_tty中的代码。

二.实验步骤

1.开发环境的配置同实验一

  • (1)设置xp系统、redhat虚拟机、arm机的ip在同一网段。
  • (2)安装arm编译器
  • (3)进入虚拟机,在命令行中输入./install.sh,安装脚本程序将会自动建立目录,配置编译环境。

2.将实验代码拷贝到共享文件夹中bc中

3.在虚拟机中编译代码。

4.下载调试

在超级终端中运行可执行文件pthread

三代码解析

  • 这是一个生产者和消费者的LINUX多线程实现

1. pthread.c代码

	.#include <stdio.h>
	.#include <stdlib.h>
	.#include <time.h>
	.#include "pthread.h"
	.#define BUFFER_SIZE 16
	/* 设置一个整数的圆形缓冲区 */
	struct prodcons {
	int buffer[BUFFER_SIZE]; /* 缓冲区数组 */
	pthread_mutex_t lock; /* 互斥锁 */
	int readpos, writepos; /* 读写的位置*/
	pthread_cond_t notempty; /* 缓冲区非空信号 */
	pthread_cond_t notfull; /*缓冲区非满信号 */
	};
	/*--------------------------------------------------------*/
	/*初始化缓冲区*/
	void init(struct prodcons * b)
	{
	pthread_mutex_init(&b->lock, NULL);
	pthread_cond_init(&b->notempty, NULL);  //条件变量初始化
	pthread_cond_init(&b->notfull, NULL);
	b->readpos = 0;
	b->writepos = 0;
	}
	/*--------------------------------------------------------*/
	/* 生产者写入共享的循环缓冲区函数 PUT,向缓冲区中写入一个整数*/
	void put(struct prodcons * b, int data)
	{
	pthread_mutex_lock(&b->lock);   //获取互斥锁
	/*等待缓冲区非满*/
	while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {
	printf("wait for not full
");
	pthread_cond_wait(&b->notfull, &b->lock); //等待状态变量b->notfull,不满则跳出阻塞
	}
	/*写数据并且指针前移*/
	b->buffer[b->writepos] = data;  //写入数据
	b->writepos++;
	if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
	/*设置缓冲区非空信号*/
	pthread_cond_signal(&b->notempty);  //设置状态变量
	pthread_mutex_unlock(&b->lock);  //释放互斥锁
	}
	/*--------------------------------------------------------*/
	/*消费者读取共享的循环缓冲区函数 GET,从缓冲区中读出一个整数 */
	int get(struct prodcons * b)
	{
	int data;  
	pthread_mutex_lock(&b->lock);  //获取互斥锁
	/* 等待缓冲区非空*/
	while (b->writepos == b->readpos) {   //如果读写位置相同
	printf("wait for not empty
");
	pthread_cond_wait(&b->notempty, &b->lock);  //等待状态变量,不空则跳出阻塞。否则无数据可读。
	}/* 读数据并且指针前移 */
	data = b->buffer[b->readpos];  //读取数据
	b->readpos++;  
	if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
	/* 设置缓冲区非满信号*/
	pthread_cond_signal(&b->notfull);  //设置状态变量
	pthread_mutex_unlock(&b->lock);  //释放互斥锁
	return data;
	}
	/*--------------------------------------------------------*/
	.#define OVER (-1)
	struct prodcons buffer;
	/*--------------------------------------------------------*/
	void * producer(void * data)
	{
	int n;
	for (n = 0; n < 1000; n++) {
	printf(" put-->%d
", n);
	put(&buffer, n);
	}
	put(&buffer, OVER);
	printf("producer stopped!
");
	return NULL;
	}
	/*--------------------------------------------------------*/
	void * consumer(void * data)
	{
	int d;
	while (1) {
	d = get(&buffer);
	if (d == OVER ) break;
	printf(" %d-->get
", d);
	}
	printf("consumer stopped!
");
	return NULL;
	}
	/*--------------------------------------------------------*/
	int main(void)
	pthread_t th_a, th_b;
	void * retval;
	init(&buffer);
	pthread_create(&th_a, NULL, producer, 0);  //线程创建函数
	pthread_create(&th_b, NULL, consumer, 0); 
	/* 等待生产者和消费者结束 */
	pthread_join(th_a, &retval);  //等待指定的线程结束
	pthread_join(th_b, &retval);
	return 0;
	}

2.term.c代码

	.#include <termios.h> /*PPSIX 终端控制定义*/
	.#include <stdio.h> /*标准输入输出定义*/
	.#include <unistd.h> /*linux 标准函数定义*/
	.#include <fcntl.h> /*文件控制定义*/
	.#include <sys/signal.h>
	.#include <pthread.h> /*线程库定义*/
	.#define BAUDRATE B115200
	.#define COM1 "/dev/ttyS0"
	.#define COM2 "/dev/ttyS1"
	.#define ENDMINITERM1 27 /* ESC to quit miniterm */
	.#define ENDMINITERM2 3  /*ctl +c  to quit miniterm */
	.#define FALSE 0
	.#define TRUE 1
	
	volatile int STOP=FALSE;
	volatile int fd;
	
	
	void child_handler(int s)
	{
	  printf("stop!!!
");
	   STOP=TRUE;
	}
	
	/*--------------------------------------------------------*/
	void* keyboard(void * data)
	{
	int c;
	    for (;;){
	        c=getchar();
	//  printf("getchar is :%d",c);
	if( (c== ENDMINITERM1) | (c==ENDMINITERM2)){
	    STOP=TRUE;
	    break ;
	    }
	    }
	return NULL;
	}
	/*--------------------------------------------------------*/
	/* modem input handler */
	void* receive(void * data)
	{
	    int c;
	    printf("read modem
");
	    while (STOP==FALSE) 
	    {
	    read(fd,&c,1); /* com port */
	    write(1,&c,1); /* stdout */
	    }
	    printf("exit from reading modem
");
	    return NULL; 
	}
	/*--------------------------------------------------------*/
	void* send(void * data)
	{
	    int c='0';
	    printf("send data
");
	    while (STOP==FALSE) 
	    {
	    c++;
	    c %= 255;
	    write(fd,&c,1); /* stdout */
	    usleep(100000);
	    }
	    return NULL; /* wait for child to die or it will become a zombie */
	}
	/*--------------------------------------------------------*/
	int main(int argc,char** argv)
	{
	
	    struct termios oldtio,newtio,oldstdtio,newstdtio;
	    struct sigaction sa;
	    int ok;
	    pthread_t th_a, th_b, th_c;
	    void * retval;
	
	    if( argc > 1)
	    fd = open(COM2, O_RDWR );  /*以读写方式打开串口*/
	    else  
	        fd = open(COM1, O_RDWR ); //| O_NOCTTY |O_NONBLOCK);
	    if (fd <0) {  /* 不能打开串口一*/
	    perror(COM1);
	    exit(-1);
	    }
	    tcgetattr(0,&oldstdtio);
	    tcgetattr(fd,&oldtio); /* save current modem settings */
	    tcgetattr(fd,&newstdtio); /* get working stdtio */
	    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* 控制模式标志 */
	    newtio.c_iflag = IGNPAR;  /* 输入模式标志 */
	    newtio.c_oflag = 0;     /* 输出模式标志 */
	    newtio.c_lflag = 0;   /* local mode flags */
	    newtio.c_cc[VMIN]=1;
	    newtio.c_cc[VTIME]=0;
	 /* now clean the modem line and activate the settings for modem */
	    tcflush(fd, TCIFLUSH);
	    tcsetattr(fd,TCSANOW,&newtio);/*set attrib    */
	
	    sa.sa_handler = child_handler;
	    sa.sa_flags = 0;
	    sigaction(SIGCHLD,&sa,NULL); /* handle dying child */
	    pthread_create(&th_a, NULL, keyboard, 0);
	    pthread_create(&th_b, NULL, receive, 0);
	    pthread_create(&th_c, NULL, send, 0);
	    pthread_join(th_a, &retval);
	    pthread_join(th_b, &retval);
	    pthread_join(th_c, &retval);
	
	    tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */
	    tcsetattr(0,TCSANOW,&oldstdtio); /* restore old tty setings */
	    close(fd);
	    exit(0); 
	}

3. tty.c代码

.#include <stdio.h> /*标准输入输出定义*/
.#include <unistd.h> /*linux 标准函数定义*/
.#include <fcntl.h> /*文件控制定义*/
.#include <errno.h> /*错误号定义*/
.#include <termios.h> /*PPSIX 终端控制定义*/

int main()
{
int fd,n;
    char buf[256];
fd=open("/dev/ttyS1",O_NOCTTY|O_RDWR|O_NONBLOCK); /*以读写方式打开串口*/
if( fd < 0)  /* 不能打开串口一*/
{
perror("Unable open /dev/ttyS0
 ");
        return 1;
}
n = write( fd, "hello
", 6);
if ( n < 0 )
        puts( "write() of 6 bytes failed!
");
puts( "write() of 6 bytes ok!
");

while(1)
{
        read(fd,buf,256);
        puts(buf);
        if(strncmp(buf,"quit",4)==0)break;  
}
return 0;
}

int set_port(int fd)
{
    struct termios opt;

    tcgetattr(fd,&opt);/*get current option setup*/
    show_option(&opt);

//  opt.c_cflags &= 
    tcsetattr(fd,&opt);/*get current option setup*/
}

三、遇到的问题及解决
这次实验和实验一一起完成的,基本没有遇到问题,只是由于这些指令平时没有用功,出现把命令敲错了情况,没有其他问题

原文地址:https://www.cnblogs.com/jdy1453/p/6059499.html