1 应用层与驱动层

要想学习嵌入式Linux应用层的开发,首先要区分好应用层和驱动层之间的关系。我们在本科阶段学习51等较简单的单片机时,都是把应用层和驱动层混在一个文件里写的。比如拿下面的I2C程序为例:

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define nop _nop_()sbit sda = P2^1;//sda接在P2.1
sbit scl = P2^0;//sda接在P2.0void delay1()//用于每个语句间的延时
{;//空语句;;
}void delay(unsigned int i )//用于LED亮灯延时
{while(i--);
}/*scl在高电平期间,sda由高电平变成低电平时,I2C启动*/
void start_24c02()    //用于24C02的启动
{scl = 1;delay1();   sda = 1;delay1();sda = 0;delay1();}/*scl在高电平期间,sda由低电平变成高电平时,I2C停止*/
void stop_24c02()   //用于24c02启动
{sda = 0;delay1();scl = 1;delay1();sda = 1;delay1();
}/*scl在高电平期间,sda变成低电平表示应答*/
void ack_24c02()    //24C02的应答
{uchar i = 0;scl = 1;delay1();while((sda ==1)&&(i<200)) //(i<200)表示:如果期间不给应答信号,则程序会一直停在这里,为了避免长时间的等待应答,在此处增加了一个延时{i++;}scl = 0;delay1();}/*I2C总线初始化,将I2C总线全部设置为高电平,来释放总线*/
void init_24c02()//I2C总线的初始化
{sda = 1;delay1();     scl = 0;delay1();
}/*读取一个字节*/
uchar read_onebyte_24c02()
{uchar i,date;scl=0;delay1();sda=1;delay1();  for(i = 0;i<8;i++)                 {scl = 1;                   delay1();                                     date=(date<<1)|sda;                scl = 0;delay1();            }delay1();          return date;}/*写一个字节*/
void write_onebyte_24c02(uchar date)
{uchar i,temp;temp = date;for(i=0;i<8;i++)                {temp = temp<<1;    scl = 0;delay1();sda =CY;  //temp 左移一位,将移出的最高位字节放到PSW的CY中delay1();scl = 1;delay1();}scl = 0;delay1();sda = 1;delay1();
}/*对从机的某一地址的某一位置写入一个字节
1、找到要操作地址的从机,同时进行写操作0xA0
2、要写入的位置add
3、要写入的数据dat
*/
void write_add_dat_24c02(uchar add,uchar dat)
{start_24c02();                 write_onebyte_24c02(0xA0);       //进行写操作0XA0,24C02 的高四位地址为1010;后三位地址A2、A1、A0全部接地,所以为000,;由于为写操作,所以最后一位也为0ack_24c02();                   write_onebyte_24c02(add);       ack_24c02();                     write_onebyte_24c02(dat);      ack_24c02();                     stop_24c02();
}/*读取某地址的一个字节
1、找到要操作地址的从机,同时进行写操作0xA0
2、要写入的地址add
3、对选中地址的从机进行读操作 0xA1
4、调用读取一个字节函数read_onebyte_24c02(),进行数据读取
*/
uchar read_add_dat_24c02(uchar add)
{uchar dat;start_24c02();                    write_onebyte_24c02(0xa0);      ack_24c02();                    write_onebyte_24c02(add);       ack_24c02();                    start_24c02();                  write_onebyte_24c02(0xa1);  //进行读操作0XA0,24C02 的高四位地址为1010;后三位地址A2、A1、A0全部接地,所以为000,;由于为读操作,所以最后一位为1ack_24c02();                     dat = read_onebyte_24c02();   ack_24c02();stop_24c02();                    return (dat);
}void main()
{init_24c02();                       //初始化I2C while(1){write_add_dat_24c02(3,0x0f);  //对地址3进行写入数据delay(200);                         write_add_dat_24c02(4,0xf0);    //对地址4进行写入数据delay(200);                        P3 = read_add_dat_24c02(3);         //读取地址3的数据delay(55000);                     //保持灯亮P3 = read_add_dat_24c02(4);      //读取地址4的数据delay(55000);                    //保持灯亮}
}

该程序所要实现的功能是将数据0x0f和0xf0分别写入地址3和地址4。这个目标可以分为两部分执行:第一部分是计算出要存储的数据(由于该程序要存储的数据已经给出来了,就不用算了,但在实际工程中,这些数据一般是要自己获取的),第二部分是按照I2C协议的时序将这些数据发送给硬件。于是,上面提到的第一部分被称为应用层开发,第二部分被称为驱动层开发。

我们观察以上示例代码,发现作者还是很规矩地把驱动层程序编程了函数的形式(例如write_add_dat_24c02()),但应用层和驱动层的程序终究还是存储在同一个c文件中。而在Linux系统中,驱动层和应用层分的很清楚,它们分别保存在两个不同的文件中。并且应用层的程序运行在用户空间中,驱动层的程序则是被编进了Linux内核里。在实际调用程序的过程中,由应用层程序执行数据计算等任务,任务执行完后通过一个接口将算好的数据发送给驱动层程序,最后由驱动层程序进行硬件实现。这样的分层有一个好处就是对于调用同一个硬件的应用程序,他的驱动层可以不用修改,只修改应用层程序就可以了

由于Linux操作系统现在发展的已经比较完善了,很多硬件设备都能在网上找到写好的驱动,因此在进行嵌入式Linux开发的过程中,一般更多地进行应用层的开发,只是当找不到合适的驱动时,才会在现有驱动程序的基础上进行适当改写,以使其适应我们的硬件。

2 Linux的文件结构

Linux下一切皆文件。在Linux系统中,不仅像文本文档等传统文件是文件,各种设备也可以被映射成一个文件。通过对设备文件进行操作就可以实现对设备的操作。因此,了解Linux的文件结构非常重要。

2.1 目录

目录是用来保存其他文件节点(inode)号和名字的文件,目录文件中的每项数据都指向一个文件的节点,删除一个文件就相当于删除了目录文件中对应的节点项。

那么问题来了,什么是文件的节点(inode)呢?文件节点其实就是保存了文件的属性的一个东西,这些属性包括文件的创建/修改日期、访问权限、文件位置、文件长度等等。Linux在寻找某文件或对,某个文件进行操作时,不是去寻找文件的名字,而是去寻找文件对应的节点。

Linux系统中最常用的目录之一就是家目录。Linux系统会为每个用户创建一个家目录。比如你的用户名叫neil,那你的家目录就是/home/neil/。很多Linux系统,比如Ubuntu,都允许用~ 符号代替用户的家目录。然而,标准库函数不能识别文件参数中的~ 符号,因此在程序中不要使用波浪线符号代替家目录。

所有目录的最顶层是根目录。在它下面包含了存放系统程序的/bin目录、存放系统配置文件的/etc目录、存放系统函数库的/lib目录和存放代表物理设备的设备文件的/dev目录等等。

2.2 文件和设备

在Linux中,设备可以被映射成一个文件。例如,我们可以使用以下命令将CD-ROM驱动挂载为一个文件:

mount -t iso9660 /dev/hdc /mnt/cdrom
cd /mnt/cdrom

这时我们进入到/mnt/cdrom下就可以查看CD-ROM中包含的目录,只不过其中的目录都是只读的。

Linux中有3个比较重要的设备文件:/dev/console、/dev/tty和/dev/null。

  1. /dev/console
    这个设备代表系统控制台。错误信息和诊断信息通常会被发到这个设备。

  2. /dev/tty
    如果一个进程有控制终端的话,文件/dev/tty就会作为控制终端的别名。但对于系统自动运行的进程和脚本,它们就没有控制终端,不需要访问设备/dev/tty。

  3. /dev/null
    这个设备是“空”设备,所有写向这个设备的输出都会被丢弃,而读这个设备会返回一个文件尾标志。通常用于作复制空文件的源文件,或将不需要的输出重定向到此文件。

设备可以分为字符设备和块设备,两者的区别在于访问设备时是否需要一次读写一整块。字符设备通常是普通的设备,块设备通常是硬盘、SD卡等存储设备。

嵌入式Linux应用层开发教程(一)基本概念相关推荐

  1. 《嵌入式Linux驱动开发教程》--高级I/O操作

    高级I/O操作 1.ioctl设备操作 2.proc文件系统 3.非阻塞式IO 4.阻塞式IO 5. IO多路复用 6.异步IO 7.异步通知(信号驱动IO模型) 8.相关代码 8.1非阻塞式IO用户 ...

  2. 嵌入式linux驱动开发教程

    目录 第二章 内核模块 宏内核和微内核 内核模块程序的初始化和退出函数原型 内核模块的相关工具 内核模块基本框架(内核最原始的结构) 多个源文件编译生成一个内核模块 内核模块参数(参数类型要注意) 内 ...

  3. 《嵌入式Linux驱动开发教程》--内核模块

    内核模块 绝大多数的驱动都是以内核模块的形式实现. 宏内核和微内核 宏内核(Linux):所有的内核功能都被整体编译在一起,形成单独的内核镜像文件,内核中各功能模块的交互通过直接的函数调用进行. 微内 ...

  4. 嵌入式linux驱动开发实战教程,嵌入式Linux驱动开发实战视频教程

    嵌入式Linux驱动开发实战教程(内核驱动.看门狗技术.触摸屏.视频采集系统) 适合人群:高级 课时数量:109课时 用到技术:嵌入式 Linux 涉及项目:驱动开发.看门狗技术.触摸屏.视频采集 咨 ...

  5. 嵌入式linux应用层中断函数,嵌入式LINUX驱动开发(中断处理函数)

    嵌入式LINUX驱动开发(中断处理函数) 2020年08月11日 | 萬仟网网络运营 | 我要评论 嵌入式LINUX驱动学习之7中断相关(一)中断处理函数一.函数.头文件及说明二.编译举例:一.函数. ...

  6. 【嵌入式Linux】嵌入式Linux应用开发基础知识之网络通信

    文章目录 前言 1.网络通信--TCP 1.1.常用概念辨析 1.2.程序分析 2.网络通信--UDP 程序分析 参考资料 前言 韦东山嵌入式Linux应用开发基础知识学习笔记 文章中大多内容来自韦东 ...

  7. 002_韦东山嵌入式Linux应用开发基础_实操碰到的问题集锦

    嵌入式Linux应用开发基础_韦东山教程思考笔记 配合<嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板> 文件目录 访问根/目录下,Filesystem Root目 ...

  8. 嵌入式Linux驱动程序开发

    嵌入式Linux驱动程序开发 1.设备驱动程序的概念... 2 2.处理器与设备间数据交换方式... 2 21.查询方式... 2 2.2.中断方式... 3 2.3.直接访问内存(DMA)方式... ...

  9. linux 没有那个文件或目录_【新视频进度】国庆节至今更新6节quot;嵌入式Linux应用开发基础quot;...

    说到做到,韦东山老师国庆没有休息,录了4节新视频,到目前快速入门-嵌入式Linux应用开发基础知识已更新6节: 01.HelloWorld背后没那么简单 02.GCC编译器的使用 03.Makefil ...

最新文章

  1. 5 -- Hibernate的基本用法 --2 1 Hibernate 下载和安装
  2. 残差平方和ssr的计算公式为_如何为你的回归问题选择最合适的机器学习方法?...
  3. 微信公众平台对所有公众号开放自定义菜单
  4. 全新目标检测范式SparseR-CNN,超详细实战教学(附数据集)
  5. 怎样才算精通Python?
  6. mysql5.7.11源码安装_MySQL5.7.10最新版本源代码安装详细过程_MySQL
  7. WPF GridControl控件的用法举例
  8. bpmn流程图_流程图怎么做?金舟在线流程图教你高逼格制作
  9. android.mk添加静态库,Android Gradle添加静态库
  10. 【王道考研操作系统】—文件的基本操作
  11. 微信账号公开买卖;华为:5G 火车站启动;小米 9 高通骁龙 855 全球首发 | 极客头条...
  12. Node.js折腾记一(改进):文件夹目录树获取
  13. linux复习题之阶段性考试题目
  14. DPDK X710 DDP PPPoE 实践
  15. 【CAS】CAS原理
  16. 2021最新城市人才引进计划!硕博满满的福利!
  17. 青龙面板 抖音极速版
  18. linux 安全删除文件_如何在Linux上安全删除文件
  19. 记一次webpack优化免费邮官网 ym.163.com
  20. IDEA运行卡顿,网页刷新不及时,网页报404错误以及Ajax收不到servlet返回的数据(已解决)

热门文章

  1. Spring Security 文档
  2. TechSmith Camtasia2023屏幕录像和编辑软件更新介绍
  3. MySQL添加外键时报错:ERROR 1452
  4. 什么是JIT?怎么优化?
  5. 7. awk数组,定义数组,判断元素是否存在,非数字下标,删除元素,查询数组
  6. VS2008正式版序列号
  7. Vue 项目中高亮格式化 xml 代码
  8. C语言——pow函数的使用,计算一个数的n次方
  9. java thread main_Exception in thread main 解决办法
  10. 【函数式编程】什么是函数式编程? C语言为何不是函数式语言?