目录
前言
01 .Linux应用与裸机编程、驱动编程之间的区别
1.1裸机编程:
1.2 驱动编程
1.3应用编程
前言
🎬 个人主页:@ChenPi
🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨
🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨
🛸推荐专栏3: 《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🌺本篇简介 : 嵌入式Linux应用开发和裸机,驱动开发的区别
从本章开始,我们要开始写一些关于Linux应用编程的东西了,为后面的嵌入式开发打下基础
讲嵌入式软件开发的时候,我们绕不开三个名词,不管是校园招聘,还是我在BOSS,还是当地招聘会,我总会看到三种岗位
- 嵌入式单片机开发工程师
- 嵌入式Linux应用开发工程师
- 嵌入式驱动工程师
本系列的话主要写关于我学习嵌入式Linux应用开发的过程及心得
然后我们来谈一谈其中的异和同吧
01 .Linux应用与裸机编程、驱动编程之间的区别
1.1裸机编程:
- 单片机程序是裸机程序,没有操作系统的概念
- 单片机程序是硬件驱动+业务逻辑的集合,
- 程序是整体编译一般把没有操作系统支持的编程环境称为裸机编程环境
裸机编程的硬件我用过的就是STC89C52与STM32103了
这个和Linux应用编程给我最直接的区别就是可以直接在KEIL直接编写代码和编译代码,甚至是烧录,而且裸机操作更多的操作都是操作寄存器和配置寄存器
编辑器和写Linux应用还是很大区别,我也试过用别的编辑器写裸机程序,比如微软的VS CODE,后面发现好麻烦
需要将寄存器的库配置好,还要自己写点汇编配置C语言的运行环境,之后才能用C语言写 ,
编译文件还要编写Makefile
1.2 驱动编程
- 驱动程序运行在内核空间
- 驱动程序完成的是底层硬件操作逻辑
- 驱动程序可编译成模块或内置到内核,但都需要依赖于内核源码进行编译
驱动开发的话我了解的还比较少, 只知道Linux 中的三大类驱动:字符设备驱动、块设备驱动和网络设备驱动,还有就是设备树了
1.3应用编程
⭐我们可以看这个图,应用层其实属于最外层的,在我们说裸机开发的时候说过,直接操作寄存器
但是到了Linux应用开发,那就不一样了,我们可以看到属于应用层的我们根本接触不到硬件,也接触不到内核,
🌺那离应用层最近的是哪个层面呢?
可以看到是shell指令和库函数以及系统调用了
所以所我们想要操作硬件,做应用开发的其实不是直接配置寄存器了
🌹那怎么写代码以及沟通硬件呢?
🛸看个小案例
比如要写一个流水灯的程序,驱动编程就是操作寄存器来点灯,而应用程序则是通过系统调用写好的点灯驱动程序来完成业务代码,点亮流水灯
所以应用开发要的操作是使用系统调用/库函数/shell指令操作硬件,编写逻辑代码,以及利用其他根据,进行上层的开发
- 应用程序运行在用户空间
- 应用程序完成的是业务逻辑
- 应用程序可单独编译
应用程序可以单独编译,指的是项目可以单独编译执行,可以同时跑很多的应用程序
比如我这里可以单独编译,然后网络发送给开发板,开发板能接收文件,还能同时干别的事情
//主函数
int main(int argc,char **argv){
struct Devices *tmp=NULL;
pthread_t voiceThread; //语音RXTX线程
pthread_t socketThread; //socke线程
pthread_t fireThread; //火灾线程
pthread_t voice_DianPing;
port = argv[2]; //socket 端口号
ipAdress = argv[1]; //IP地址
printf("%s %s",ipAdress,port);
if(-1 == wiringPiSetup()){ //
printf("链接失败");
return -1;
}
//1.指令工厂初始化
commanderHead = addVoiceControlToIputCommanderLink(commanderHead);
commanderHead = addSocketControlToIputCommanderLink(commanderHead);
//2设备控制工厂初始化
pdevicesHead = addBathroomLightToDeviceLink(pdevicesHead);
pdevicesHead = addupstairLightToDeviceLink(pdevicesHead);
pdevicesHead = addcanteenLightToDeviceLink(pdevicesHead); //将厨房灯的节点加入项目的链表节点中
pdevicesHead = addlivingroomLightToDeviceLink(pdevicesHead);
pdevicesHead = addFireToDeviceLink(pdevicesHead);
LED_Init();
//3线程池建立
//3.1.1语音线程
pthread_create(&voiceThread,NULL,voice_thread,NULL);//调用voice_thread
//3.1.2语音线程电平模式
//pthread_create(&voice_DianPing,NULL,voiceDianPing_thread,NULL);
//3.2socket线程
pthread_create(&socketThread,NULL,socket_thread,NULL);//调用socket_thread
//3.3摄像头线程
//3.4 火灾线程
pthread_create(&fireThread,NULL,fire_thread,NULL);//调用fire_thread
pthread_join(voiceThread,NULL);
pthread_join(socketThread,NULL);
pthread_join(fireThread,NULL);
//pthread_join(voice_DianPing,NULL);
return 0;
}
可以简单的看一下,这一段就是用于香橙派的代码 ,做应用编程的时候不需要配置寄存器
配置寄存器是驱动干的,记住
Linux底下一切皆文件
下一章我们讲解一下Linux的文件目录
欢迎大家的点赞关注
如果有写的不好的,可以提醒我修改,谢谢