wordpress外贸网站好用的模板下载,用开源吗做的网站可以用吗,前端学校网站开发视频,淘宝网手机版1.1 系统调用
系统调用#xff08;system call#xff09;其实是 Linux 内核提供给应用层的应用编程接口#xff08;API#xff09;#xff0c;是 Linux 应用层进入内核的入口。不止 Linux 系统#xff0c;所有的操作系统都会向应用层提供系统调用#xff0c;应用程序通…1.1 系统调用
系统调用system call其实是 Linux 内核提供给应用层的应用编程接口API是 Linux 应用层进入内核的入口。不止 Linux 系统所有的操作系统都会向应用层提供系统调用应用程序通过系统调用来使用操作系统提供的各种服务。
通过系统调用Linux 应用程序可以请求内核以自己的名义执行某些事情譬如打开磁盘中的文件、读写文件、关闭文件以及控制其它硬件外设。
通过系统调用 API应用层可以实现与内核的交互其关系可通过下图简单描述 图 1.1.1 内核、系统调用与应用程序
内核提供了一系列的服务、资源、支持一系列功能应用程序通过调用系统调用 API 函数来使用内核提供的服务、资源以及各种各样的功能如果大家接触过其它操作系统编程想必对此并不陌生譬如Windows 应用编程操作系统内核一般都会向应用程序提供应用编程接口 API否则我们将我无法使用操作系统。
应用编程与裸机编程、驱动编程有什么区别
在学习应用编程之前相信大家都有过软件开发经验譬如 51、STM32 等单片机软件开发、以及嵌入式 Linux 硬件平台下的驱动开发等51、STM32 这类单片机的软件开发通常是裸机程序开发并不会涉及到操作系统的概念那应用编程与裸机编程以及驱动开发有什么区别呢
就拿嵌入式 Linux 硬件平台下的软件开发来说我们大可将编程分为三种分别为
裸机编程Linux 应用编程Linux 驱动编程
首先对于裸机编程这个概念来说很好理解一般把没有操作系统支持的编程环境称为裸机编程环境譬如单片机上的编程开发编写直接在硬件上运行的程序没有操作系统支持狭义上 Linux 驱动编程指的是基于内核驱动框架开发驱动程序驱动开发工程师通过调用 Linux 内核提供的接口完成设备驱动的注册驱动程序负责底层硬件操作相关逻辑如果学习过 Linux 驱动开发的读者想必对此并不陌生而 Linux 应用编程系统编程则指的是基于 Linux 操作系统的应用编程在应用程序中通过调用系统调用 API 完成应用程序的功能和逻辑应用程序运行于操作系统之上。
通常在操作系统下有两种不同的状态
内核态和用户态应用程序运行在用户态、而内核则运行在内核态。
关于应用编程这个概念以上给大家解释得很清楚了以实现点亮一个 LED 功能为例给大家简单地说明三者之间的区别LED 裸机程序如下所示
static void led_on(void) {/* 点亮 LED 硬件操作代码 */
}static void led_off(void) {/* 熄灭 LED 硬件操作代码 */
}int main(void) {/* 用户逻辑 */for ( ; ; ) {led_on(); //点亮 LEDdelay(); //延时led_off(); //熄灭 LEDdelay(); //延时}
}可以看到在裸机程序当中LED 硬件操作代码与用户逻辑代码全部都是在同一个源文件同一个工程中实现的硬件操作代码与用户逻辑代码没有隔离没有操作系统支持代码编译之后直接在硬件平台运行俗称“裸跑”。我们再来看一个 Linux 系统下的 LED 驱动程序示例代码如下所示
#include linux/module.h
#include linux/platform_device.h
#include linux/of_gpio.h
#include linux/delay.h
#include linux/cdev.h
#include linux/uaccess.hstatic void led_on(void) {/* 点亮 LED 硬件操作代码 */
}static void led_off(void) {/* 熄灭 LED 硬件操作代码 */
}static int led_open(struct inode *inode, struct file *filp) {/* 打开设备时需要做的事情 */
}static ssize_t led_write(struct file *filp, const char __user *buf,size_t size, loff_t *offt){int flag;/* 获取应用层 write 的数据,存放在 flag 变量 */if (copy_from_user(flag, buf, size))return -EFAULT;/* 判断用户写入的数据,如果是 0 则熄灭 LED,如果是非 0 则点亮 LED */if (flag)led_on();elseled_off();return 0;
}static int led_release(struct inode *inode, struct file *filp) {/* 关闭设备时需要做的事情 */
}
static struct file_operations led_fops {.owner THIS_MODULE,.open led_open,.write led_write,.release led_release,
};static int led_probe(struct platform_device *pdev) {/* 驱动加载时需要做的事情 */
}static int led_remove(struct platform_device *pdev) {/* 驱动卸载时需要做的事情 */
}static const struct of_device_id led_of_match[] {
{ .compatible alientek,led, },{ /* sentinel */ },
};MODULE_DEVICE_TABLE(of, led_of_match);
static struct platform_driver led_driver {.driver {.owner THIS_MODULE,.name led,.of_match_table led_of_match,},.probe led_probe,.remove led_remove,
};
module_platform_driver(led_driver);
MODULE_DESCRIPTION(LED Driver);
MODULE_LICENSE(GPL);
以上并不是一个完整的 LED 驱动代码如果没有接触过 Linux 驱动开发的读者看不懂也没有关系 并无大碍此驱动程序使用了最基本的字符设备驱动框架编写而成非常简单led_fops 对象中提供了 open、 write、release 方法当应用程序调用 open 系统调用打开此 LED 设备时会执行到 led_open 函数当调用 close 系统调用关闭 LED 设备时会执行到 led_release 函数而调用 write 系统调用时会执行到 led_write 函数此驱动程序的设定是当应用层调用 write 写入 0 时熄灭 LEDwrite 写入非 0 时点亮 LED。
驱动程序属于内核的一部分当操作系统启动的时候会加载驱动程序可以看到 LED 驱动程序中仅仅实现了点亮/熄灭 LED 硬件操作相关逻辑代码应用程序可通过 write 这个系统调用 API 函数控制 LED 亮灭接下来我们看看 Linux 系统下的 LED 应用程序示例代码如下所示
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.hint main(int argc, char **argv) {int fd;int data;fd open(/dev/led, O_WRONLY);//打开 LED 设备(假定 LED 的设备文件为/dev/led)if (0 fd)return -1;for ( ; ; ) {data 1;write(fd, data, sizeof(data)); //写 1 点亮 LEDsleep(1); //延时 1 秒data 0;write(fd, data, sizeof(data)); //写 0 熄灭 LEDsleep(1); //延时 1 秒}close(fd);return 0;
}
此应用程序也非常简单仅只需实现用户逻辑代码即可循环点亮、熄灭 LED并不需要实现硬件操作相关示例代码中调用了 open、write、close 这三个系统调用 API 接口open 和 close 分别用于打开/关闭LED 设备write 写入数据传给 LED 驱动传入 0 熄灭 LED传入非 0 点亮 LED。
LED 应用程序与 LED 驱动程序是分隔、分离的它们单独编译它们并不是整合在一起的应用程序运行在操作系统之上有操作系统支持应用程序处于用户态而驱动程序处于内核态与纯粹的裸机程序存在着质的区别。Linux 应用开发与驱动开发是两个不同的方向将来在工作当中也会负责不同的任务、解决不同的问题。