P1 嵌入式开发之什么是Linux应用开发

目录

前言

01 .Linux应用与裸机编程、驱动编程之间的区别

1.1裸机编程:

1.2 驱动编程

1.3应用编程


前言

                             

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3: ​​​​​​《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🌺本篇简介  :  嵌入式Linux应用开发和裸机,驱动开发的区别

 从本章开始,我们要开始写一些关于Linux应用编程的东西了,为后面的嵌入式开发打下基础

讲嵌入式软件开发的时候,我们绕不开三个名词,不管是校园招聘,还是我在BOSS,还是当地招聘会,我总会看到三种岗位

  1. 嵌入式单片机开发工程师
  2. 嵌入式Linux应用开发工程师
  3. 嵌入式驱动工程师

本系列的话主要写关于我学习嵌入式Linux应用开发的过程及心得

然后我们来谈一谈其中的异和同吧

01 .Linux应用与裸机编程、驱动编程之间的区别


1.1裸机编程:

  1. 单片机程序是裸机程序,没有操作系统的概念
  2. 单片机程序是硬件驱动+业务逻辑的集合,
  3. 程序是整体编译一般把没有操作系统支持的编程环境称为裸机编程环境

裸机编程的硬件我用过的就是STC89C52与STM32103了

这个和Linux应用编程给我最直接的区别就是可以直接在KEIL直接编写代码和编译代码,甚至是烧录,而且裸机操作更多的操作都是操作寄存器和配置寄存器

编辑器和写Linux应用还是很大区别,我也试过用别的编辑器写裸机程序,比如微软的VS CODE,后面发现好麻烦

需要将寄存器的库配置好,还要自己写点汇编配置C语言的运行环境,之后才能用C语言写 ,

编译文件还要编写Makefile

1.2 驱动编程

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

驱动开发的话我了解的还比较少, 只知道Linux 中的三大类驱动:字符设备驱动、块设备驱动和网络设备驱动,还有就是设备树了


1.3应用编程

⭐我们可以看这个图,应用层其实属于最外层的,在我们说裸机开发的时候说过,直接操作寄存器

但是到了Linux应用开发,那就不一样了,我们可以看到属于应用层的我们根本接触不到硬件,也接触不到内核,


🌺那离应用层最近的是哪个层面呢?

可以看到是shell指令和库函数以及系统调用了
所以所我们想要操作硬件,做应用开发的其实不是直接配置寄存器了

🌹那怎么写代码以及沟通硬件呢?

🛸看个小案例

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

 所以应用开发要的操作是使用系统调用/库函数/shell指令操作硬件,编写逻辑代码,以及利用其他根据,进行上层的开发

  1. 应用程序运行在用户空间
  2. 应用程序完成的是业务逻辑
  3. 应用程序可单独编译

 应用程序可以单独编译,指的是项目可以单独编译执行,可以同时跑很多的应用程序

 

比如我这里可以单独编译,然后网络发送给开发板,开发板能接收文件,还能同时干别的事情

//主函数
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的文件目录

欢迎大家的点赞关注

如果有写的不好的,可以提醒我修改,谢谢

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用IAR Embedded Workbench for 8051编写的CC2530传感器读取代码的示例: ```c #include <stdio.h> #include "ioCC2530.h" // 定义传感器接口引脚 #define SDA_PIN P1_3 #define SCL_PIN P1_2 // 定义传感器地址 #define SENSOR_ADDRESS 0x27 // 初始化I2C总线 void I2C_Init(void) { // 配置SDA和SCL引脚 SDA_PIN = 1; SCL_PIN = 1; P1SEL &= ~(BIT2 | BIT3); P1SEL2 &= ~(BIT2 | BIT3); // 配置I2C I2C0CFG = 0x00; I2C0CN = 0x00; I2C0ADR = 0x00; I2C0CKL = 0x0A; I2C0CKH = 0x0A; I2C0CN |= 0x80; } // 向传感器写入数据 void I2C_Write(uint8_t address, uint8_t data) { // 等待I2C总线空闲 while (I2C0CN & 0x01); // 开始发送数据 I2C0CN |= 0x20; I2C0DAT = address << 1; while (!(I2C0CN & 0x02)); // 发送数据 I2C0DAT = data; while (!(I2C0CN & 0x02)); // 停止发送数据 I2C0CN |= 0x40; } // 从传感器读取数据 uint8_t I2C_Read(uint8_t address) { uint8_t data; // 等待I2C总线空闲 while (I2C0CN & 0x01); // 开始发送数据 I2C0CN |= 0x20; I2C0DAT = address << 1; while (!(I2C0CN & 0x02)); // 读取数据 I2C0CN |= 0x20; I2C0DAT = (address << 1) | 0x01; while (!(I2C0CN & 0x02)); data = I2C0DAT; // 停止发送数据 I2C0CN |= 0x40; return data; } void main(void) { uint8_t data; // 初始化I2C总线 I2C_Init(); // 向传感器写入数据 I2C_Write(SENSOR_ADDRESS, 0x01); // 从传感器读取数据 data = I2C_Read(SENSOR_ADDRESS); // 输出读取的数据 printf("Data read from sensor: %d\n", data); while (1); } ``` 这段代码使用了CC2530微控制器的I2C接口来读取一个地址为0x27的传感器的数据。在使用时需要根据具体的传感器型号和接口进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@ChenPi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值