嵌入式软件工程师
文章平均质量分 58
嵌入式软件工程师
这个作者很懒,什么都没留下…
展开
-
树莓派的刷机以及相关配置的设置,多种方式登录树莓派
树莓派相关的配置,以及多种方式登录树莓派原创 2022-06-08 17:18:00 · 573 阅读 · 0 评论 -
Linux系统编程项目之ftp云盘
一、首先介绍一下这个项目要实现的功能在客户端对服务端的操作:1.获取服务器的文件(get)2.查看服务器的所有文件(ls)3.进入服务器的某个文件夹(cd)4.上传文件到服务器(put)5.查看服务器当前在那个文件夹(pwd)6.退出 (quit)在客户端本地的功能实现:1.查看客户端本地有哪些文件(lls)2.进入客户端的某个文件夹(lcd)3.查看客户端当前在那个文件夹下(lpwd)4.退出连接(quit)二、介绍一下项目开发的思路服务端:(1)先建立socket通道(2原创 2022-05-31 15:21:29 · 408 阅读 · 0 评论 -
Linux系统编程之线程(多线程编程初探)
在讲线程之前,我们先来看看线程与进程之间的关系:进程与线程:典型的UNIX/linux进程可以看成是只有一个控制线程,一个进程在同一时刻只做一件事情,有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程各自处理独立的任务。进程是程序执行时的一个实例,是担当分配系统资源(CPU时间、内存等)的基本单位。在面向线程设计的系统中,进程本身不是基本运行单位,而是线程的容器。程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行实例。线程是操作系统能够进原创 2022-05-19 17:07:01 · 379 阅读 · 0 评论 -
Linux系统编程之进程间的通信(信号量)
前言:信号量的相关概念:信号量:主要用于同步与互斥。为了防止出现因多个进程访问临界资源而引发的一系列问题,信号量可以提供这样一种访问机制,在任一时刻只能有一个执行线程访问代码的临界区域,也就是说信号量是用来协调进程对临界资源的访问。信号量的操作:信号量是一种特殊的变量,对信号量的访问必须是原子操作,信号量的操作只有两种:P操作(-1,申请资源)和V操作(+1,释放资源)。最简单的信号量只有两种取值0和1,称这样的信号量为二元信号量。可以取值为正整数N的信号量称为多元信号量,它允许多个线程并发的访问资源原创 2022-05-16 21:01:47 · 593 阅读 · 0 评论 -
Linux系统编程之进程间通信(信号)
信号(signal):信号的基本概念:信号是事件发生时对进程的通知机制,有时也叫软件中断,信号可以让一个正运行进程被另一个运行进程异步进程中断,转而处理某突发事件。注意:信号的产生和处理都是由内核完成简单说一下使内核为进程产生信号的事件有:1 终端发特殊字符,如CTRL+C 对前台进程发送中断信号2 硬件发生异常,如被0除等异常机器语言指令。3 系统状态变化:如alarm定时器到期引起SIGALRM信号,进程某个子进程退出4 运行kill 命令/函数。信号使用的目的:...原创 2022-05-16 16:44:41 · 261 阅读 · 0 评论 -
Linux系统编程之进程间通信(共享内存)
前言:首先说一下共享内存实现进程间通信的基本原理,共享内存实际是操作系统在实际物理内存中开辟的一段内存。共享内存实现进程间通信,是操作系统在实际物理内存开辟一块空间,一个进程在自己的页表中,将该空间和进程地址空间上的共享区的一块地址空间形成映射关系。另外一进程在页表上,将同一块物理空间和该进程地址空间上的共享区的一块地址空间形成映射关系。看上图,一个进程往该共享内存空间写入内容时,另一个进程也可以访问到这个共享内存空间,读取到一个进程写入的内容,相反也可,这就实现了两个进程间的通信。要实现进程间通信需原创 2022-05-12 21:57:08 · 377 阅读 · 0 评论 -
Linux系统编程之进程间的通信(消息队列)
一、消息队列(1) 消息队列是进程间通信的一种方式,遵循先进先出的原则,保证了时间的顺序性。拥有该消 息队列读权限的进程可以从消息队列读出数据,拥有该消息队列写权限的进程可以向消息队列发送数据。(2)消息作为节点一个一个地存放在消息队列里,可把消息队列比作信箱,消息比作依次顺序存放的信件。地址比作消息类型,内容为消息。支持双向传输,可以使用消息类型区分不同的消息。,其实消息队列说白了就是用来存放消息的链表。(3)消息队列不再局限于父子进程,在任何两个进程间都能通信。重要提示:消息队列是linu原创 2022-05-12 16:25:02 · 1276 阅读 · 0 评论 -
Linux系统编程之进程间的通信方式(无名管道与命名管道)
进程间的五种通信方式(IPC):1、管道(无名管道),速度慢,容量有限,只有父子进程能通讯;2、FIFO(命名管道),任何进程间都能通讯,但速度慢;3、消息队列,容量受到系统限制;4、信号量,不能传递复杂消息,只能用来同步;5、共享内存区。一、管道:管道:通常指无名管道,是UNIX系统中IPC最古老的形式。1.特点:它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。它可以看成是一种特殊的文件,对于它的读写也原创 2022-05-10 15:14:27 · 292 阅读 · 0 评论 -
Linux系统编程之进程中的system函数与popen函数
1.system函数system的返回值如下:成功的话,返回进程的状态值;当sh不能执行时,返回127,失败则返回-1详细请参考精彩博文:system函数精彩讲解system函数例子:#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(){ printf("this is system!\n"); if(system("ps") == -原创 2022-04-28 15:42:10 · 205 阅读 · 0 评论 -
Linux系统编程之进程中的exec族函数
exec族函数的作用我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。详细参考精彩博文:exec族函数精彩博文直接上例子:echoarg.c#include <stdio.h>int main(int argc,char *argv[]){ int i = 0; for(i = 0; i <原创 2022-04-28 15:17:07 · 270 阅读 · 0 评论 -
Linux系统编程之进程退出,父进程等待子进程退出
1.首先讲一下进程的退出进程的退出分为正常退出和异常退出:正常退出:(1)main函数调用return(2)进程调用exit(),标准C库(3)进程调用_exit()或_Exit(),属于系统调用(4)进程最后一个线程返回(5)最后一个线程调用pthread_exit异常退出:(1)调用abort(2)当进程收到某些信号时,例如Ctrl+c(3)最后一个线程对取消(cancellation)请求做出响应以上三张图片是对进程退出的补充,在第二第三张图中的exit(),_exit原创 2022-04-28 14:05:07 · 2296 阅读 · 0 评论 -
linux系统编程之进程创建实战,fork与vfork创建进程的区别
1.首先我们先来了解一下fork创建进程:(1)使用fork函数创建一个进程,pid_t fork(void),fork函数调用成功的话,返回两次返回值为0, 代表当前进程是子进程。返回值为非负数,代表当前进程是父进程。 调用失败的话,返回-1。重要提示:调用fork函数时,父进程的返回值就是子进程的进程ID,而子进程的返回值是0;(2)fork函数创建一个子进程的一般目的(3)fork编程实战(4)直接上代码#include <stdio.h>#in原创 2022-04-27 20:35:03 · 358 阅读 · 0 评论 -
Linux系统编程之进程概念的相关问题
linux进程原创 2022-04-23 15:54:26 · 803 阅读 · 0 评论 -
Linux系统编程之API(fputc、fget和feof)
1.函数fputc;函数原型: int fputc(int c, FILE *stream);返回值:如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。c -- 这是要被写入的字符。该字符以其对应的 int 值进行传递。stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符的流。注意:该函数是一个字符一个字符的写进的,并不是一串一串的写,还有其实这个函数跟write是一样的,就是将字符写进文件的意思。上代码:#inc原创 2022-04-21 21:06:54 · 311 阅读 · 2 评论 -
Linux系统编程之文件的标准C库里的fopen,fread,fwrite,fseek等,并用标准C库的函数实现将整数结构体和结构体数组写进文件里
经过之前那么多节的学习,对文件的打开,关闭等操作有了很大的理解,那么今天我们来聊一下标准C库里的打开关闭等函数。1.首先来看一下标准c库里的fopen函数函数原型: FILE *fopen(const char *path, const char *mode);fopen返回的是FILE类型的字符流。path:要打开的文件名(含路径,缺省为当前路径);mode:打开的方式,例如“w+”就是以可读可写的方式打开,若文件不存在并创建,若存在则将原来的内容清空, (还有很多想“w+”的这原创 2022-04-21 20:25:14 · 490 阅读 · 0 评论 -
Linux文件之strstr函数、将一个整数,结构体和结构体数组写进文件里
linux原创 2022-04-20 22:00:50 · 392 阅读 · 0 评论 -
Linux系统编程之文件的标准输入与标准输出,且实现linux下的复制指令cp
linux系统编程原创 2022-04-20 21:33:33 · 975 阅读 · 0 评论 -
Linux系统编程之常用的几个API之read、lseek、creat
上一篇博文说到了open和write函数,这一篇继续来说一下剩下的几个API,分别是read、lseek和creat。1.read函数原型是: ssize_t read(int fd, void *buf, size_t count);read函数的返回值是读取到的字节数(即count),fd为文件描述符,count是读取到的字节数,buf是字节缓冲区。read函数的含义是:从fd所指向的文件中读取count个字节的内容存到字节缓冲区buf去。重要提示:在使用read函数时,一定要注意文原创 2022-04-18 22:17:53 · 509 阅读 · 0 评论 -
Linux系统编程之文件常用的几个API之open、write
前言:从这个博文开始我们开始学习Linux相关的编程,探索Linux奥秘1.第一个API函数是open函数open有两种表现形式 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);open函数返回的是一个对应的文件描述符pathname:要打开的文件名(含路径,缺省为当前路径)flags:以什么的方式打开,O_RDONLY(只读打开),O_WRON原创 2022-04-18 21:09:58 · 665 阅读 · 1 评论 -
C语言之动态创建链表的两种方式
之前我们说的链表是基于静态创建的,但静态创建的链表很不灵活而且在工作中的项目中的很多场景都不适合,所以我们来记录一下链表的两种动态创建的方式。1.方式一:链表动态创建之头插法那么我们直接上代码讲:struct Test* insertLinkfrontHead(struct Test *head,struct Test *new){//动态创建链表之头插法 if(head == NULL) { head = new; } else { new->next = h原创 2022-04-14 15:45:20 · 2702 阅读 · 0 评论 -
C语言之删除链表指定的结点与修改链表指定结点
这一节讲链表增删改查中的改跟删1.删除链表中元素例子:1->2->3->4->5删除也分两种情况,一种是否是删除头结点,二是正常删除链表的结点。(1)删除头结点(切记,链表无论是插入还是修改还是删除,一旦动了头结点一定要返回一个新的头结点);struct Test* point = head; if(point->data == data) { head = head->next; free(point);//其实这里要有个free的,但是这是静原创 2022-04-14 14:52:34 · 5933 阅读 · 0 评论 -
C语言链表之在指定结点前面或后面插入新的结点
1.我们知道链表无非就是增删改查这几个操作。而在指定结点前方或后方插入结点就是增加的一种体现。(1)在指定结点后方插入新结点例子:1->2->3->4->5当要在3和4之间插入新结点的时候(即在3的后方插入新结点)步骤:1.先找到3(point->data == data)2.将3->next(即4的地址)赋给new->next,将新结点new与结点4建立了联系即:new->next = 3->next;3.完成上面两步骤后,再执行3-&g原创 2022-04-14 14:29:04 · 4318 阅读 · 0 评论 -
C语言之链表初认识
1.其实链表就是多个相同的结构体连在一起的而已,用数组来类比一下即可,数组的所有数据的地址连续的,而链表却不是,而链表不同结点的地址是可以连续的也可以是不连续的,数组想减少或添加一个数据很艰难,而链表恰恰相反,链表是一个很灵活的东西。链表无非就是四样东西:增删改查2.现在我们来进行一个链表的静态创建其实静态创建是很麻烦的,但对于学习有很好的理解帮助struct Test{ int data; struct Test* next; //定义一个指针指向自己};静态创建与打印 str原创 2022-04-13 22:03:08 · 105 阅读 · 0 评论 -
C语言面试宝典之计算结构体的大小
面试宝典之结构体大小计算原创 2022-04-12 14:06:23 · 825 阅读 · 0 评论 -
继续接着上一节,用结构体二级指针来修改投票系统并对二级指针有一定的了解
1.我们都知道,指针就是保存地址的变量,所以所谓二级指针就是用来保存一级指针本身的地址的指针,其实多级指针也都一个样,只要进行类比一下就行了。所以在这里我想说一下接着上一节的如果传参的是指针的话,什么情况需要返回指针,什么时候不需要。上一节已经讲的很清楚了,局部指针就需要返回。现在来看一个对结构体指针进行初始化的函数封装,这个就是返回跟不返回都是一样的。我们这里是用二级指针进行传参,但类比一下其实是跟一级指针是一样的,最底层的还是对一级指针进行操作。首先看一个返回指针的struct Candida原创 2022-04-10 18:37:28 · 91 阅读 · 0 评论 -
继上一节,用结构体指针来改写投票系统,并进行函数的封装
1.开始时我想说一下,我们学习指针时,我们知道任何变量都是有地址的,而在进行函数的封装的时候,单独是将main函数的里的变量进行传参是没用的,在函数里是修改不了main函数里对应变量的地址的内容的,只有将我们main函数里的变量的地址传上去才能修改到我们main函数对应变量的地址。但是仅仅将变量本身传上去也不是不可以改变main函数里的变量的值,只要返回一个相同类型的变量到main函数里的对应变量进行承接即可指针也一样(无论是结构体指针还是其他类型的指针都是一样的),但不同的是指针本身就是地址,返回一个原创 2022-04-09 18:06:07 · 353 阅读 · 0 评论 -
C语言之结构体的学习笔记
1.结构体就是不同类型的一组数的集合,切记结构体不像联合体那样所有数据是不共用同一个内存地址的。结构体的简单定义:struct Student{ int scores; //成绩分数 char name[128];//此处定义一个字符数组来保存学生的姓名 int number; //学号 }; //切记这里的分号千万别忘记写2.函数指针在结构体内的定义与调用//此处函数指针的原型是void datas(int a){ printf("a = %d!\n",a);原创 2022-04-09 17:06:18 · 854 阅读 · 0 评论 -
C语言typedef关键字的用法
1.typedef关键字的用法typedef为C语言里的一个关键字,其用法是(1)是为一种数据类型包括内部数据类型(int char等)和自定义的数据类型(struct 等)(2)和struct等匹配为了代码缩写简洁(3)//在单片机开发, 寄存器8位,16位,32位举例说明:(1)typedef int zhnegxing;typedef char zifu;typedef double fudian;这里的意思是用zhengxing代表int,zifu代表char,fudian代表原创 2022-04-08 22:22:02 · 1006 阅读 · 0 评论 -
学习笔记之C语言的断言函数assert,复制函数strcpy,strncpy,拼接函数strcat,比较函数strcmp
1.断言函数assert(笔试时可能会考到)assert的头文件是<assert.h>assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。其实assert的用法有点像if语句,例如 assert(str != NULL && des != NULL);//当满足括号中的条件时才执行下面的程序只有当括号里的条件为真是才进行下面代码的执行,如果为假(即0),则输原创 2022-04-05 14:28:50 · 1038 阅读 · 0 评论 -
C语言之字符串的输入输出方式与及动态开辟函数malloc、扩容函数realloc,初始化函数memset的初认识
1.首先记录一下字符串的输入输出方式有哪些字符串得输入有两种方式,分别是:char pstr[128];scanf("%s",pstr);//第一种方式gets(pstr);//第二种输入字符串的方式字符串的输出也有两种方式printf("%s\n",pstr);//第一种方式puts(pstr);//第二种方式2.接下来记录常用的动态空间开辟函数malloc,扩容函数realloc,初始化函数memset这里由于是记录我学习的笔记,我就不记录的那么官方,就直入例子(1)malloc原创 2022-04-04 13:44:00 · 1152 阅读 · 0 评论 -
C语言之sizeof与strlen的区别
我们都知道sizeof计算的是数组的所有的大小,而strlen计算的是字符串的有效的大小,不能用sizeof来计算字符串的有效长度,切记sizeof是C语言里的一个关键字而不是函数,用strlen来计算字符串的大小的时候,它会一直往字符串下去跑,直到遇到‘\0’后结束计算,记得用strlen来算时’\0’是没有算进字符串的大小里的。接下来直接用代码来体现一波;1.首先举个例子先例char data[20] = "hello”;此时用sizeof来计算的话会算出的是20个字节的大小,而用strlen来原创 2022-04-02 22:12:49 · 3676 阅读 · 1 评论 -
C语言之二级(多级)指针认识
1.多级指针认识(包括二级)指针就是地址变量,就是存放地址的变量,一级指针是存放其他变量的地址的变量,而多级指针则是存放指针地址的变量。例如int data;int *p;p = &data;这里的一级指针是保存的是data的地址二级指针则是保存的是指针p本身的地址例如int *p;int **pp;pp = &p;这里的pp保存的是指针p本身的地址;而*pp保存的是一级指针p保存的地址特别注意其实保存一级指针的地址还可以再定义一个一级指针来保存一级指针的地原创 2022-04-01 21:50:22 · 567 阅读 · 0 评论 -
C语言里的函数指针、指针数组和函数指针数组
1.函数指针函数指针也是一个指针变量,但这个指针存放的是一个函数的地址,以前的函数通过函数名来调用,现在也可以通过指针来调用,运用类比法理解,例如以前的**int p是一个整型变量,是一个指向一个整型数的指针定义方式:无参数的:void printwelcome(){}指针方式:void (*p1)();p1 = printwelcome;//把函数的名即地址赋给指针**有参数的:int add(int a,int b){ }指针方式:int (p2)(int a,int b){ }p2原创 2022-03-31 13:26:13 · 1007 阅读 · 0 评论 -
C语言之数组指针与二维数组的应用
1.首先我们先来了解一下,二维数组的定义二维数组是一定要有列的,即arr[0][1]和arr[][2]这两种写法都是合法的,而arr[5][]这样写则是违法的,那么在函数调用二维数组时也一样例:(1)一维数组被函数调用时的传参形式可知在函数进行对一维数组的调用时都是要将地址传上去,我们熟悉的是一维数组的名字或数组第一个元素的地址都可以代表整个数组的地址,那么图上的是传了数组的名字上去当做数组地址。那么接下来我们看二维数组的传参形式是怎么样的(2)二维数组传参.此时的行这个地方可以空着,而列这原创 2022-03-28 22:42:04 · 934 阅读 · 0 评论 -
C语言里指针与数组的见怪不怪的方式
在指针指向 一个数组的时候的见怪不怪指针取内容的时候(1)指针当做数组名,下标法访问(2)数组名当做指针+i进行地址的偏移(1)用p来代替arr(2)数组名当做指针+i进行地址的偏移(3)数组名与指针的区别数组名++不能代替指针名++,即arr++ != p++;原因:数组名相当于一个常量指针,而指针相当于是一个指针变量,数组名的地址是固定的,但指针变量的地址是变的(4)在sizeof()的时候即int是4个字节,char是1个字节,float也是4个字节,double是8个字节,原创 2022-03-27 00:31:22 · 748 阅读 · 0 评论 -
C语言避坑之scanf函数的原样输入
scanf函数避坑原创 2022-03-14 21:45:10 · 1857 阅读 · 0 评论 -
C语言避坑之%m.nf的理解
C语言避坑之%a.bf 的理解原创 2022-03-14 20:58:51 · 3339 阅读 · 0 评论 -
基于Wemos D1的智能感应开盖垃圾桶
这个项目我们主要用到的东西有环保型垃圾桶,Wemos D1模块,舵机,超声波模块,若干条杜邦线等等。新的改变我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:全新的界面设计 ,将会带来全新的写作体验;在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;全新的 KaTeX数学公式 语法;增加了支持原创 2021-01-22 20:43:31 · 761 阅读 · 3 评论