什么是系统调用?.应用编程与裸机编程、驱动编程有什么区别?

目录

一 何为系统调用

1.系统调用

2.应用编程与裸机编程、驱动编程有什么区别?

2.1裸机编程:

2.2驱动编程

2.3应用编程

二 何为库函数

1.概念

2.库函数部分函数是由系统调用封装

3.为啥要使用库函数

三 应用程序的 main()函数

应用编程概念

概念:应用编程是指基于操作系统的应用程序开发,通过调用系统 API 完成应用程序的功能和逻辑。应用程序运行于操作系统之上,在用户态运行。与裸机编程和驱动编程相比,应用编程是在操作系统环境下进行的,利用操作系统提供的系统调用和库函数来实现应用程序的功能。应用编程主要涉及系统调用库函数应用程序的开发环境等内容。

一 何为系统调用

1.系统调用

系统调用(system call)其实是 Linux 内核提供给应用层的应用编程接口(API),是 Linux 应用层进入 内核的入口。不止 Linux 系统,所有的操作系统都会向应用层提供系统调用,应用程序通过系统调用来使用 操作系统提供的各种服务。

通过系统调用,Linux 应用程序可以请求内核以自己的名义执行某些事情,譬如打开磁盘中的文件、读 写文件、关闭文件以及控制其它硬件外设。

系统调用是内核直接向应用层提供的应用编程接口,譬如 open、write、read、close 等

通过系统调用 API,应用层可以实现与内核的交互,其关系可通过下图简单描述: 

2.应用编程与裸机编程、驱动编程有什么区别?

2.1裸机编程:

单片机程序是裸机程序,没有操作系统的概念 单片机程序是硬件驱动+业务逻辑的集合,程序是整体编译

一般把没有操作系统支持的编程环境称为裸机编程环境

2.2驱动编程
  1. 驱动程序运行在内核空间
  2. 驱动程序完成的是底层硬件操作逻辑
  3. 驱动程序可编译成模块或内置到内核,但都需要依赖于内核源码进行编译
2.3应用编程
  1. 应用程序运行在用户空间
  2. 应用程序完成的是业务逻辑
  3. 应用程序可单独编译

案列:比如要写一个流水灯的程序,驱动编程就是操作寄存器来点灯,而应用程序则是通过系统调用写好的点灯驱动程序来完成业务代码,点亮流水灯 

二 何为库函数

1.概念

库函数也就是 C 语言库函数,C 语言库是应用层使用的一套函数库,在 Linux 下,通常以动态(.so) 库文件的形式提供,存放在根文件系统/lib 目录下

2.库函数部分函数是由系统调用封装

C 语言库函数构建于系统调用之上,也就是说库函数其 实是由系统调用封装而来的,当然也不能完全这么说,原因在于有些库函数并不调用任何系统调用,譬如一 些字符串处理函数 strlen()、strcat()、memcpy()、memset()、strchr()等等;

而有些库函数则会使用系统调用来 帮它完成实际的操作,譬如库函数 fopen 内部调用了系统调用 open()来帮它打开文件、库函数 fread()就利用 了系统调用 read()来完成读文件操作、fwrite()就利用了系统调用 write()来完成写文件操作。

3.为啥要使用库函数

Linux 系统内核提供了一系列的系统调用供应用层使用,我们直接使用系统调用就可以了呀,那为何还 要设计出库函数呢?

事实上,有些系统调用使用起来并不是很方便,于是就出现了 C 语言库,这些 C 语言 库函数的设计是为了提供比底层系统调用

  1. 更为方便
  2. 更为好用
  3. 且更具有可移植性的调用接口。
  •  库函数是属于应用层,而系统调用是内核提供给应用层的编程接口,属于系统内核的一部分;
  •  库函数运行在用户空间,调用系统调用会由用户空间(用户态)陷入到内核空间(内核态);
  • 库函数通常是有缓存的,而系统调用是无缓存的,所以在性能、效率上,库函数通常要优于系统调 用;
  • 可移植性:库函数相比于系统调用具有更好的可移植性,通常对于不同的操作系统,其内核向应用 层提供的系统调用往往都是不同,譬如系统调用的定义、功能、参数列表、返回值等往往都是不一 样的;而对于 C 语言库函数来说,由于很多操作系统都实现了 C 语言库,C 语言库在不同的操作

所以库函数在不同操作系统之间相比于系统调用具有更好的 可移植性。

所以应用编程简单点来说就是:开发 Linux 应用程序,通过调用内核提供的系统调用或使用 C 库函数 来开发具有相应功能的应用程序。

三 应用程序的 main()函数

对学习过 C 语言编程的读者来说,譬如单片机编程、Windows 应用编程等,main 函数想必大家再熟悉 不过了,很多编程开发都是以 main 函数作为程序的入口函数,同样在 Linux 应用程序中,main 函数也是作 为应用程序的入口函数存在,main 函数的形参一般会有两种写法,如果执行应用程序无需传参,则可以写 成如下形式:

示例代码 1.4.1 main 函数写法之无传参

int main(void)

{ /* 代码 */

}

如果在执行应用程序的时候需要向应用程序传递参数,则写法如下:

示例代码 1.4.2 main 函数写法之有传参

int main(int argc, char **argv)

{ /* 代码 */

}

argc 形参表示传入参数的个数,包括应用程序自身路径和程序名,譬如运行当前目录下的 hello 可执行 文件,并且传入参数,如下所示: ./hello 112233

那么此时参数个数为 2,并且这些参数都是作为字符串的形式传递给 main 函数: argv[0]等于"./hello" argv[1]等于"112233

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@ChenPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值