一、shell基础命令
pwd 查看当前路径
cd 改变当前路径
cd 回到当前用户主目录
cd - 回到刚才的目录
mkdir 创建新目录
rm dir 删除空目录
rm dir -r 递归删除非空目录
ls 查看文件
-a 所有文件
-l 详细信息
-R 该目录及所有子目录的文件名
tree 以树形的方式显示文件
touch 创建空文件、更新三个时间
mv 移动、重命名文件
-f 强制覆盖已有文件
-v 输出移动信息
cp 拷贝文件
-r 拷贝目录
-a 拷贝所有
rm 删除文件
-f 删除前不提示,直接删除
file 查看文件类型
cat 查看文本内容(concatenate连接)
-n 对所有行编号
-b 对非空白行编号
more 逐屏查看文件内容
less 逐行查看文本内容
head 显示文件开头部分内容(默认显示十行)
-n n 显示前n行
-v 显示文件名
tail 显示文件结尾部分内容(默认显示十行)
-n n 显示后n行
-v 显示文件名
-f 实时更新(用追加重定向测试)
chown 改变文件的拥有者,只有当前文件的拥有者和root才可以
-R 递归修改子目录的文件
user :group 同时修改拥有者和拥有组
chgrp 改变文件的拥有组
-R 递归修改子目录的文件
find [路径] [参数] 最常用的文件查找工具
-name filename 查找文件名为filename的文件
-type [fdlpsbc] 根据文件类型查找
-perm –xxxx 查找权限为xxxx 的文件
-user username 查找username用户的文件
-group groupname 查找groupname组用户的文件
-exec command {} \; 每查找一个文件就执行一次command
tar
功能:打包,根据不同选项实现打包压缩或解压解包
用法:
tar -jxvf a.tar.bz2
tar -zcvf b.tar.gz xxx/
j----处理的是bzip2格式的
z----处理的是gz格式的
x----解包解压
c----打包压缩
v----显示过程信息
f----指定操作对象文件的名字
ps
功能:查看进程状态
用法: ps -ef
ps aux
ps ajx
diff/patch 制作补丁/打补丁
diff old/ new/ -ruN > patch.old
cd old
patch -p1 < ../patch.old
patch -p1 < ../patch.old -R //打补丁的反操作
ln
软链接:相当于win的快捷方式
ln -s target softlink
ln -s a.txt a.soft
硬链接:复制+同步更新
ln a.c a.hard
a.hard 与a.c 的inode相同,链接数也一样
ifconfig 查看/修改IP
sudo ifconfig ens33 192.168.23.4
ls | cat 把ls的输出通过管道(|)给到cat命令作为其输入
head -n 10 a.txt | tail -n 1
ls | xargs grep "hello" -Hrnw
在ls列出的各个文件的内容中搜索“hello”,(把一个命令的输出,作为另一个命令的参数)
/ ---根目录结构内容
├── bin ---可执行的程序
├── boot ---系统启动相关文件
├── cdrom
├── dev ---设备文件
├── etc ---配置文件
├── home
├── initrd.img -> boot/initrd.img-4.10.0-37-generic
├── initrd.img.old -> boot/initrd.img-4.10.0-35-generic
├── lib ---库
├── lib32
├── lib64
├── lost+found
├── media
├── mnt ---常用的挂载目录
├── opt
├── proc ---虚拟文件系统,系统运行的各种信息都在该目录下
├── root ---超级用户的家
├── run
├── sbin ---只有root有权限执行的可执行程序
├── snap
├── srv
├── sys ------系统中内核驱动相关信息在此目录下
├── tmp
├── usr-------用户程序、头文件 库
├── var------易变的,例如系统日志文件
├── vmlinuz -> boot/vmlinuz-4.10.0-37-generic
└── vmlinuz.old -> boot/vmlinuz-4.10.0-35-generic
2、动态库与静态库
gcc main.c -o main -I dir1/ -L dir2 -lxxx
-I 告诉gcc头文件在dir1目录下
-L 告诉gcc需要的库在dir2目录下
-lxxx 告诉gcc链接的是xxx库而不是yyy库
静态库的制作与使用
gcc -c add.c
gcc -c sub.c
ar rcsv libxxx.a add.o sub.o//静态库xxx制作OK
gcc main.c -o main -I dir1/ -L dir2 -lxxx
动态库的制作与使用
gcc -fpic -Wall -c yyy.c
得到yyy.o
gcc -shared -o libxxx.so yyy.o
得到了动态库libxxx.so
使用:
编译:gcc main.c -o main -I dir1/ -L dir2 -lxxx ------相同目录下,同名的动态库和静态库,优先链接动态库
如果想要链接静态库:编译:gcc main.c -o main -I dir1/ -L dir2 -lxxx -static
把libxxx.so拷贝到系统默认的库路径下/lib 或/usr/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:dir/ ----dir为动态库所在路径,写绝对路径,不用共享目录
修改/etc/ld.so.conf 把动态库所在路径追加到最后
sudo ldconfig ---使新修改的配置生效
gcc -Wl,-rpath,dir/ main.c -o main -I dir1/ -L dir2 -lxxx ---dir为动态库所在路径
其中-Wl,-rpath,dir1/:dir2/.....
env -----查看系统中所有环境变量
echo $PATH ----打印出PATH环境变量的值
3、make工具(makefile的编写)
make工具默认在当前目录下依照下列顺序读取内容
GNUmakefile makefile Makefile
makefile基本格式
目标:依赖文件 -----makefile中第一个出现的目标是最终目标
TAB命令
命令执行的条件(满足其一):
目标不存在
依*新
makefile的变量
自定义变量
DEP=main.o add.o sub.o
$(DEP)
$(CC) $(CFLAGS)
系统预定义变量
自动变量
$@ ----目标文件的完整名
$< ----依赖的第一个文件的完整名
$^ ----依赖的所有的文件,并以空格隔开
makefile 的规则
普通规则
模式规则
VAR=main.o add.o sub.o
main:$(VAR)
gcc -o $@ $(VAR)
%.o:%.c
gcc -c $< -o $@
.PHONY:clean
clean:
rm -f *.o main
隐式规则
main:
注意:隐式规则使用时不能有其它编译选项,目标名与源文件名相同
make 的常用选项
make -f xxx
make -C dir/
以dir_makefile目录下的simplemakefile作为makefile来组织编译程序
make -C ./dir_makefile/ -f simplemakefile
双目标
main::a.c
gcc -o main a.c
main::b.c
gcc -o main b.c
4、gdb调试器
编译时:gcc -g main.c -o main
gdb main
l (list)---查看代码
b 20 ---在20行设置断点
b 9 if i>98
info b ---查看断点信息
d 断点编号----删除断点
r run ---运行程序
next/step/continue
n--不进入函数内部,一次执行完一句
s--进入函数内部单步执行
c--从断点继续执行到程序结束
print i---- 打印变量i的值
display i
q quit--退出调试状态
5、Ubuntu上服务器搭建,与arm运行环境连接
设置开发板IP
ifconfig eth0 192.168.23.xxx ---------开发板的IP重启后失效
可修改/etc/profile
添加ifconfig eth0 192.168.23.xxx
重新启动
nfs服务器
确保虚拟机能够上外网
sudo apt-get update
sudo apt-get install nfs-kernel-server nfs-common
sudo gedit /etc/exports
在末尾加上
/opt/nfs *(rw,sync,no_subtree_check)
Rw-------客户端对该目录可读可写
Sync----双方同步更新
no_subtree_check--------客户端与系统中当前用户权限相同
重启
sudo service nfs-kernel-server restart
查看设置好的nfs服务器目录
showmount -e
看到
/opt/nfs *
修改/opt/nfs的权限
sudo chmod 777 /opt/nfs -R
开发板端
mount -t nfs -o nolock 192.168.23.4:/opt/nfs /mnt
把ip为192.168.23.4的主机上的/opt/nfs目录,挂载到开发板的/mnt就可以通过/mnt访问到虚拟机中/opt/nfs目录下的内容
tftp服务器
sudo apt-get install tftp tftpd openbsd-inetd
sudo gedit /etc/inetd.conf
添加:
tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /opt/tftp
sudo mkdir /opt/tftp
sudo chmod 777 /opt/tftp/ -R
重启tftp
sudo service openbsd-inetd reload
sudo service openbsd-inetd restart
查看tftp服务是否启动
netstat -a
netstat -a | grep "tftp"
sudo cp aaa.txt /opt/tftp/
开发板端
tftp -g -r aaa.txt 192.168.23.4
从IP为192.168.23.4主机的tftp服务器目录下,下载文件aaa.txt到开发板
6、交叉编译工具链的安装与使用
解压
tar -jxvf 4.5.1.tar.bz2 (注意不要在共享目录下解压)
tar -jxvf 4.5.1.tar.bz2 -C dir/
得到目录4.5.1
设置环境变量
临时生效
export PATH=dir:$PATH
vim ~/.bashrc
在最后添加
export PATH=dir:$PATH
使新配置生效
source ~/.bashrc
/etc/bash.bashrc
/etc/profile
使用
arm-linux-gcc xxx.c -o xxx
注意:
64位的UBUNTU需要安装一些库才能兼容32位的交叉编译工具
sudo apt-get install lib32ncurses5
sudo apt-get insatll ia32-libs
7、库的移植
例如:JPEG库的移植
解压缩
tar -zxvf jpegsrc.v9a.tar.gz
cd jpeg-9a/
对jpeg源码进行配置
./configure --host=arm-linux --prefix=/home/gec/jpeglib
make
make install
把虚拟机中的jpeglib目录拷贝到开发板文件系统中的根目录下
/jpgelib
修改开发板中的配置脚本/etc/profile
增加:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/jpeglib/lib(检查后面是否有直接定义)
保存退出后重启开发板
编译:arm-linux-gcc show_jpeg.c -o show_jpeg -I /home/gec/include/ -L /home/gec/lib/ -ljpeg
SQLITE3库移植
解压缩
tar -zxvf sqlite-autoconf-3250200.tar.gz
cd sqlite-autoconf-3250200/
对SQLITE3库进行配置
./configure --prefix=/home/gec/armsqlite --host=arm-linux
make
make install
使用sqlite3的命令行
(1)创建数据文件(要求.db结尾)
sqlite3 数据库文件的名字
例如: sqlite3 xxxx.db
.tables //查看当前数据库文件中有多少个表格
.quit //退出sqlite3
.help //查看命令
.dump //查看历史输入命令
(2)创建表格
create table 表的名字 (字段1 修饰符号,字段2 修饰符号,........);
例如:create table stutable (name text,age int,score float);
创建好的表格自动存储在了.db数据文件中
(3)往表格中插入数据
insert into 表的名字 values(字段信息一一对应);
例如:insert into stutable values("wangwu",19,78); //重点values很容易漏掉
(4)删除表格中的数据
delete from 表名字 where 条件;
例如:delete from stutable where name="lisi"; //判断字符串相等,直接用=
(5)删除整个表格
drop table 表的名字
例如:drop table stutable;
(6)查询表格中的数据内容(重点)
select * from 表的名字; //查询所有的信息
例如:select * from stutable;
select name from 表的名字; //查询name这个具体字段
例如:select name from stutable;
select * from 表的名字 where 条件; //按照where语句后面的条件去查询
例如:select * from stutable where score<60;
select * from stutable where score>=60 and score<=80;
(7)修改表格中的数据
update 表名字 set 新的字段信息 where 旧的字段信息;
例如:update stutable set score=88 where score=60.5;
(8)常用的修饰语句
字段唯一性(比如:电话,身份证号码这些是不可能有重复的)
unique关键词修饰:
例如: create table stutable (name text,age int,phonenum char[11] unique);
null:表示空值
insert into stutable values("zhao",null,null);
空值如何修改删除
delete from sptable where price is null; //不要写成price=null
not null:限制字段不允许接收空值
like:模糊匹配字符串
select * from stutable where name like "%jian%"; //名字中有jian
select * from stutable where name like "zhang%";
select * from stutable where name like "%guo";
order by:升序/降序查询
select * from stutable order by age asc; //按照年龄升序
select * from stutable order by age desc; //按照年龄降序
if not exists:新建表格的是判断是否存在
create table if not exists stutable(name text,age int,phonenum char[11] unique);
注意的问题:
第一个:sqlite3并不帮助你检查数据类型
insert into stutable values(852,"kkk","hfdhsfjk");
第二个:字段个数必须一致
insert into stutable values("zhao",15,125879,78.9);
Error: table stutable has 3 columns but 4 values were supplied
第三个:区分.开头的命令和增删改查命令
.开头的命令后面没有分号
.开头的命令只能小写,但是增删改查命令大小写都行
第四个:同一个数据库文件中不允许出现同名的表格,哪怕表格中的字段不一样,也不行!!!!
第五个:命令输入错误,如何退出,直接输入分号,回车就可以了
代码实现数据库操作--->使用sqlite3源码中提供的接口函数(很重要)
(1)打开/新建数据库文件 //头文件sqlite3.h的第3338行
int sqlite3_open(const char *filename,sqlite3 **ppDb);
返回值:成功 返回SQLITE_OK 失败 参见头文件中的宏定义 //有点类似于errno
参数:filename -->你要打开的那个数据库文件的路径
ppDb -->存放数据库文件的句柄
(2)操作数据库文件,调用前面学习的命令 //重点
int sqlite3_exec(sqlite3*,char *sql,int (*callback)(void*,int,char**,char**),void *,char **errmsg);
返回值:成功 返回SQLITE_OK 失败 参见头文件中的宏定义
参数:sqlite3* -->将sqlite3_open中的句柄传递过来
sql -->你想要执行的语句
int (*callback)(void*,int,char**,char**) -->函数指针,当你使用查询命令的时候,就必须要用到该参数
参数: void* -->接收第四个参数传递过来的内容
int -->你查询的表格的列数
char** -->具体的每一行的信息
char** -->字段名
重点重点: 查询有结果,callback指向的函数就会被调用,没有结果就不调用
查询结果有几条,那么callback指向的函数就被调用几次
void * -->传递给callback的第一个参数
errmsg-->存放出错信息
(3)关闭数据库文件
int sqlite3_close(sqlite3*);
ALSA库移植
解压缩
tar -zxvf alsa-lib-1.0.22.tar.bz2
cd alsa-lib-1.0.22/
tar -zxvf alsa-utils-1.0.22.tar.bz2
cd alsa-utils-1.0.22/
交叉编译alsa-lib
./configure --prefix=/home/gec/myalsa \ (此处是alsa库的安装路径,是要按照实际情况来改的)
--host=arm-none-linux-gnueabi \
--disable-python
make
make install
交叉编译alsa-utils
./configure --prefix=/home/gec/myalsa \
--host=arm-none-linux-gnueabi \
--with-alsa-prefix=/home/gec/myalsa/lib/ \
--with-alsa-inc-prefix=/home/gec/myalsa/include/ \
--disable-alsamixer \
--disable-xmlto
make 会出现这个error:找不到alsa-utils-1.0.22/alsaconf/po下面的t-ja.gmo,只需要先创建文件t-ja.gmo,然后make,又出现找不到alsa-utils-1.0.22/alsaconf/po下面的t-ru.gmo,接着新建一个就行了
make install
ALSA库的使用
第一步:将移植得到的库文件,头文件,可执行程序打包下载到开发板中
配置动态库的环境变量或者偷懒直接将库文件拷贝到开发板的/lib
export LD_LIBRARY_PATH=/XXXX/XXXXX:$LD_LIBRARY_PATH
将bin文件中的arecord和aplay拷贝到开发板的/bin
第二步:设置alsa的配置文件路径
将移植得到的文件夹(bin include lib share)share中的alsa文件夹里面的所有文件复制到开发板的/home/gec/myalsa中
注意,注意,注意:解压之后的文件夹在开发板中路径也必须跟当初你移植的时候ubuntu上的路径一致
第三步:设置音频文件相关设备节点
执行写好的脚本 ./mknod.sh(开发板中打开这个脚本,将每一行后面的M去掉)
第四步:录音和播放
arecord -d3 -c1 -r16000 -twav -fS16_LE example.wav
说明:
-d:录音时长(duration) 秒
-c:音轨(channels)
-r:采样频率(rate) 人的耳朵 20HZ ---20000HZ
-t:封装格式(type)
-f:量化位数(format)16bit 小端
第五步:播放
执行如下命令播放
aplay example.wav
在做的过程中遇到的问题:
第一个问题: write error: No space left on device
解决方案: 第一步 mkfs.vfat /dev/mmcblk0p7 将/dev/mmcblk0p7格式化
第二步 mount -t vfat /dev/mmcblk0p7 /xxxx 将/dev/mmcblk0p7挂载到开发板/xxxx下面
第三步 以后你下载的大文件就存放到/xxxx就可以了(/xxxx就相当于是新开辟空间)