猪哥的专栏

私信 关注
猪哥-嵌入式
码龄7年
  • 1,138,094
    被访问量
  • 290
    原创文章
  • 2,941
    作者排名
  • 1,243
    粉丝数量
  • 于 2013-10-07 加入CSDN
获得成就
  • 博客专家认证
  • 获得586次点赞
  • 内容获得133次评论
  • 获得2,010次收藏
荣誉勋章
兴趣领域
  • #大数据
    #数据仓库
TA的专栏
  • Unix/Linux环境编程
    12篇
  • OPC UA
    1篇
  • NUC980
    1篇
  • Linux
    92篇
  • ARM
    37篇
  • 嵌入式
    37篇
  • C/C++
    51篇
  • uC/OS
    8篇
  • 电子技术
    40篇
  • 阿里云IOT
    16篇
  • M-BUS
    2篇
  • Linux-0.11注解
    2篇
  • 杂感
    1篇
  • U-boot
    20篇
  • Makefile
    17篇
  • 自动控制
    3篇
  • MQTT
    8篇
  • 程序人生
    8篇
  • TCP/IP
    9篇
  • 超低功耗-STM32L
    6篇
  • SQLite
    7篇
  • git
    3篇
  • 算法与数据结构
    3篇
  • 最近
  • 文章
  • 资源
  • 问答
  • 课程
  • 帖子
  • 收藏
  • 关注/订阅

MQTT协议详解及开发教程(六)PUBLISH发布QoS0消息报文分析

推荐一款稳定的基于C编写的MQTT Client开源库 cMQTTMQTT协议详解及开发教程(一)MQTT协议概述MQTT协议详解及开发教程(二)MQTT服务器EMQx搭建MQTT协议详解及开发教程(三)MQTT Client工具软件选择及简单测试MQTT协议详解及开发教程(四)MQTT协议报文格式MQTT协议详解及开发教程(五)CONNECT/CONNACK报文分析前言在上一篇文章中,我们对CONNECT和CONNECT的报文进行了分析,本文接着介绍PUBLISH发布QoS0消息报文,该报文
原创
0评论
0点赞
发布博客于 24 天前

MQTT协议详解及开发教程(五)CONNECT/CONNACK报文分析

推荐一款稳定的基于C编写的MQTT Client开源库 cMQTTMQTT协议详解及开发教程(一)MQTT协议概述MQTT协议详解及开发教程(二)MQTT服务器EMQx搭建MQTT协议详解及开发教程(三)MQTT Client工具软件选择及简单测试MQTT协议详解及开发教程(四)MQTT协议报文格式前言在上一篇文章中,我们对MQTT协议的报文格式做了整体的介绍,从本文开始,将通过实例代码,分析MQTT的不同类型的控制报文,我们会使用之前搭建的MQTT服务器和MQTT.fx来进行测试,同时使用Wi
原创
0评论
0点赞
发布博客于 24 天前

MQTT协议详解及开发教程(四)MQTT协议报文格式

推荐一款稳定的基于C编写的MQTT Client开源库 cMQTTMQTT协议详解及开发教程(一)MQTT协议概述MQTT协议详解及开发教程(二)MQTT服务器EMQx搭建MQTT协议详解及开发教程(三)MQTT Client工具软件选择及简单测试前言在前面的文章中,我们对MQTT的应用场景,MQTT服务器搭建、MQTT client工具测试进行了简单的描述,对MQTT有了初步的了解,从本文开始,将会详细的分析MQTT协议内容。1.MQTT 控制报文结构名称备注Fixed
原创
0评论
0点赞
发布博客于 24 天前

MQTT协议详解及开发教程(三)MQTT Client工具软件选择及简单测试

推荐一款稳定的基于C编写的MQTT Client开源库《cMQTT》MQTT协议详解及开发教程(一)MQTT协议概述MQTT协议详解及开发教程(二)MQTT服务器EMQx搭建在上一篇文章中,我们使用EMQx搭建了一个MQTT服务器,有了服务器,自然就需要MQTT Client,在协议了解阶段,我们还是选择别人做好的MQTTclient软件更容易理解MQTT的整个过程,我们以目前常用的MQTTclient软件 MQTT.fx为例,这个可以在官网下载,也可以在其他网站下载,下载完成...
原创
0评论
2点赞
发布博客于 25 天前

MQTT协议详解及开发教程(二)MQTT服务器EMQx搭建

MQTT协议详解及开发教程(一)MQTT协议概述在上一篇文章中,我们对MQTT协议进行了概述,后面的文章,我们就要基于开发环境,对协议进行详细介绍,我们首先就要进行MQTT服务器搭建。MQTT服务器我们选择目前比较常用的EMQx,之所以选择这个broker,主要是因为它开源,部署也比较简单,EMQx的下载安装步骤可以参考EMQx官网资料:...
原创
0评论
0点赞
发布博客于 25 天前

MQTT协议详解及开发教程(一)MQTT协议概述

推荐一款稳定的基于C编写的MQTT Client开源库《cMQTT》一概述 MQTT协议目前在物联网技术中应用非常广泛,各种公有云的IOT平台通信基本上都是按照该协议来实现的,这里先简单的做个总结: (1)MQTT协议框架及内容比较标准,可以认为是“物联网行业的Modbus协议”。 (2)不同厂家的MQTT服务器或客户端在通信层面是完全一致的,只有业务数据不同而已。这也就意味着,如果知道client ID 、password、payload格式,那么任何的 ...
原创
0评论
1点赞
发布博客于 25 天前

阿里云IOT SDK中的MQTT稳定架构分析

1、TCP的read和write都采用select机制进行这里使用select可以实现至少两种功能:(1)select可以检测socket状态,如果select返回为负,说明当前socket异常,就不会再进行read/write 这样就能有效的避免 SIGPIPE带来的终止进程操作。(2)select还可以检测当前socket是否拥堵,这样就变相的实现了同一个socket的“并发”读写。2、由于 MQTT协议标准,所以在进行“读”socket操作时,步骤:...
原创
0评论
0点赞
发布博客于 29 天前

MQTT协议:Retain (保留消息)功能分析小结

场景分析 某个mqtt客户端A每小时向某个特定的topic发布一条消息,所有订阅这个topic的客户端将会收到该消息,这是正常流程,如果客户端A刚刚发布消息,此时有一个新的客户端B订阅该topic,也就是“订阅”是在“发布”后,这个时候客户端B将接收不到该消息。 Retain 功能就是为了解决这一问题,当客户端A发布小时时,将 retain标志置1,那么broker就会保存该消息,当有新的客户端订阅该topic时,会立刻将该条消息推送给客户端B。 所以官方的协议中是这样介绍
原创
0评论
0点赞
发布博客于 1 月前

systemctl 启动/关闭/启用/禁用服务 总结

启动服务systemctl start vsftpd.service关闭服务systemctl stop vsftpd.service重启服务systemctl restart test.service显示服务的状态systemctl status test.service在开机时启用服务systemctl enable test.service在开机时禁用服务systemctl disable test.service查看服务是否开机启动sys
原创
0评论
1点赞
发布博客于 1 月前

Posix 消息队列 实例分析

一、概述在linux应用开发中,消息队列的应用场景很普遍,比如最常见得生产 --消费模型,一方产生数据,并把数据放入队列中,而另一方从队列中取数据。linux中的消息队列的主要用途为进程间通信,当然,也可以进行 “线程间通信”。 我们可以简单的理解为: (1)创建了一个消息队列,相当于在内核层面,创建了一个链表,这也就意味着这个消息队列,在不主动删除的情况下,会一直存在,即便是创建它的进程退出后,该消息队列仍然存在。消息队列在内存中可能的布局如下: (2)消息队列...
原创
0评论
0点赞
发布博客于 1 月前

__sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=]报警解决

在使用sprintf时,编译时会检测格式化输出的缓存大小,如果缓存过小,则会出现该警告,比如代码如下就会出现这样的警告void func(int cnt){ char buf[10]; sprintf(buf, "%d", cnt); // ....}解决办法:只需要将buf的大小改大即可,如下:char buf[32];...
原创
0评论
0点赞
发布博客于 1 月前

OPC UA技术通俗理解、案例体验

1、OPC UA是什么? 是一种工业自动化标准,OPC全称OLEfor Process Control(用于过程控制的OLE(对象连接与嵌入,可以理解为接口,linux下的pipe))。 UA全称是“Unifiedarchitecture”,即统一架构。2、OPC的目的是什么? 其目的是把PLC特定的协议(如Modbus,Profibus等)抽象成为标准化的接口,作为“中间人”的角色把其通用的“读写”要求转换成具体的设备协议,反之亦然,以便HMI/SCADA系...
原创
1评论
0点赞
发布博客于 2 月前

Linux:主线程退出对子线程的影响

有一种说法:“主线程退出,子线程也会跟着退出”,其实这是不严谨的, 在linux下其实是没有所谓的“主线程”和“子线程”区分的,都是线程,只不过main函数比较特殊,如果main函数执行到最后 return 0退出,这里的return 其实会默认调用函数exit,然后退出该进程,因为进程运行完毕,退出导致所有创建的线程也跟着退出了。如果我们在子线程中,调用 pthread_cancel(main_tid) 提前终止main,那么子线程是不会退出的。...
原创
0评论
0点赞
发布博客于 2 月前

gettimeofday() 和 clock_gettime()函数 分析小结

在上一篇文章《struct timeval 和 struct timespec 应用小结》我们分析了与linux系统时间相关的结构体定义,在linux系统C编程中,获取系统时间的api函数有两个,分别为:int gettimeofday(struct timeval *tv, struct timezone *tz)int clock_gettime(clockid_t, struct timespec *)我们逐个分析:1、gettimeofday() 该函数把当前时...
原创
0评论
0点赞
发布博客于 3 月前

struct timeval 和 struct timespec 应用小结

在基于linux的C编程中,经常会看到 struct timeval和struct timespec 这两个跟时间有关的结构体,有时候会容易混淆,先看下这两个结构体的定义,以linux-2.6.35为例,在time.h下struct timeval { __kernel_time_t tv_sec; /* seconds */ __kernel_suseconds_t tv_usec; /* microseconds */};struct timespec { __kernel
原创
0评论
0点赞
发布博客于 3 月前

undefined reference to symbol ‘pow@@GLIBC_2.2.5 编译错误解决方法

解决方案:gcc编译时增加 -lm选项,这样程序就能引用libm.so(libmath)库了。 该错误的含义并不是glibc库的错误,而是pow符号未定义, pow是数学中的求幂函数,也就是说,如果我们在C文件中引用了math.h ,那么在使用gcc编译时,必须添加 -lm选项,因为书序函数是位于libm.so库文件中的,-lm选项告诉编译器书序函数要到这个库文件中查找。...
原创
0评论
0点赞
发布博客于 3 月前

libxx.so is not an ELF file 解决方法

嵌入式Linux下进行共享库移植时,在PC上交叉编译生成共享库后,需要将共享库和软连接拷贝到设备/lib下,正常情况下是可以使用的,但是在程序调用动态库的时候,出现了题目中的错误,如下图所示:问题分析:linux下的拷贝不完全,或者说对于 共享库的 软连接 不能拷贝完全。解决办法:先将原来的软连接删除,然后使用 ln -s 命令手动创建软连接。其中 -s 是可选参数,创建 符号链接。实例:给libmodbus.so.5.1.0 创建 软连接 libmodbus.so.5ln ...
原创
0评论
0点赞
发布博客于 4 月前

libev交叉编译移植到ARM

交叉编译过程与之前的文章《libmodbus协议栈1——Linux下详细移植步骤(配置、生成)》中的流程是类似的。下面简单的做记录1、下载libev源码git clone https://github.com/enki/libev.git2、安装automake,autoconf,libtoolsudo apt-get insatll automake autoconf libtool3、这里不用执行./autogen.sh了,因为下载的源码中已经拥有了configure执行文件。4、创建
原创
0评论
0点赞
发布博客于 4 月前

MCP4728分析及示例驱动程序(C)

目录前言技术要点1、引脚功能2、配置位:3、DAC数值对应计算关系5、写指令类型MCP4728驱动1、快速写2、同时写2路3、一次写多路DAC 4、单次写入DAC 使用注意前言 MCP4728是一款4通道输出DAC芯片,分辨率为12bit,通信接口为I2C,而且内部自带EEPROM,EEPROM功能使得DAC器件在断点后仍然能够保持DAC输入寄存器值,这样就尤为方便了,因为是第一次使用,关于这个芯片的稳定性,还需要进一步测试。技术要点...
原创
0评论
1点赞
发布博客于 5 月前

STM32L151C8T6和STM32L151C8T6A的区别

我们在使用STM32L151这款超低功耗芯片的时候,容易混淆尾缀“A”,这里的“A”可以理解为 advance,也就是说,STM32L151C8T6A是STM32L151C8T6的高级版,哪高级了呢? 主要是RAM的大小,来看下官方手册里的资源表:首先是订货号中的分析:“C”代表48Pin, 8代表64K的flash,T代表LQFP的封装,6代表工业级温度(-40~85℃),所以我们能确定的是,STM32L151C8T6和STM32L151C8T6A的Flash都是一样的64K。...
原创
0评论
0点赞
发布博客于 6 月前

NUC980 IOT 实验板快速测试详细流程及注意

本文简单的做下关键点笔记,NUC980 IOT的官方提供的实验板烧录方式可以参考官方提供的文档,这里就不赘述了,参考NUC980 IOT实验板做了一款精简版的 实验板,外围资源 包括:1、CPU(NUC980DK61Y)2、SPI Nand Flash(W25N01GVZE1G)3、USB 调试串口。4、USB Host5、SD卡。5、以太网口(Eth0)6、UART1/2/3/4.配置选择编译内核流程1、安装交叉编译器 arm-linux-gcc...
原创
0评论
0点赞
发布博客于 7 月前

sprintf、snprintf、vsprintf、vsnprintf格式化函数分析

格式化输入、可变参数表格式化输入。
原创
0评论
0点赞
发布博客于 8 月前

fcntl函数的作用及应用场景

在unp书中,关于函数fcntl的参数讲解的比较多,但是这个函数功能只有简单的一句话“fcntl函数可以改变已经打开文件的属性”。我们知道,在Unix/linux环境下,不管是设备、I/O、socket等等,几乎一切都是文件,所以fcntl的功能就是对于这些设备、文件、I/O的属性进行设定,比如常用的功能:1、复制一个已有的描述符,类似于dup函数功能。2、获取/设置文件描述符标志。3、获取/设置文件状态标志。4、获取/设置一步I/O所有权。5、获取/设置记录锁。fcntl的功能很强大,也很全
原创
0评论
0点赞
发布博客于 8 月前

linux下 O_NONBLOCK与O_NDELAY的区别

在上一篇文章《linux下“阻塞”与“非阻塞”的定义及区别》中,我们分析了阻塞和非阻塞两种模式,与“非阻塞模式”相关的有两个 标志,就是 O_NONBLOCK与O_NDELAY,这两种参数的结果都是使I/O操作设置为“非阻塞模式”,也就是non-blocking,当进行read/write操作时,不管结果如何,都会马上返回,而不会阻塞。他们的区别是:在read时,如果读不到数据,O_NDELAY会返回0,由于正常读取到文件末尾时,也会返回0,这样就无法区分是否是遗产隔离,所以就引入了O_NONBLOCK,
原创
0评论
0点赞
发布博客于 8 月前

linux下“阻塞”与“非阻塞”的定义及区别

前言在unix/linux下,不管是设备、文档、可执行程序,对于内核来说,都是文件,都会涉及到open、read、write的操作,对于文件操作就有了“阻塞”和“非阻塞”的概念了,我们以串口设备来举例分析这两种概念,首先保证,我们已经打开并初始化一个串口。“阻塞”的定义对于 read,当串口的接收缓冲区没有数据的时候,read函数会阻塞在那里,不返回,程序也无法下一步执行,一直到串口的接收缓冲区中有数据可读时,read读到了想要长度的字节数后才会返回,返回值为读到的字节数。对于write,当串口发送
原创
0评论
0点赞
发布博客于 8 月前

dup函数分析及应用场景

dup应用场景分析Unix系统中支持不同的进程共享的打开文件,dup函数可以复制一个现有的文件描述符,这里的“复制”不是说dup返回完全一样的文件描述符,那是没有意义的。而是返回一个当前可用文件描述符中的最小数值,通过这一新的文件描述符也可以访问该文件。“共享”的分析上面提到了“共享”,对于刚接触文件描述符的人来说,可能会有些疑问,为什么要“共享”,将文件描述符作为一个“全局变量”访问不是很方便吗?有这种想法的,往往是因为我们大多数情况下的应用范围都是仅限于1个进程,即便1个进程下有多个线程,对于单进
原创
0评论
0点赞
发布博客于 8 月前

strerror和perror函数的用法及区别

strerror原型#inlcude <string.h>char *strerror(int errnum);strrerror 函数将errnum映射为一个出错消息字符串,并返回该字符串指针,这里的“字符串”是Unix中已经定义好的常量字符串。perror原型#inlcude <stdio.h>void perror(char *msg);perro函数是基于当前的errno值,在标准错误(控制台)上输出一条出错消息,它首先输出由msg指向的字符串,然后跟一个冒
原创
0评论
0点赞
发布博客于 8 月前

变频器等设备在工业控制系统中的“干扰”分析3:变频器是怎样干扰PLC或其他控制器的

本系列文章参考了西瓜视频-杨继深老师的《深讲电磁兼容》相关视频内容,这里向杨老师致敬。 在前面的文章中:《90%的电磁干扰问题是共模电流导致》《变频器的共模电流》 我们分析了共模电流的概念,也了解到了共模电流是产生干扰的主要源头,那么本文就简单分析,变频器的共模电流是如何干扰PLC或其他控制器的。通过前面文章的分析,我们应该能知道答案,一般情况下,变频器是通过地线来干扰PLC或其他控制器的。 变频器会在地线上产生共模电压,也就是“地线噪声”,驱动产生“地线”产生地线电流...
原创
0评论
0点赞
发布博客于 8 月前

变频器等设备在工业控制系统中的“干扰”分析2:变频器的共模电流

本系列文章参考了西瓜视频-杨继深老师的《深讲电磁兼容》相关视频内容,这里向杨老师致敬。在上一篇文章《90%的电磁干扰问题是共模电流导致》中提到了共模电流的概念,本文进一步说明变频器的共模电流。变频器的控制回路,如下图所示: 很明显,我们需要的是差模电流,共模电流是干扰信号,共模电流通过杂散电容,在“地线”上会产生地线电压,也会产生电磁辐射,会干扰周边其他的电子设备。 共模电压的产生,主要是因为跟变频器里的频繁脉冲有关。小结:1、变频器的共模电流就是电机定子...
原创
0评论
0点赞
发布博客于 8 月前

变频器等设备在工业控制系统中的“干扰”分析1:90%的电磁干扰问题是共模电流导致

本系列文章参考了西瓜视频-杨继深老师的《深讲电磁兼容》相关视频内容,这里向杨老师致敬。 工业控制系统中,变频器是比较常见的容易产生电磁干扰的设备,不管使用的是PLC,还是小型嵌入式硬件设备,都有可能被变频器干扰。我的专业方向是嵌入式硬件产品开发,所以干扰问题经常遇到,有时候也是没有很好的办法去解决,一般要么是加外置的隔离器,要么就是在软硬件上做一些辅助性的措施,但是对于其中的干扰原理,比较肤浅,这个主要是因为“干扰”本身是一种看不见摸不着的东西,有些人戏称为“玄学”。 查阅相关的资...
原创
0评论
1点赞
发布博客于 8 月前

数组的优点就是链表的缺点,链表的优点就是数组的缺点

本文的标题是无意中看到的一句话,是(qq_37839971)对某篇文章的回复,这句话可能不太严谨,但是概括性很强,概括了数组和链表数据结构的部分优缺点,数组是一种顺序存储线性表,最大的优点是可以快速的存取表中任一位置元素,而缺点就是表长度不够灵活,而且想要插入、删除操作时,需要移动大量的元素。链表数据结构可以说是一种有强关联的数据结构,表长度灵活,可以随时增加删除,插入或删除操作也不需要移动太多...
原创
0评论
0点赞
发布博客于 8 月前

使用C 实现的 开源消息队列 cQueue

</>概述队列是一种非常好用的数据结构,消息队列可以提高业务逻辑的成功率,在Unix/Linux下,消息队列还是进程之间通信的一种技术方案,关于队列数据结构的知识点,可以参考之前的文章:深入理解数据结构(一):队列队列的功能虽然很好用,但是如何编写一个文件的消息队列功能,还是有些难度的,本文参考uC/OS 操作系统的队列代码原理,编写了消息队列 功能,使用者可以将cQueue....
原创
0评论
0点赞
发布博客于 8 月前

调用free 后内存状态

malloc和free是常用的动态内存申请和释放函数,功能就不赘述了,尤其在调用 free 后,我们脑海中想到的就是释放之前申请的内存区域,那么我们再细究一下,调用free(p) 后,指针p值和 p指向的内存状态是什么样呢?说下答案吧:1、调用free(p) 后,p值不变。2、调用free(p) 后,p指向的内存的值不确定,有可能变,也有可能不变。这里就说明了一个容易忽略的结果...
原创
0评论
1点赞
发布博客于 8 月前

epoll 分析、应用场景及与select对比

在Unix/linux 中有 I/O 操作,I/O操作针对的是 文件,而linux下,“文件”概念是比较庞大的,不管是 普通文件还是硬件设备,还是socket连接、管道等等,都是文件,文件 最常用的3中操作就是 “读”、“写”、“异常”,我们经常使用的就是“读”操作,比如读取串口接收数据,读取socket 接收数据等等,文件的“读” 一般分2种,“阻塞”和“非阻塞”,对于这两种概念,我们举...
原创
0评论
0点赞
发布博客于 9 月前

buildroot的作用简单分析

buildroot 是linux平台下的一种构建嵌入式Linux系统的框架,这个工具在刚开始接触的时候,觉得有点懵? 这玩意儿能够构建系统内核、u-boot、根文件系统?太夸张了吧,后来经过使用发现,这个工具还真 可以,只不过实现的方式比较意外。Buildroot是由Makefile脚本和Kconfig配置文件构成的,对于构建内核、u-boot,它是 需要 写好脚本,从芯片厂家提供的下载链...
原创
0评论
2点赞
发布博客于 10 月前

理解CPU的 推挽、开漏输出以及应用场景

0- 概述在嵌入式CPU中,GPIO口都是可以设置成多种模式的,比如STM32的芯片 GPIO端口可以由软件配置成多种模式: 对于 输入模式和复用功能模式,都是比较容易理解的,但是 输出 推免输出和开漏输出,理解起来确实有些难度, 如果不理解这两种模式,那么对于这两种模式的应用场景,也是难以很好的理解的,接下来,我们就以STM32的 GPIO口的 结构为例,从电路的角...
原创
2评论
6点赞
发布博客于 1 年前
STM32中GPIO的8种工作模式
发布Blink于 1 年前
推挽输出和开漏输出区别
发布Blink于 1 年前

阿里云IOT C-SDK 源码分析系列(8): IOT_Linkkit_Report 分析

从函数名称上就可以知道,这个函数的主要功能是向云端发送消息,但是它的功能不仅仅如此,特别需要注意的就是,他还包含子设备登录/子设备退出功能。函数 原型如下:IOT_Linkkit_Report 原型int IOT_Linkkit_Report(int devid, iotx_linkkit_msg_type_t msg...
原创
0评论
0点赞
发布博客于 1 年前

阿里云IOT C-SDK 源码分析系列(7): IOT_Linkkit_Close 源码分析

该函数的功能是 关闭网络连接,并且释放Linkkit 的所有的占用资源。原型如下:IOT_Linkkit_Close原型int IOT_Linkkit_Close(int devid);接口说明若设备ID为主设备, 则关闭网络连接并释放Linkkit所有占用资源参数说明参数 数据类型 方向 说明devid int 输入 设备ID返回值说明值 说...
原创
0评论
0点赞
发布博客于 1 年前

阿里云IOT C-SDK 源码分析系列(6):IOT_Linkkit_Yield 用户 事件调度函数源码分析

在上一篇文章中,着重分析了 SDK的 核心调度线程yield,本文再简单的分析下用户 事件调度 API 接口函数,该函数 原型如下:IOT_Linkkit_Yield原型void IOT_Linkkit_Yield(int timeout_ms);接口说明若SDK占有独立线程, 该函数只将接收到的网络报文分发到用户的回调函数中, 否则表示将CPU交给SDK让其接收网络报文并将消息...
原创
0评论
1点赞
发布博客于 1 年前

阿里云IOT C-SDK 源码分析系列(5):重点理解SDK的核心调度线程 _iotx_cm_yield_thread_func

本文是 本系列的 最重要的 一篇,因为本文尝试着去揭示SDK本身的 工作内容,为什么要理解 SDK 的工作内容呢?因为SDK提供给开发者的是API接口函数,我们只是会简单的使用 这些API接口, 但是这些API接口的相关资料只有寥寥几句话, 相关的技术文档也非常少,作者的出发点可能是开发者快速的进行应用开发,不需要了解SDK本身的任何 实现机制,但是个人觉得,如果完全不了解 SDK的...
原创
0评论
0点赞
发布博客于 1 年前

阿里云IOT C-SDK 源码分析系列(4):IOT_MQTT_Construct 源码分析

IOT_MQTT_Construct 函数没有开放给 用户使用,它不是一个 API接口,但是对于移植者而言,尤其是关注 底层原理的,这个函数还是非常重要的,不管我们是采用 SDK自带的编译系统进行移植,还是采用“ 代码抽取”的方式进行移植,编写wrapper.c 中的HAL_xxx函数都是必不可少的, 尤其是TCP 连接、断开、读、写的HAL 接口函数,这些 都是具体的硬件层面的 接...
原创
0评论
0点赞
发布博客于 1 年前

阿里云IOT C-SDK 源码分析系列(3):IOT_Linkkit_Connect 接口源码分析

从字面意思也能看出 该函数是 设备 向 云服务器 发起连接的功能函数,但是“连接”功能知识它的主要功能,它还实现了一些其他的参数初始化,比如特别重要的 底层 HAL 接口函数的绑定。该函数 原型如下:IOT_Linkkit_Connect原型int IOT_Linkkit_Connect(int devid);接口说明对于主设备来说, 将会建立设备与云端的通信. 对于子设备...
原创
0评论
1点赞
发布博客于 1 年前

阿里云IOT C-SDK 源码分析系列(2):IOT_Linkkit_Open 接口源码分析

该函数是使用 IOT的SDK的 需要调用的 第一个 接口函数,该函数原型如下:IOT_Linkkit_Open原型int IOT_Linkkit_Open(iotx_linkkit_dev_type_t dev_type, iotx_linkkit_dev_meta_info_t *meta_info);接口说明初始化设备资源, 在对设备进行操作之前, 必须先调用此接口. 该接口...
原创
0评论
0点赞
发布博客于 1 年前

阿里云IOT C-SDK 源码分析系列(1):应用框架概述

在前面的文章:《阿里云IOT-C-SDK系列(1)概述:移植流程、程序框架、代码目录》《阿里云IOT-C-SDK系列(2)快速体验:移植+示例C代码》《阿里云IOT-C-SDK系列(2)快速体验:移植+示例C代码》《阿里云IOT-C-SDK系列(4)SDK配置选项理解》《阿里云IOT-C-SDK系列(5):进一步理解SDK的移植使用方式》 我们是从 移植、应用的角...
原创
0评论
2点赞
发布博客于 1 年前

freemodbus 从机 原理分析小结

在之前的文章《Freemodbus原理分析》,结合代码对 freemodbus 进行了分析,这里对 freemodbus机制做一下分析小结。freemodbus 的应用场景 主要是在 非linux下的 单片机系统,当然了,freemodbus 1.6 版本也开始支持了 linux,不过在linux下,如果不是一定要移植源码的话,个人觉得 libmodbus 相比 freemodus 还是...
原创
1评论
2点赞
发布博客于 1 年前

libmodbus源码分析(3)从机(服务端)功能源码分析

在上一篇文章《libmodbus源码分析(2)主机(客户端)功能源码分析》 从 主机的角度 分析了 源码,本文以 从机(服务器)的角度分析一下源码。同样的,我们以 modbus rtu 协议的 4x区保持寄存器功能进行举例说明。 我们简单的写一下 modbus rtu 下 响应客户端(主机)读4x 区保持寄存器的伪代码流程:int main(void){ modbu...
原创
0评论
2点赞
发布博客于 1 年前

libmodbus源码分析(2)主机(客户端)功能源码分析

在上一篇文章《libmodbus 源码分析(1)基本框架、关键数据结构、接口》中,分析了libmodbus的源码基本框架和关键的数据结构、接口,本文就分析一下 libmodbus 作为 主机(客户端)的功能源码实现,这里我们以 modbus rtu 协议 的读 4x 区保持寄存器功能 进行举例说明,我们简单的写一下 modbus rtu 下读 4x 区保持寄存器的 伪代码 流程:in...
原创
0评论
3点赞
发布博客于 1 年前

libmodbus 源码分析(1)基本框架、关键数据结构、接口

在之前的文章:《 libmodbus协议栈1——Linux下详细移植步骤(配置、生成) 》《 libmodbus协议栈2—— Linux下 modbus RTU master 开发案例 》《 libmodbus协议栈3—— Linux下 modbus RTU 从机 开发案例 》《 libmodbus协议栈4—— 总结 》 我们是从 应用的角度了解到了 libmodbus 的使...
原创
4评论
4点赞
发布博客于 1 年前

单向链表删除并清空操作 注意

在之前的文章《深入理解Linux内核之链表 list.h 功能实现原理、接口说明及示例代码》中详细的分析了链表的各种操作,我们经常使用的操作是“初始化”、“ 添加节点”、“遍历”、“删除”,对于链表节点的删除,使用的相对少,而且由于 删除操作的 宏函数 定义的复杂,容易混淆,本文基于此,对 链表的删除清空做下备忘录。以单向链表结构 为例,用到的宏函数有2个,分别为:/* * I...
原创
0评论
0点赞
发布博客于 2 年前

libev 笔记(三):libev的使用模型

上一篇《libev 笔记(二):事件驱动模型 在 稳定的网络服务器 程序中的应用》我们介绍了 事件驱动模型的作用,以及在网络服务器中应用,本文简单的说一下 libev 的 使用关键点。 libev 是一种高性能事件循环 / 事件驱动库。作为 libevent 的替代作品,由于其支持linux,而且其作者声称其相比libevent速度更快,代码更少,所以我们在嵌入式linux中采用...
原创
1评论
0点赞
发布博客于 2 年前

libev 笔记(二):事件驱动模型 在 稳定的网络服务器 程序中的应用

在前面的文章《libev 笔记(一):“事件驱动模型” 的 理解》 简单的介绍了 事件驱动模型的概念,但是文字概念毕竟理解起来稍微有点抽象,接下来从具体案例来一步步的分析,事件驱动模型 能解决什么问题,也就是怎么用。 本文 参考了顾锋磊 老师的 文章 《使用事件驱动模型实现高效稳定的网络服务器程序》,在此向作者致敬,写的确实不错。 libev 目前 最典型的应用场景可能就...
原创
0评论
0点赞
发布博客于 2 年前

libev 笔记(一):“事件驱动模型” 的 理解

libev 是 一种 “事件驱动”的编程框架,所谓“事件驱动”,简单地说就是就是 有什么动作(点按钮、中断),程序就执行什么操作(中断服务函数、回调函数),当然事件不仅限于用于的操作,只要是定义好的,各种突发、预设的各种将要发生的事情,都是事件。这里,我对CPU相对熟悉一些,可以把“事件驱动”理解为 自定义软件中断。这里我们举几个案例来分析:案例1: 状态机FSM 状态机是一...
原创
0评论
0点赞
发布博客于 2 年前

ID 值自动 “申请”和“释放” 算法及C代码 (2)

在上一篇文章《ID值自动申请和释放》中,简单的介绍下应用背景和C代码,不过上一篇中的代码 至适用于 “释放”一次,不支持多次释放,也就是说必须要释放1次后,下一次操作必须是重新申请,因为代码中没有 使用 “队列”操作,所以本文为了实现多次释放的功能,进一步改善了代码,引入了队列的思想,关于“队列”的概念,可以参考之前的文章《深入理解数据结构(一):队列 及 C代码框架》。下面就是具体的代码:#...
原创
0评论
0点赞
发布博客于 2 年前

ID 值自动 “申请”和“释放” 小算法及C代码

简单的说下题目中涉及到的 应用场景,在 开发 网关或一些组态软件的时候,我们一般是需要创建变量或者设备表的,还有就是对于数据库表中的 ID值,我们在对表中记录进行“增”、“删”操作时,也涉及到 ID值的 管理,这个具体体现为:(1)当我们新创建一个变量或一条记录时,希望ID值为最新的,而且是唯一的、递增的。(2)如果只有“增”操作,没有“减”操作,那就比较简单了,对id值进行 id...
原创
0评论
0点赞
发布博客于 2 年前

C语言 带参数宏定义中 # 和 ## 知识点总结、代码分析

目录一、宏定义中 “#”知识点1、直接转换字符串,不展开。2、转换出的结果一定是“字符串”。二、宏定义中 ## 知识点1、应用场景2、“##”的作用是将 左右两边的参数做整体字符串拼接替换3、经过 ## 替换后的内容必须 有一个 同名的 变量与之对应。4、 只拼接,不展开。5、## 操作 动态函数指针 案例代码一、宏定义中 “#”知识点 #的...
原创
0评论
0点赞
发布博客于 2 年前

C语言 枚举enum 知识点总结

目录1、枚举中的值是整型。2、枚举中的成员就是一个全局“宏”。3、如果第1个枚举成员未赋值,第一个枚举成员默认值为整型的0。4、没有指定值的枚举元素,其值为前一元素加1.5、枚举元素的值可以自定义,也可以不定义。 枚举类型在C编程中经常用到,尤其是状态枚举、使得程序的可读性更强,“枚举”正如字面意思,将变量可能 出现的值都列举出来,限定变量的值范围,比如:...
原创
0评论
1点赞
发布博客于 2 年前

Unix/Linux 互斥量、条件变量的作用及C代码案例分析

在分析“条件变量”这个概念之前,我们需要了解两个相关的概念,分别是:线程同步、互斥量。1、线程同步 所谓线程同步,“同步”二字单从字面意思来看,是很容易有歧义的,起码不太容易理解是什么意思,“同步”不是同时,而是 只两个或两个以上随时间变化的量在变化过程中保持一定的相对关系(也特别拗口)。这里我用白话解释就是:排队,按顺序来。线程的同步就是说具有一定关系的两个或两个以上的线程...
原创
0评论
0点赞
发布博客于 2 年前

Unix编程艺术:模块式编码的6个问题思考

在前面的文章《Unix编程艺术:哲学基础》中,提到的模块原则是复杂软件的一个利器,也是Unix编程艺术的核心之一,模块性体现在良好的代码中,这首先来自于良好的设计,在编写代码时,需要考虑下面这些问题,这些问题有助于提高代码的模块性。1、有 多少全局变量?全局变量对模块化是 毒药,很容易使各模块轻率、混乱地互相泄露信息,全局变量 同时也意味着代码不能重入,也就是说同一个进程的多个实例可能彼...
原创
0评论
0点赞
发布博客于 2 年前

Unix编程艺术:哲学基础

目录阐述一:阐述二阐述三:1、模块原则。2、清晰原则。3、组合原则.4、分离原则:策略同机制分离,接口同引擎分离。5、简洁原则:设计要简洁,复杂度能低则低。6、吝啬原则:除非确无 它法,不要编写庞大的程序。7、透明性原则:设计要可见,以便 审查和调试。8、健壮原则:健壮源于透明与简洁。9、表示原则。10、通俗原则:接口设计 避免标新立异...
原创
0评论
1点赞
发布博客于 2 年前

cJSON库使用:特别注意事项

cJSON的简单使用——STM32移植cJSON打包功能使用-代码案例、特别注意事项 在前面的文章中,我们对cJSON进行了一些简单分析,包括解析、打包这两种最常用功能,cJSON的移植相对简单,但是在使用的时候,还是有一些特别需要注意的地方的,这 主要是因为 cJSON库 中的一些函数会进行内存申请操作,但是并不会自动释放内存,这就相当于 是风险, 需要使用者自己去及时的释放 内存。...
原创
0评论
1点赞
发布博客于 2 年前

sqlite3在嵌入式Linux上的移植步骤详解

深入理解SQLite3之sqlite3_exec及回调函数sqlite3:深入理解sqlite3_stmt 机制sqlite3: sqlite3_step 函数sqlite3:sqlite3_bind 函数sqlite3:sqlite3_column 函数sqlite3:嵌入式linux下使用总结 在前面的文章中,对sqlite3进行了一些零碎知识点分析, 本文分析一...
原创
0评论
0点赞
发布博客于 2 年前

cJSON打包功能使用-代码案例、特别注意事项

在前面的文章《cJSON的简单使用——STM32移植》中,分析了cJSON的简单使用和移植步骤,这个使用 案例主要 是针对 json包解析的,其实cJSON也提供 json 包 打包 功能,这里针对常用的“对象”类型json进行打包,我们主要使用到以下几个接口函数:1、cJSON *cJSON_CreateObject(void) 该函数用于 创建1个 objec...
原创
0评论
1点赞
发布博客于 2 年前

I2C总线:通信线缆长度的影响及改进措施

本文主要从应用的层面来分析I2C的通信线缆长度的影响及改进措施,不涉及理论分析。I2C总线是嵌入式硬件中一种常用的 通信总线,比如一些时钟芯片,传感器芯片、eeprom等等都是I2C接口,这里我们先说一些共识: I2C总线确实不适合远距离通信,尤其是需要使用线缆与I2C接口器件进行通信,这里的“不适合”并不是说不可以,这也是本文的重点。一般使用I2C总线,都是在用一个开发板上,或...
原创
0评论
2点赞
发布博客于 2 年前

命令行参数小结

说来惭愧,对于命令行参数这个概念接触的比较少,可能也是之前一直使用IDE进行开发程序的原因吧,对于C程序,总是从main函数开始执行,main函数的原型如下:int main(int argc, char *argv[]);这里面我们可以发现main函数的特点:(1)有两个形参,argc和 argv。(2)返回值为 int,有符号整型,我们常常在main函数的最后,添加 ...
原创
0评论
0点赞
发布博客于 2 年前

阿里云IOT-C-SDK系列(5):进一步理解SDK的移植使用方式

阿里云IOT-C-SDK系列(1)概述:移植流程、程序框架、代码目录阿里云IOT-C-SDK系列(2)快速体验:移植+示例C代码阿里云IOT-C-SDK系列(3)快速体验:不使用SDK自带编译系统进行移植示例及Makefile的编写示范阿里云IOT-C-SDK系列(4)SDK配置选项理解 在系列(1)中简单的描述了SDK的两种移植方式:(1)基于SDK自带的编译系统,通过修改HAL层的函...
原创
0评论
2点赞
发布博客于 2 年前

阿里云IOT-C-SDK系列(4)SDK配置选项理解

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入阿里云IOT...
原创
0评论
0点赞
发布博客于 2 年前

阿里云IOT-C-SDK系列(3)快速体验:不使用SDK自带编译系统进行移植示例及Makefile的编写示范

阿里云IOT-C-SDK系列(1)概述:移植流程、程序框架、代码目录阿里云IOT-C-SDK系列(2)快速体验:移植+示例C代码 在系列(2)中详细的罗列了如何使用SDK自带的编译系统进行移植,正如前面所述,使用SDK自带的编译系统看起来简单,但是由于SDK对很多的细节进行了封装,所以对于我们深入的理解SDK反倒是不好的,所以阿里的技术支持更加推荐用户能够使用“代码抽取”功能,将抽取...
原创
0评论
1点赞
发布博客于 2 年前

深入理解Linux内核之链表 list.h 功能实现原理、接口说明及示例代码

目录一、双向链表接口函数及相关宏定义分析0、list_head 结构体1、offsetof(TYPE, MEMBER) 宏2、ontainer_of(ptr, type, member) 宏3、LIST_HEAD_INIT 宏4、LIST_HEAD 宏5、INIT_LIST_HEAD 函数6、LIST_HEAD 和INIT_LIST_HEAD 的区别7、lis...
原创
1评论
5点赞
发布博客于 2 年前

阿里云IOT-C-SDK系列(2)快速体验:移植+示例C代码

《阿里云IOT-C-SDK系列(1)概述:移植流程、程序框架、代码目录》在上一篇文章我们分析了C-SDK的移植流程一级程序框架, 为了快速的体验一下这个移植流程,本文按照上篇文章提供2 种移植方式分别举例如何移植。官方的快速 移植案例为:Quick_start, 我对移植案例进行整理和修改,为了快速的体验,我们使用ubuntu来运行示例程序,原因是SDK中已经提供了HAL_XXX接口函数的实...
原创
0评论
2点赞
发布博客于 2 年前

阿里云IOT-C-SDK系列(1)概述:移植流程、程序框架、代码目录

前言 阿里云推出的 物联网 平台是 专为 设备上云的平台,其物联网平台目前做的还是比较好的,尤其是高级版的 物模型 + IOT studio使得设备数据不仅能够在云端上线,而且可以方便的做web+app显示,基本上相当于web版本+app版的组态软件。基于阿里云的市场份额和功能特点,可以预计,未来其物联网平台应该会应用广泛。对于开发者而言,对重要的就是要使设备连接到物联网平台上...
原创
0评论
0点赞
发布博客于 2 年前

Linux下 静态库(*.a)和动态库(*.so) 的区别及应用分析

目录1、静态库和动态库的区别2、“库”的概念3、静态库和动态库的创建命令 4、静态库和动态库的使用方式1、静态库和动态库的区别(1)所谓静态库(*.a),就是程序link的时候就把静态库中的东西取出来,放到生成的可执行文件中,当这个可执行文件执行时,就不需要再次调用这个静态库了。 (2)所谓动态库(*.so),就是程序link的时候,只是将库中的 符号包...
原创
0评论
1点赞
发布博客于 2 年前

超低功耗研发-STM32L151C8T6芯片(五)低功耗设计总结

超低功耗研发-STM32L151C8T6芯片(一)时钟系统概述超低功耗研发-STM32L151C8T6芯片(二)低功耗模式超低功耗研发-STM32L151C8T6芯片(三)RTC自动唤醒机制超低功耗研发-STM32L151C8T6芯片(四)串口接收唤醒机制、注意事项、C代码目录一、硬件设计1、DC-DC电源部分2、CPU供电3、开关控制电路4、外围芯片供电...
原创
1评论
10点赞
发布博客于 2 年前

超低功耗研发-STM32L151C8T6芯片(四)串口接收唤醒机制、注意事项、C代码

超低功耗研发-STM32L151C8T6芯片(一)时钟系统概述超低功耗研发-STM32L151C8T6芯片(二)低功耗模式超低功耗研发-STM32L151C8T6芯片(三)RTC自动唤醒机制在前面的文章中,详细分析了STM32L151 的 低功耗的各种概念和相关知识,在应用中,还有一种常见的需求,就是CPU被外部唤醒。 RTC唤醒是用于正常的业务需求,而外部唤醒也是需要的,比如说我们需...
原创
0评论
3点赞
发布博客于 2 年前

深入理解数据结构(一):队列 及 C代码框架

“队列”型数据结构是一种非常经典的数据结构,理解这个数据结构,能够更深入的理解一些功能机制,比如消息队列等。队列的思想对于程序逻辑中的应用,还是非常普遍和重要的,最常见的应用就是消息队列,下面就来分析一下队列数据结构的各种概念。一、“队列”数据结构能做什么? 队列数据结构,正如字面意思所述,能够对一堆数据,按照先后顺序来管理,本质上是对内存区域的管理,举例来讲,消息队列,假设...
原创
0评论
1点赞
发布博客于 2 年前

Linux下 线程之间数据 共享性 分析

先说下结论:同一个进程下,各个线程之间的数据是共享的,数据的种类可以有很多种,比如标准数据、结构体、文件描述符等等,但是这里有个前提,这些能够被共享的数据,一定是主线程在创建 子线程时,向 子线程传递的数据(通过指针传递)。程序案例如下:#include "xxx.h" //各种必要头文件void *cthread(void *arg){ int *p = (in...
原创
0评论
0点赞
发布博客于 2 年前

冒泡排序、快速排序算法理解及C程序实现

前言:关于 快速排序算法的相关理解,本文借鉴了 啊哈磊 老师的《常用排序——快速排序》 ,在此向作者 致敬,写的挺好。目录一、冒泡排序二、快速排序三、小结一、冒泡排序 冒泡排序是各种教材中 经常提到的一种排序 方法,基本思想就是: ① 从数组的头部开始,比较相邻两个数,如果第1个数比第2个数大,就交换他们两个。也就是让较大 的数逐渐往后 移动,直...
原创
1评论
9点赞
发布博客于 2 年前

指针的使用注意事项:空指针、指针赋值、void *指针

前面的文章,分析了指针的一些概念,可以说指针是C的灵魂,看起来简单,但是想要理解透彻却是相当难,需要大量的练习,不断的巩固,不断的重复才能尽可能的理解指针,这里做一个简单的阶段总结。1、指针是地址,而不是具体的标量值,这是指针的精髓,不管是一级指针、二级 指针、 整型指针、浮点数指针、结构体指针等等等等所有类型的指针,内容都是个地址,而指针本身当然也是有地址的,而且容易忽略的是,不管这...
原创
0评论
2点赞
发布博客于 2 年前

二级指针的作为函数形参的深入理解

在上一篇文章《C函数的“传值调用”和“传址调用”的深入分析》我们分析了函数参数的使用,对于一级指针,理解起来相对容易,而二级指针参数的理解相对难一些,我们先说一下二级指针作为函数形参的目的。 二级指针作为形参,往往是为了获取一个特定“地址”,没错,就是想要通过形参获取地址。这里可能会有些疑问,如果想要获取地址,那么直接将函数 返回值设定为指针型就可以啊,这 当然是可以的,但是还有一...
原创
0评论
0点赞
发布博客于 2 年前

C函数的“传值调用”和“传址调用”的深入分析

目录传值调用传址调用指针参数的妙用 C中函数一般都有形参,当然也有形参为void的函数,对于那些有形参的函数,我们在调用的时候,就涉及到参数的传递,我们常见的参数有2种,一种是标准变量参数,比如int、char、结构体等单独变量,另一种就是指针,指针可以是一级指针,也可以是多级指针。传值调用 对于上面说的第1种,函数的参数是标量参数,我们在调用函数,给函数传递参...
原创
0评论
2点赞
发布博客于 2 年前

cJSON的简单使用——STM32移植

目录背景知识 JSON数据结构cJSON重要接口函数解析案例移植注意 事项背景知识 JSON是一种轻量级的数据交换格式,这里不做详细的分析,简单的理解为,是互联网上的一种数据打包协议,比较方便人阅读和编写,下面是阿里云物联网设备影子信息的json格式,如下所示:{ "state": { "reported": { "hz": ...
原创
1评论
4点赞
发布博客于 2 年前

C的指针的理解

简单看完《C和指针》这本书后,感慨颇多,最大的感觉就是为什么没有早点看这本书,我们在学校里学的教材,太基础了,等到工作后,尤其是看到程序员大牛和一些优秀开源项目时,总会很纳闷儿?他们的代码为什么能这么写,为什么显得好高级啊,直到看完C和指针这本书,才发现,原来答案都在这里面,真是有种,“课堂学的不考,课下学的才考”的感受。 指针是C语言的灵魂,起码我是这么认为的,为什么这么说呢?...
原创
0评论
0点赞
发布博客于 2 年前

CPU执行程序的简单理解

本文引用了《CPU执行程序的原理(简化过程)》、《CPU的运行到函数调用做个了解》部分图片和内容,这里向作者致谢。 这里不去讲过于专业的专业知识,毕竟,CPU上的任意一个知识点,想讲明白,都不容易,我们从使用者的角度去分析,CPU执行程序的过程原理。目录一、背景知识简单介绍1、CPU系统图2、RAM3、ROM4、指令二、程序运行基本流程知识延伸:函...
原创
0评论
3点赞
发布博客于 2 年前

为什么需要内存RAM——内存、程序执行的形象分析

这里就不去讲RAM的各种专业术语了,要是讲,估计一个博士论文也讲不完,这个问题也一直困惑着我,我也只是从使用的角度去联想,方便去理解,毕竟很多程序员都有强迫症,必须要想明白,才愿意去用。 我们打个比方,场景是一个不大不小的饭店,饭店里有个厨房,储藏间,存放了各种蔬菜、肉、调味料等原料。厨房里目前有1名永远只会动嘴不会动手的主厨、的1名书呆子厨师、1名搬运工、1名洗菜师傅、1名切菜师...
原创
0评论
3点赞
发布博客于 2 年前

如何理解C指针及二级指针(1):二级指针的使用方式

在前面的文章《如何理解C指针及二级指针(1)》 介绍了指针的一些重要概念,对于一级指针,相对来讲是比较容易理解的,这里就不再赘述了。我们重点来看一下二级指针的使用方式。 我们知道,不管是几级 指针,本质上也是个普通变量,只不过指向的内容不同而已。二级指针指向的是“一级指针的地址”。这里,参考博友二级指针的详解的里的图片,向作者致谢。使用方法一: 先为二级指针分配空...
原创
2评论
15点赞
发布博客于 2 年前

如何理解C指针及二级指针(1)

本来想叫这篇文章为“深入理解C指针”,后来想想,还是要谦卑一些,毕竟C指针确实博大精深,是C语言的精髓之一。先说一些说一些简单的背景知识。 任何 架构的CPU, 程序的运行都是需要内存的,所谓内存,内存这个概念听起来简单,想要说的特别通透也是挺难的,我们姑且简单的打个比方:内存就相当于一个房子里的无数个抽屉,每个 抽屉都是有一个编号来标识的,每个抽屉一般有8个隔间,也就是能存储8个...
原创
2评论
26点赞
发布博客于 2 年前

sqlite3:嵌入式linux下使用总结

通过前面的讲述,我们可以了解到sqlite3是一个小型的数据库,功能上还是比较强大的,代码量少,运行占内存也比较少,采用C 编写,所以天生适合嵌入式系统中,尤其是嵌入式linux,相当支持,sqlite3可以直接通过shell运行,不过这个也只限于测试使用,在实际的项目编程中,我们还是要使用sqlite3提供的C/C++接口函数,也就是API接口,常用的接口函数如下:1.sqlite3...
原创
0评论
0点赞
发布博客于 2 年前

sqlite3:sqlite3_column 函数

该函数实例用于 查询(query)结果的筛选,返回当前结果的某1列。常用函数为:int sqlite3_column_int(sqlite3_stmt*, int iCol);double sqlite3_column_double(sqlite3_stmt*, int iCol);const unsigned char *sqlite3_column_text(sqlite...
原创
0评论
3点赞
发布博客于 2 年前

sqlite3:sqlite3_bind 函数

该函数组用于绑定变量值到 prepare 语句中,也就是给 sqlite3_stmt变量赋值。前面的文章讲过,我们一定是先通过sqlite3_prepare_v2函数创建并初始化一个 sqlite3_stmt 变量语句,然后使用sqlite3_bind_xxx函数对 这个 sql语句变量进行绑定参数。常用的sqlite3_bind函数:int sqlite3_bind_int(s...
原创
0评论
0点赞
发布博客于 2 年前

sqlite3: sqlite3_step 函数

上一篇文章中,我们通过sqlite3_prepare_v2初始化sqlite3_stmt 数据(预编译)后,就可以通过sqlite3_step函数来执行。返回值:SQLITE_BUSY:当前数据库不能获取数据库锁,也就不能完成相应的操作,如果执行语句是 COMMIT 或者 发生在显式的事务之外, 我们可以重复尝试,而如果不是,则需要回退。SQLITE_DONE:...
原创
0评论
0点赞
发布博客于 2 年前

sqlite3:深入理解sqlite3_stmt 机制

我们在使用sqlite3的过程中,涉及到批量操作时(批量插入、批量读。。。),总会遇到 sqlite3_stmt这个数据类型,按照官方解释说法是这样的:sqlite3_stmt是C接口中“准备语句对象”,该对象是一条SQL语句的实例,而且该语句已经编译成二进制形式,可以直接进行计算。 它并不是我们所熟悉的sql语句,而是一个已经把sql语句解析了的,用sqlite3自己标记记录的内...
原创
0评论
6点赞
发布博客于 2 年前

git(四):github基本概念

通过前面的文章,我们对 git有了基本的概念,如果我们在自己的电脑上使用git,或者在自己的服务器上部署git服务器,那么就都够用了,但是linux的世界,最著名、最可贵的概念就是 开源,当我们想要做一个开源项目时,github这个神奇的网站,提供了git仓库托管业务,如果我们设定为 公开,那么是可以免费使用的,这有一个好处,就是我们在本地的项目可以放到github 上,这样起码当我们自己...
原创
0评论
0点赞
发布博客于 2 年前

git(三):分支策略

通过上一篇文章,我们了解到了“分支”的相关概念,那么在实际的开发中,我们如何对分支进行管理呢? 首先,master分支必须是 最稳定的版本, 也就是用于发布更新新版本的分支,平时干活是不能在master分支上的。我们需要创建一个 新的分支,假设是dev,dev分支是不稳定的,只有确定dev 分支测试稳定后,再把dev分支合并到master分支上,通过master分支发布一个新的稳定版...
原创
0评论
0点赞
发布博客于 2 年前

git(二):分支

前言:可以说 git 的分支是 git 的灵魂之一,之所以git那么好用,不让程序员担心代码找不到,最核心的原因就是"分支"概念,所谓“分支”可以理解为副本,但是git中的副本,不是实际文件的副本,可以简单的认为是 “文件指针的副本”,这也是作者的牛b所在,我们可以任意的创建分支,由于不是纯粹文件的副本,所以不管源文件有多大,我们可以在1秒内,就能创建1个分支,我们在创建的分支下,进...
原创
0评论
0点赞
发布博客于 2 年前

git(一):基础概念

前沿:git是一个软件版本管理软件,对于程序员来讲,软件版本的管理是十分重要的,不知道别人是怎么做软件版本管理的,对于程序员来讲,软件版本的管理是十分重要的,不知道别人是怎么做软件版本管理的,之前使用的一个比较笨的方法是不停的创建副本,通过readme和版本号来区别版本,所以一个项目做下来,程序文件至少要有几十个程序副本,这种方式相对简单粗暴,但是其实对于版本的管理,并不是特别细致,...
原创
0评论
1点赞
发布博客于 2 年前

深入理解SQLite3之sqlite3_exec及回调函数

sqlite3的C/C++接口API主要有3个重要函数,分别为1、sqlite3_open(const char* filename, sqlite3 **ppDb);2、int sqlite3_exec( sqlite3*, /* An open database */ const ch...
原创
7评论
7点赞
发布博客于 2 年前

socket编程——tcp客户端实现框架对比分析

在宝书《Unix网络编程》中,作者针对客户端提出了大概5种编程框架,分别如下:(1)停-等方式。(2)select加阻塞式IO版本。(3)非阻塞IO版本。(4)多进程fork版本。(5)多线程版本。在16.2.2小节中,对比总结了这几种方式,作者推荐的方式是:推荐使用 多进程fork版本。我们来整理,并简单分析一下这几种版本的编程框架。一、停-等(迭代)方式示例代...
原创
0评论
0点赞
发布博客于 2 年前

socket编程——服务器异常对客户端的影响

我们在编写socket客户端程序时,必须要提前考虑 服务器异常 时的应对措施,服务器的动作主要有3种:(1)服务器正常,返回给客户端正常数据,也就是正常的数据业务,那么客户端的套接字变为可读,并且read返回一个大于0的值(即读入数据的字节数)。(2)服务器正常终止,给客户端发送FIN,那么客户端的套接字变为可读,并且read返回0(EOF)。(3)服务器崩溃,包括崩溃...
原创
0评论
0点赞
发布博客于 2 年前

"慢系统调用"和EINTR错误

本文引用了《信号中断 与 慢系统调用》中的内容,感谢许老师的精彩分享。 所谓慢系统调用(slow system call):指的是那些可能永远阻塞的系统调用,永远阻塞的意思是指调用有可能永远无法返回,多数网络支持函数都属于这一类,比如socket编程中的 accept 函数:如果没有客户连接到服务器上,accept就不会返回。EINTR错误:如果进程正在 一个慢系统调用中阻塞,...
原创
0评论
1点赞
发布博客于 2 年前