拿嵌入式 Linux 硬件平台下的软件开发来说,我们大可将编程分为三种,分别为裸机编程、 Linux 驱动编程以及 Linux 应用编程。
裸机编程:
一般把没有操作系统支持的编程环境称为裸机编程环境,譬如单片机上的编程开发,编写直接在硬件上运行的程序,没有操作系统支持;
Linux 驱动编程:
Linux 驱动编程指的是基于内核驱动框架开发驱动程序, 驱动开发工程师通过调用 Linux 内核提供的接口完成设备驱动的注册, 驱动程序负责底层硬件操作相关逻辑, 如果学习过 Linux 驱动开发的读者,想必对此并不陌生;
Linux 应用编程:
Linux 应用编程(系统编程)则指的是基于 Linux 操作系统的应用编程,在应用程序中通过调用系统调用 API 完成应用程序的功能和逻辑, 应用程序运行于操作系统之上。通常在操作系统下有两种不同的状态:
内核态和用户态:
内核态和用户态,应用程序运行在用户态、而内核则运行在内核态。
系统调用和库函数:
系统调用是内核直接向应用层提供的应用编程接口, 譬如 open、 write、read、 close 等
库函数也就是 C 语言库函数, C 语言库是应用层使用的一套函数库, 在 Linux 下,通常以动态(.so)库文件的形式提供,存放在根文件系统/lib 目录下, C 语言库函数构建于系统调用之上,也就是说库函数其实是由系统调用封装而来的.
Linux 系统内核提供了一系列的系统调用供应用层使用, 我们直接使用系统调用就可以了呀,那为何还要设计出库函数呢?事实上, 有些系统调用使用起来并不是很方便, 于是就出现了 C 语言库,这些 C 语言库函数的设计是为了提供比底层系统调用更为方便、更为好用、 且更具有可移植性的调用接口。
它们之间的区别:
⚫ 库函数是属于应用层,而系统调用是内核提供给应用层的编程接口,属于系统内核的一部分;
⚫ 库函数运行在用户空间,调用系统调用会由用户空间(用户态)陷入到内核空间(内核态);
⚫ 库函数通常是有缓存的,而系统调用是无缓存的,所以在性能、效率上,库函数通常要优于系统调用;
⚫ 可移植性:库函数相比于系统调用具有更好的可移植性,通常对于不同的操作系统,其内核向应用层提供的系统调用往往都是不同,譬如系统调用的定义、功能、参数列表、返回值等往往都是不一样的;而对于 C 语言库函数来说,由于很多操作系统都实现了 C 语言库, C 语言库在不同的操作系统之间其接口定义几乎是一样的,所以库函数在不同操作系统之间相比于系统调用具有更好的可移植性。
所以应用编程简单点来说就是:开发 Linux 应用程序,通过调用内核提供的系统调用或使用 C 库函数来开发具有相应功能的应用程序。
glibc 官网
https://www.gnu.org/software/libc/
点击sources,本地配置好git环境即可下载
确定 Linux 系统的 glibc 版本:
进入目录 /lib/x86_64-linux-gnu
ls -l libc.so.6
2.23 表示的就是这个 glibc 库的版本号为 2.23
main函数一般是不需要传递参数的
int main(int argc, char **argv) {
}
或者写成
int main(int argc,char* argv[]) {
}
argc表示程序运行时发送给main函数的命令行参数的个数(包括可执行程序以及传参)。
argv[]是字符指针数组,它的每个元素都是字符指针,指向命令行中每个参数的第一个字符。