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设备