Linux应用开发基础知识
main函数中的两个参数:
argc argv 参数个数 存储数组
主要是传递参数用。
gcc 是c语言的编译工具
使用Linux-arm-gcc 编译完arm可执行程序后重新后,Ubuntu通过nfs网络文件系统传输文件至开发板,进行编译调试。
挂载指令:(数据传输)
mount -t nfs -o nolock,vers=3 192.168.3.40:/home/alienteek/linux/nfs get/
-t nfs : 网络文件系统
-o nolock 不带锁的,ver=3(nfs版本是3.0) 地址是xxx.xxx.xxx.xxx:Ubuntu的nfs目录 开发板存储目录
上面的指令意思是,把服务器上nfs里的文件挂载到开发板get文件夹里。
0若文件夹不存在,则要创建文件夹,使用mkdir get
.h 申明 ->在系统目录中(工具链目录),或者自己指定
.c实现
用户态 user
内核态kernel
硬件
GCC编译器
预处理 编译 汇编 链接
程序错误是在编译时检查,预处理不检查
gcc -o
gcc -c -o xxx.o 预处理 编译 汇编做了,但是不link
-I 指定目录找头文件 < >
静态库 ar crs xxx.a xxx.o
-lxxx 会链接xxx.o动态库链接
-L dir 指定查找的lib文件
-l动态库 链接
-E -dM > .txt 展开所有宏,看宏的链接
arm-linux-gcc
Makefile
目标文件 : 依赖文件 TAB+命令
当依赖比目标新,执行命令
gcc -c -o xxx.o xxx.c
gcc -o xxx a.o b.o
语法
% 通配符号
gcc -c -o xxx.o xxx.c gcc -c -o $@
$<
gcc -o xxx a.o b.o gcc -o xxx $^
$@ 表示目标
$< 表示第一个依赖文件
$^ 表示所有依赖文件
假想目标: PHONY:文件夹下有同名文件的时候,不要执行。
即时变量(简单变量)、延时变量,expor
a :=即时变量,马上确定的量,马上赋值
b = 使用到的时候才赋值 延时变量
?= 如果是第一次定义才起效,如果前面定义过该变量,则忽略这句话
+= 附加,它是及时变量还是延时变量,取决于前面的定义
函数
$(foreach val,$(A),$(val).o)
遍历循环函数
filter
查找函数
fileter_out
查找取反
wildcard 查找同一目录下的所有同后缀名的文件、查找真实存在的文件,从文件列表中
patsubst 替换操作
gcc生成依赖
gcc -M 打印出依赖
-MF 依赖写入文件
ifneq
endif
CFLAGS 编译参数
1 - werror很多警告都是有错误的,要变成error
通用Makefile
Makefile笔记 韦东山通用Makefile解析 - 明明1109 - 博客园 (cnblogs.com)
文件IO
函数
标准IO f开头 先把数据读入/写入用户buffer,然后对其进行读写,一定条件后再执行系统调用IO
系统调用IO open/read/write 每次都会进入内核
posix 通用接口
open函数
man man 查找函数调用方法
O_RDWR 可读可写可操作
#include<errno.h>
perror(“open ”) 打印错误信息
fd -l
kill - 9 程序id
ls -l
cd /proc/id号/fd
查看打开的文件
0 标准输入
1标准输出
2 标准错误
open 函数创建文件 已存在的文件无法改变权限
O_CREAT 如果不存在,创建文件
man 2 open 查看手册
umask//屏蔽参数,chmod&~umask 得到文件权限。防止给文件夹过大的权限。例如,禁止给orhers写权限
写入数据
write
某个位置写
lseek 文件读写偏移
read函数
O_TRUNC
hexdump -C 文件名 打印文件,以126进制打印
\n \r 空格、换行
strcpy copy字符串的
sscanf:从字符串中得到数据
strlen() 字符串大小
文件头部 编码格式 回车换行 0d 0a \r\n
系统调用接口,由glib.c实现。系统调用接口 触发异常(设置原因)分辨异常(原因) 处理异常(调用不同的函数) 继续执行
glib.c、app.c 用户空间,用户层面
内核文件怎么打开?
接口:ABI
EABI
OABI
/proc/id 进入进程目录
程序句柄如何和具体文件挂钩?
内核:task_struct->files_struct->fdtable.file_rcu *fd,这个fd就是进程的fd号(程序句柄)
每个进程有自己的文件句柄空间。
不同的进程结构体file中的f_pos也不一样,虽然打开了相同文件
如果用dup(fd)(内核中会得到一个未使用的最小的文件句柄),让不同的文件句柄指向同一个fd,这样就 共用f_pos
输出句柄重定向 dup2(3,1)//3号的复制到1号 关闭1号文件,然后1号指针指向3号
dup3
Framebuffer应用编程
LCD一种驱动程序
用来保存一帧数据的内存
要知道分辨率、bpp:每个像素用多少位来表示
offset:偏移地址,比如(x,y)的像素: (y*x方向的像素分辨率 + x)*bpp/8
第一行是0,0开始的
RGB888(32BPP)
16BPP RGB565 RGB555
获取lcd 参数 根据偏移地址找到相应左边
open:打开驱动程序
ioctl :获取lcd参数
mmap:映射frambuffer
描点函数fb_base
RGB颜色转换:
例如888->565: 最高的不取 取高5位置 高6位 高5位置就行、
888: 24bit 16bit 8bit 0bit 最高8位是AAAAAAAA
ascii码可以表示128个字符2^7
ANSI:编码 不同的编码会编译出不同的字符
unicode 不同的编码只对应不同的字符,一一对应的。0000-10FFFF 3个字节
UTF8:每个字符都带有字符长度值
点阵字符实现
fontdata8x16
spft
指定编码格式 -finput-charset = GB2312 -fexec-charset =UTF-8
字库文件 区码第一个-0xa1 位码 第二个 -0xd0
交叉编译程序
freetype(矢量字体)为例子
运行时候,不用把头文件放到板子上
wchar中保存的是unicode编码的值
输入系统驱动层、输入系统核心、输入系统事件层
驱动程序上报:type 、code、value
input_event
hexdump
同步事件
input_value结构体
type code value
1byte 1byte 2byte
输入事件写法
poll/select
查询方式、休眠唤醒、poll方式、异步通知
ioctl函数
eventbit
查询方式O_NONBLOCK 一直查询
休眠唤醒不传入O_NONBLOCK
strcmp(a,b)
poll 和定时中断差不多
异步通知方式 和外部中断差不多
app注册信号处理函数
signal
SIGIO
打开驱动程序 signal();
告诉进程号 fcntl();
使能异步通知 fcntl();
电阻屏和电容屏
slot 其实符
tslib 触摸屏开源库 src 接口函数 plugins/module插件 tests测试程序
tslib内核源码涉及链表,头插链表,处理数据时候用了递归的思想,从顶层开始一直套向底层。
下载 配置 make make install prefix
tslib配置 读取 处理
网络编程
网络通信 数据传输三要素:源、目的、长度 A B
服务器:被动响应请求
客户端:主动发起请求
TCP:可靠,有重新传输机制。传输命令、文件可用。有连接
UDP:不可靠。视频传输可用、无连接
怎么写程序 fd、read、write
IP、端口
TCP传输:服务器:fd=socket()
bind(自己的ip、端口信息)
listen(开始监测数据)
accept(等待建立一条连接)
send(发)
receive(收)
客户端: fd=socket()
connect(目的)
send(发)
receive(收)
fork:创建进程(子进程) 相当于父子进程,
ps - A
僵尸进程 用signal函数消除僵尸进程
UPD编程
服务器:fd=socket()
bind(自己的ip、端口信息)
sendto(发)
receive_from(收)
客户端: fd=socket()
connect(目的)
可不用这个函数,用send_to就行
send_to(发)
receive_fro,(收)
多线程编程
调度是以线程为单位,资源分配以进程为单位
多进程(例如,每个main函数就是一个进程)。不同main函数通信效率低
创建线程pthread_create 创建的线程和中断差不多
ps -T 查看
kill -9 pid号
程序休眠: 使用信号量 sem_wait(等待信号量) sem_post(唤醒信号量)
互斥访问 pthread_mutex_lock pthread_mutex_unlock
在进程中,先使用lock,执行完该进程中的线程后,再unlock,再让其他进程继续运行。
同步操作 pthread_mutex_lock pthread_cond_wait
先锁定进程,然后在pthread_cond_wait中判断条件是否成立,成立的话继续执行,否则释放互斥量,继续等待、
串口编程(UART)
通用异步接收器
1、波特率(每一位占据的时间)
2、格式:数据位、停止位、校验位、流控
开始位(从高拉到低)
数据位中间读取引脚状态
校验位(奇偶校验)
停止位(一位、1.5位、2位)
RS232、TTL电平
FIFO
115200,8n1 t=1/115200,传输1byte要10位(start,data,stop)。1s能传11520byte数据
TTY体系设备节点差别
TTY(远程打印机)
TTY0是前台的终端 其他的都是虚拟终端
dev/tty 表示当前程序使用的终端
终端
控制台console 权限更大,可以控制终端
dev/console
tty0、tty1是虚拟终端
TTY驱动程序框架
Line discipline 行规程 处理输入、输出的数据用的
需要设置行规程,处理一些字符输入、输出等。
ls dev/tty 可以看板子上的串口号等
mount /dev/mmcblk2p2 /boot 挂载设备树
串口编程
串口驱动、行规程、TTY驱动
open 设置行规程 read/write
exe 串口号 执行程序
串口回环
gps编程
sscanf分隔符高级用法,可以把逗哈去掉解析数据 %[^,]
I2C
I2C协议
上拉电阻 传输数据 一主多从
写操作:开始 设备地址 方向 回应 数据 回应 数据 回应 P结束
读操作: 开始 地址 方向 回应 数据 回应 数据 回应 P结束
设备地址P:7bit 地址和1位读写标志位 低电平是回应信号
SCL高电平 传输SDA数据 开漏输出 不加上拉会烧掉的 scl也是开漏输出,所以也要上拉
SMBus协议(I2C协议的一个子集)
VDD只支持1.5-1.8
时钟频率有限制,min10khz
等待ack回应时间要小于一定值
地址回应ack 一定要回地址回应信号
不用再发P信号,直接再次发送start信号就行
对数据格式有要求
PEC校验码
I2C的话优先使用SMbus。
I2C硬件框架 设备驱动:负责控制读写数据、控制器驱动:负责传输
确定第几个I2C控制器I2C_adapter
i2c_client
I2C软件框架
I2C_tool
i2cget
i2ctransfer
i2cdetect y 检测i2c设备