1 基于嵌入式 Linux 开发基础 丁男
2 概要 基于 linux 系统开发简介 基于 linux 系统开发简介 多线程技术 多线程技术 对文件操作 对文件操作 对设备操作 对设备操作
3 嵌入式 Linux 的开发过程 针对嵌入式 linux 的系统开发环境 针对嵌入式 linux 的系统开发环境 开发平台: linux 桌面系统,如 red hat, debin 等。 编辑器: vi(m) 编译器: Armv4l-unknown-linux-gcc 基于嵌入式 linux 系统的开发流程 基于嵌入式 linux 系统的开发流程 编写代码 编辑器 编译代码 编译器 下载代码
4 可执行代码的格式 可执行代码格式 可执行代码格式 a.out 早期 linux 执行格式,用 gcc 不加 -o ,即默认输出格式。 elf gcc –o 的输出格式 扩展名 扩展名 在 linux 下,应用程序没有固定的扩展名,只要有可以执 行性就可以 可用 ls –l 查看其可行性 运行./filename
5 如何自动运行用户程序 rc.local rc.local./root/usr/etc/rc.local#/////////////////#!/bin/sh ifconfig lo route add -net netmask lo portmap if [ -f /mnt/yaffs/init.sh ]; then /mnt/yaffs/init.sh fi #Add user’s program./program #exec /sbin/getty ttyS
6 多线程编程技术 在 Linux 系统下,启动一个新的进程必须分配给它独 立的地址空间,建立众多的数据表来维护它的代码 段、堆栈段和数据段,这是一种 “ 昂贵 ” 的多任务工 作方式。而运行于一个进程中的多个线程,它们彼 此之间使用相同的地址空间,共享大部分数据,启 动一个线程所花费的空间远远小于启动一个进程所 花费的空间。而且,线程间彼此切换所需的时间也 远远小于进程间切换所需要的时间。 在 Linux 系统下,启动一个新的进程必须分配给它独 立的地址空间,建立众多的数据表来维护它的代码 段、堆栈段和数据段,这是一种 “ 昂贵 ” 的多任务工 作方式。而运行于一个进程中的多个线程,它们彼 此之间使用相同的地址空间,共享大部分数据,启 动一个线程所花费的空间远远小于启动一个进程所 花费的空间。而且,线程间彼此切换所需的时间也 远远小于进程间切换所需要的时间。
7 多线程的优点 提高应用程序响应。 提高应用程序响应。 使多 CPU 系统更加有效。 使多 CPU 系统更加有效。 改善程序结构。 改善程序结构。 线程间方便的通信机制。 线程间方便的通信机制。 线程间的通信方式。 线程间的通信方式。 个线程的数据可以直接为其它线程所用.
8 实例 /* example.c*/ #include #include void thread(void) { int i; for(i=0;i #include void thread(void) { int i; for(i=0;i<3;i++) printf("This is a pthread.n"); } int main(void) { pthread_t id; int i,ret; ret=pthread_create(&id,NULL,(void *) thread,NULL); if(ret!=0){ printf ("Create pthread error!n"); exit (1); } for(i=0;i<3;i++) printf("This is the main process.n"); pthread_join(id,NULL); return (0); }
9 运行结果 Gcc -lpthread –o thread example.c Gcc -lpthread –o thread example.c
10 相关函数及说明 编写 Linux 下的多线程程序,需要使用头文件 pthread.h 。 编写 Linux 下的多线程程序,需要使用头文件 pthread.h 。 线程创建函数: 线程创建函数: int pthread_create (pthread_t * thread_id, __const pthread_attr_t * __attr, void *(*__start_routine) (void *),void *__restrict __arg); 线程退出: 线程退出: void pthread_exit (void *__retval) 等待指定的线程结束: 等待指定的线程结束: int pthread_join (pthread_t __th, void **__thread_return)
11 线程的互斥 互斥锁:互斥锁用来保证一段时间内只有一个线程在 执行一段代码 。实现线程间数据的共享和通信 。 互斥锁:互斥锁用来保证一段时间内只有一个线程在 执行一段代码 。实现线程间数据的共享和通信 。 线程的互斥: 线程的互斥: 互斥锁的初始化: pthread_mutex_init (pthread_mutex_t *,__const pthread_mutexattr_t *) 锁定互斥量(阻塞): int pthread_mutex_lock (pthread_mutex_t *__mutex); 解锁互斥量 int pthread_mutex_unlock (pthread_mutex_t *__mutex) 销毁互斥量: int pthread_mutex_destroy (pthread_mutex_t *__mutex)
12 线程的同步 条件变量 条件变量被用来进行线承间的同步。 条件变量 条件变量被用来进行线承间的同步。 条件变量的结构为 pthread_cond_t , 条件变量的结构为 pthread_cond_t , 初始化条件变量函数: 初始化条件变量函数: int pthread_cond_init (pthread_cond_t *__restrict __cond,__const pthread_condattr_t *__restrict __cond_attr) 销毁条件变量 COND 销毁条件变量 COND int pthread_cond_destroy (pthread_cond_t *__cond) 唤醒线程等待条件变量 唤醒线程等待条件变量 int pthread_cond_signal (pthread_cond_t *__cond) int pthread_cond_signal (pthread_cond_t *__cond) 等待条件变量(阻塞) 等待条件变量(阻塞) int pthread_cond_wait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex) int pthread_cond_wait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex)
13 对文件操作 Linux 下最常用的操作就是对文件操作。 Linux 下最常用的操作就是对文件操作。 主要操作 主要操作 文件的创建和读写 文件的各个属性 目录文件的操作 int open(const char *pathname , int flags) ; int open(const char *pathname , int flags) ; O_RDONLY :以只读的方式打开文件。 O_WRONLY :以只写的方式打开文件。 O_RDWR :以读写的方式打开文件。 O_CREAT :创建一个文件。 ssize_t read(int fd , void *buffer , size_t count) ; ssize_t write(int fd , const void *buffer , size_t count) ; ssize_t read(int fd , void *buffer , size_t count) ; ssize_t write(int fd , const void *buffer , size_t count) ; int close(int fd) ; int close(int fd) ; int access(const char *pathname,int mode); int access(const char *pathname,int mode); R_OK 文件可以读, W_OK 文件可以写, X_OK 文件可以执行, F_OK 文件存 在
14
15 与操作目录相关的函数 int mkdir(const char *path , mode_t mode) ; int mkdir(const char *path , mode_t mode) ; DIR *opendir(const char *path) ; DIR *opendir(const char *path) ; struct dirent *readdir(DIR *dir) ; struct dirent *readdir(DIR *dir) ; void rewinddir(DIR *dir) ; void rewinddir(DIR *dir) ; off_t telldir(DIR *dir) ; off_t telldir(DIR *dir) ; void seekdir(DIR *dir , off_t off) ; void seekdir(DIR *dir , off_t off) ; int closedir(DIR *dir) ; int closedir(DIR *dir) ;
16 对串口操作 打开串口 在 Linux 下串口文件是位于 /dev 下的 打开串口 在 Linux 下串口文件是位于 /dev 下的 串口一 为 /dev/ttyS0 串口二 为 /dev/ttyS1 int fd; /* 以读写方式打开串口 */ fd = open( "/dev/ttyS0", O_RDWR); fd = open( "/dev/ttyS0", O_RDWR); if (-1 == fd) { /* 不能打开串口一 */ perror(" 提示错误! "); } 关闭串口 关闭串口 close(fd);
17 串口的设置 struct termio { unsigned short c_iflag; /* 输入模式标志 */ unsigned short c_iflag; /* 输入模式标志 */ unsigned short c_oflag; /* 输出模式标志 */ unsigned short c_cflag; /* 控制模式标志 */ unsigned short c_lflag; /* local mode flags */ unsigned char c_line; /* line discipline */ unsigned char c_cc[NCC]; /* control characters */ };
18 波特率的设定 struct termios Opt; tcgetattr(fd, &Opt); cfsetispeed(&Opt,B19200); /* 设置为 19200Bps*/ cfsetospeed(&Opt,B19200);tcsetattr(fd,TCANOW,&Opt);或者: newtio.c_cflag = B19200| CRTSCTS | CS8 | CLOCAL | CREAD;/*ctrol flag*/
19 读写操作 读操作 读操作 int readByte = read(fd, buff, Len); 写操作 写操作 nByte = write(fd, buffer,Length) ;