单片机技术网|技术阅读
登录|注册

您现在的位置是:单片机技术网 > 技术阅读

技术阅读

  • 分享3款开源免费的Markdown编辑器

    2023-09-24

    1 前言今天一早更新了Typora,不在是以前的beta版了,发现Typora 1.0开始收费了。目前公布的政策是$14.99一个授权,每个授权可以激活三台设备。可以使用信用卡和支付宝支付,89元也算良心,毕竟免费用了这么多年了。关于Typora的介绍这里就不说了。目前我还不打算购买,毕竟我手头的设备比较多,三台机器的授权是满足不了我的需求的。主要是此次费用支付后,可能后面还需要支付额外费用,不过作者说了不会使用订阅模式,但是谁知道呢,不过一时半会也不会有主版本更新,毕竟一个beta版都开发了这么多年。当然啦,如果暂时不想购买,还可继续使用beta...

  • 【持续集成实践指南】第1章 DevOps实践简介

    2023-09-24

    1.1 Devops概念DevOps(英文Development和Operations的组合)是开发和运维一体一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。DevOps是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。  DevOps的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作,从而实现持续、快速、可...

  • 分享一款好用的shell软件Oh My Zsh

    2023-09-24

    1 Shell简介我相信大家在用Linux的时候,肯定都使用过shell终端,那么什么是shell终端?Shell 其实就是一个程序,通常都是放在/bin或者/user/bin目录下,当前 Linux 系统可用的 Shell 都记录在/etc/shells文件中。Shell负责外界与Linux内核的交互,接收用户或其他应用程序的命令,然后把这些命令转化成内核能理解的语言,传给内核,运行完成后把结果返回用户或应用程序。Linux/Unix提供了很多种Shell,不同的shell具备不同的功能,shell还决定了脚本中函数的语法,Linux中默认的shell是/bin/bash。想知道你的系统有几种shell,可以通过以下命令查看...

  • 【ARM Cortex-M 开发实战指南(入门篇)】第1章 前言

    2023-09-23

    1.1 ARM简介1.1.1 ARM概述ARM是Advanced RISCMachines的缩写,它是一家微处理器行业的知名企业,该企业设计了大量高性能、廉价、耗能低的RISC(精简指令集)处理器。公司的特点是只设计芯片,而不生产。它将技术授权给世界上许多著名的半导体、软件和OEM厂商,并提供服务。ARM(Advanced RISC Machines)有3种含义:1.一个公司的名称;2.一类微处理器的通称;3.一种技术的名称。ARM微处理器的特点:1.体积小、低功耗、低成本、高性能;2.支持Thumb(16位)/ARM(32位)双指令集,能很好的兼容8位/16位器件;3.大量使用寄存器,指令执行速度更快;4....

  • 【ARM Cortex-M 开发实战指南(入门篇)】第8章 库开发简介

    2023-09-23

    8.1 Cortex-M 库开发概述我想如果稍微搞过嵌入式的,或多或少都学习过51单片机,51单片机比较简单,配置下寄存器就能实现我们想要的功能,也没有的什么库,但是当你学习Cortex-M之后,就会发现基于Cortex-M的各个MCU厂家都提供了不同的固件库,毕竟,32位的处理器寄存器很多,如果开发一个功能就需要配置大量的寄存器,这样开发起来效率就可想而知了,因此通过将寄存器封装,提供相应的API接口,这样开发起来的就非常方便,也便于移植,大大提高项目开发的进度和效率。因此学习Cortex-M一定要知道什么库开发,为何要使用库开发?所谓库就是函数接口(...

  • 【ARM Cortex-M 开发实战指南(基础篇)】第6章 Cortex-M中断详解

    2023-09-23

    6.1中断和异常Cortex 内核具有强大的异常响应系统,它把能够打断当前代码执行流程的事件分为异常(exception)和中断(interrupt),并把它们用一个表管理起来,编号为 0 ~ 15 的称为内核异常,而 16 以上的则称为外部中断(外是相对内核而言),这个表就称为中断向量表。STM32 对这个表重新进行了编排,把编号从–3 至 6 的中断向量定义为系统异常,编号为负的内核异常不能被设置优先级,如复位(Reset)、不可屏蔽中断(NMI)、硬错误(Hardfault)。从编号 7 开始的为外部中断,这些中断的优先级都是可以自行设置的。CM3内核支持256个中断,其中...

  • 代码编程规范-排版风格

    2023-09-23

    微信公众号:大橙子疯嵌入式点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言 这篇重点介绍一下代码编程的排版风格和自动排版工具代码规范化中的排版基本上有七大风格,主要体现在缩进、空行、代码行、空格、成对书写、对齐、注释七方面的书写规范上。规范要求 缩进程序块采用缩进风格编写,缩进可以使程序更有层次感,每次缩进一般为 4 个空格(部分要求为一个制表符Tab;我个人喜欢用空格,因为制表符不同编辑器缩进不同,虽然能设置,但是麻烦)原则是:如果地位相等,则不需要缩进;如果属于某一...

  • 代码编程规范-命名规范

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言 这篇重点介绍一下代码编程的命名规范,主要是业界流行的命名法则和标识符命名规范标识符的命名规则历来是一个敏感话题,典型的命名风格如unix风格、windows风格等,从来无法达成共识。实际上,各种风格都有其优势也有其劣势,而且往往和个人的审美观有关。对标识符定义主要是为了让团队的代码看起来尽可能统一,有利于代码的后续阅读和修改。命名完全体现了程序的可阅读性和可理解性,在一定程度上是不需要写注释也能看懂代码。命名法则介绍 目前,...

  • 不小心踩了指针和内存地址对齐的坑

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量。本质还是一个变量,指针提供了一种对存储位置的动态访问手段,(相对于普通变量而言,普通变量只能访问自己所占的存储位置)内存地址对齐,是计算机在内存中的数据排列、访问数据的方式,包含了基本数据对齐和结构体数据对齐的两种相互独立又相互关联的部分。现代计算机在内存中读写数据是按字节块进行操作,理论上任意...

  • 如何设计实现一个无锁高并发的环形连续内存缓冲队列

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言队列,也称作FIFO,常用数据结构之一,特点是先进先出。队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。设计思想首先从理想的无限缓冲区到实际的使用进行设计思考。理想化的无限缓冲区在理想情况下,写入器(数据生产者)和读取器(数据消费者)在使用过程中,能够访问相同的、连...

  • 代码编程规范-注释风格

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言这篇重点介绍一下代码编程的注释风格和注释文档生成工具注释的原则是有助于对程序的阅读理解以及提供二次开发所需文档,注释的方式有很多,但是业内常用的规范是 Doxygen 代码注释规范。遵循原则为,说明性文件、函数接口必须充分注释说明。全局变量需要说明功能及取值范围,需要自行处理资料函数需要加上使用警告信息。注意:不要使用注释来屏蔽代码。关于函数和局部变量的注释,当代码已经可自注释时,不用添加多余的注释。简介Doxygen 规范简要的...

  • 代码编程规范-扩展(头文件)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言这篇重点介绍一下代码编程规范的扩展要求-头文件规范要求对于C语言来说,头文件的设计体现了大部分的系统设计。不合理的头文件布局是编译时间过长的根因,不合理的头文件实际上反映了不合理的设计。规范要求【规范1】头文件中适合放置接口的声明,不适合放置实现内部使用的函数(相当于类的私有方法)声明不应放在头文件中内部使用的宏、枚举、结构定义不应放入头文件中变量定义不应放在头文件中,应放在.c文件中变量的声明尽量不要放在头文件中,亦...

  • 为啥隐式函数声明会导致系统这样???

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言什么是C语言的隐式函数声明。在C语言中,函数在调用前不一定非要声明被调用的函数。如果没有声明的话,那么编译器会自动按照一种隐式声明的规则,为调用函数的C代码产生汇编代码。如何踩坑的?首先说明的是,在一份优先的源代码中,编译时通常是不会出现关于函数隐式声明的警告。因为有着严格的编程规范,防止出现这种情况请看下面的代码样例,有什么问题吗?#include <stdio.h>int main(void){    int val = sqrt(4);    printf("sqrt...

  • 代码编程规范-扩展(函数)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言这篇重点介绍一下代码编程规范的扩展要求-函数规范要求函数设计的精髓:编写整洁函数,同时把代码有效组织起来。整洁函数要求:代码简单直接、不隐藏设计者的意图、用干净利落的抽象和直截了当的控制语句将函数有机组织起来。代码的有效组织包括:逻辑层组织和物理层组织两个方面。逻辑层,主要是把不同功能的函数通过某种联系组织起来,主要关注模块间的接口,也就是模块的架构。物理层,无论使用什么样的目录或者名字空间等,需要把函数用一种标准...

  • 为何堆和栈的增长方向通常是相反的?

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言数据结构中,堆(heap)与栈(stack)是两个常见的数据结构,它们的存在都是为了优化内存,提高使用效率,各有特点,理解二者的定义、用法与区别,能够利用堆与栈解决很多实际问题。栈:由操作系统(编译器)自动分配释放 ,存放函数的参数值,局部变量的值等堆:一般由程序员分配释放, 若程序员不释放,程序结束时由OS回收内存分配图通过下图了解常用的堆栈内存分配和增长方向:增长方向及原因堆(heap)的增长方向是向上增长,即低地址向高地址增...

  • 代码编程规范-扩展(变量)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言这篇重点介绍一下代码编程规范的扩展要求-变量规范要求规范要求【规范1】一个变量只有一个功能,不能把一个变量用作多种用途一个变量只用来表示一个特定功能,不能把一个变量作多种用途,即同一变量取值不同时,其代表的意义也不同如,value在同一个函数中表示结果又表示次数,在阅读时增加了难度,所以这种做法是错的,正确的做法应该定义两个变量,分别表示不同含义【规范2】结构功能单一,不要设计面面俱到的数据结构相关的一组信息才是构成一个结...

  • 资深工程师 VSCode C/C++ 必备开发插件

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注前言 俗话说“工欲善其事,必先利其器”,下面介绍几个VSCode提高开发效率的插件,资深工程师必备。之前用的是 Source Insight,确实很强大,不过自从用了 VSCode 后基本就不怎么用  Source Insight 了。基础插件 Chinese(Simplified)vscode 编辑器汉化包,安装完成后重启即可。C/C++ Extension PackC/C++扩展包,下载直接安装,它包含了 vscode 编写 C/C++ 工程需要的插件(C/C++、C/C++ Themes、CMake、CMake Tools和Better C++ Syntax等),和以前比不...

  • 代码编程规范-扩展(宏/常量)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言这篇重点介绍一下代码编程规范的扩展要求-宏/常量规范要求要求【规范1】用宏定义表达式时,要使用完备的括号因为宏只是简单的代码替换,不会像函数一样先将参数计算后,再传递。// 错误示例#define RECTANGLE_AREA(a, b) a * b     // RECTANGLE_AREA(1 + 2, 3 + 6) 替换时为 1 + 2 * 3 + 6, 因为符号优先级此时和想要的结果完全不同#define RECTANGLE_AREA(a, b) (a * b)#define RECTANGLE_AREA(a, b) (a) * (b...

  • 单片机固件中加入版本信息的方式(一)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言开发完MCU软件后,通常都会生成hex文件或者bin文件,用来做固件烧录或者升级,如果用来做产品开发,就涉及到固件版本的问题,初学者通常采用固件文件重命名来区分版本。如果需要每次上电开机通过串口或者OLED等显示版本信息,那么这种方式就无法实现下面介绍如何在程序中加入版本信息,以MDK为例介绍。实现方式1.定义一个结构体,里面定义一些软件版本相关的信息typedef struct{    char szVersion[32];    // 软件版本    char szBu...

  • 代码编程规范-扩展(表达式和基本语句)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言这篇重点介绍一下代码编程规范的扩展要求-表达式和基本语句规范要求要求【规范1】赋值语句不要写在if等语句中,或者作为函数的参数使用因为if语句中,会根据条件依次判断,如果前一个条件已经可以判定整个条件,则后续条件语句不会再运行,所以可能导致期望的部分赋值没有得到运行如:if (test == 15 || HandleLogicFun()) {...},此时若test = 15,则函数 HandleLogicFun就不会执行【规范2】用括号明确表达式的操作顺序,避免过分依赖默认优先级使用...

  • 单片机固件中加入版本信息的方式(二)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言上一篇介绍完如何在程序中添加版本信息后,这篇介绍一下如何在 MCU 程序中固定位置添加程序的版本信息等。了解首先了解一下__attribute__机制,它是个编译器指令,告诉编译器声明的特性,或者让编译器进行更多的错误检查和高级优化。GUN C中可以使用__attribute__()给变量、函数和类型设置各种属性,而__attribute__的section选项可以改变段的特性;其中__attribute__((section("section_name")))的作用是将该定义的函数或数据变量放入指定名为”sect...

  • 单片机固件中加入版本信息的方式(三)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言上一篇介绍完如何在程序中的固定位置添加版本信息,而且如何通过映像工具将版本信息和固件文件名关联同步;这篇主要介绍一下通过 Git 工具管理的程序如何在 MCU 程序版本信息中增加 Git commot 提交的 id 。Git 是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。简单来说就是用来管理程序版本的。为什么增加 git 信息通过上一篇我们了解到软件版本信息可以通过映像工具修改 hex 或者 bin 文件,那么在软件版本管...

  • 单片机 MCU 固件打包脚本软件

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言通过前面(一)、(二)和(三)篇了解版本信息的实现,那么这一篇主要介绍单片机 MCU 固件自动打包脚本软件。介绍下面介绍一个自动打包固件的脚本软件,主要实现以下功能:基于 Windows 平台的单片机 MCU 固件脚本打包工具支持 hex 文件的裁剪和 hex 文件的合并(boot)可以为 hex 固件添加版本信息、Git Commit 分支和提交记录等按照版本信息命名hex固件,可生成 bin 文件等以上均可通过 ini 配置文件设置参数对 hex 文件进行操作实现下面列举配置...

  • 代码编程规范-扩展(其他建议)

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言这篇重点介绍一下代码编程规范的扩展要求-其他的建议要求【规范1】变量的类型定义建议统一采用uint8_t、uint16_t、int8_t等定义根据8位、16位和32位等机器的不同,int等类型所占的字节不一样,如果采用int等方式定义,那么在不同位机器移植代码时就会出现很多问题为了提高代码的移植性,一般采用uint8_t、uint16_t、int8_t等定义的方式,它是通过typedef定义的,而不是一种新的数据类型,typedef定义的uint8_t、uint16_t、int8_t等可以更好的兼容各个...

  • 常用的几种 IAP 升级技术方案

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言关于 IAP 技术,做过 bootloader 的想必很熟悉(IAP全称 In Application Programming,即应用编程),和 ISP(全称 In System Programming,即系统编程)不同,ISP 一般都是通过专业的调试器或者下载器对单片机内部的 Flash 存储器进程编程(如JTAG等),而 IAP 技术是从结构上将 Flash 储存器映射分为两个或者多个分区,在一个分区中对其他分区进行编程,这个分区通常称为 bootloader。OTA(全称 Over The Air Technology,即云端下载技术,也叫做“...

  • 嵌入式软件架构设计-消息交互

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言在熟悉任务调度、程序分层和模块化编程关于软件架构、分层和模块设计后,除了函数调用设计中出现的情况外,还会遇到同层模块之前如何进行消息交互,通常是应用层之间。比如一个设备通过架构设计包含人机交互应用层模块(一般会调用按键和显示屏等功能驱动模块)和通信应用层模块(一般调用串口、CAN和网络ESP8266等功能驱动模块),两个同层之间的模块如果需要互传数据,一般都是调用各自头文件提供的接口(模块对外提供的接口尽量不要使用全局变量,...

  • 嵌入式软件架构设计-状态机

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言 功能业务代码写多了,回看代码会发现用if-else if-else用的越来越多,因为有很多场景需要区分,不同场景下的功能不一样,因此需要通过if做判断,场景一旦多了起来起来,用if-else if-else就会越来越多。这里的if-else if-else通常是用来区分不同场景下的功能实现,和上篇提到的表驱动编程还不太一样。为了避免这种情况,本编介绍一种开发方法--状态机编程。为什么需要状态机编程?相信很多人在实现if判断的时候,偶尔会出现不小心漏掉或者写错一些触...

  • 时间片论法-优化方案

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言 通过该篇学习了嵌入式的任务调度(即时间片论法)后,了解到通过以1ms为调度时间单位轮询判断是否需要执行函数任务,那么下面介绍如何基于时间片论法的任务调度模式充分利用MCU的资源,姑且先称这种方式为时间片差分调度法。充分利用MCU的资源指的是在不影响原有的函数调度情况下合理进行分配,避免MCU大部分时间处于空跑状态(即大部分时间没有调度任何的功能函数,只是在不停地判断时间状态,从而造成的资源浪费),同时提高每个任务的调度周期的...

  • 程序设计原则-单一职责原则

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言 软件开发设计中最大的难题就是应对需求的变化,而各种各样的需求变化又是不可预料的,我们要为这种不可预料的变化做好准备,这本身是一件十分痛苦的事情,通常涉及到功能的变更、扩展和删除等,所幸前辈们已经给我们提出了经典的六大设计原则和23种设计模式来“封装”未来的变化。在程序设计领域, SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期引入的记忆术首字母缩略字,指代了面向对象编程和面向...

  • 开发常使用方式之“柔性数组”

    2023-09-23

    点击上方蓝色字体了解更多的嵌入式编程实用技能。如果你觉得该文章对你有帮助,欢迎点赞+关注 前言 在软件开发过程中,常遇到一些不定长的数据处理和数据传输等场景,最开始的做法大多是定义一个结构体,包含数据长度和数据地址,如:struct Frame {    int type;    int length;    char *pBuf;};这种写法对于数据同步处理基本没什么问题,若是数据异步处理时则在使用上会稍微复杂一些。异步处理数据时要考虑变量和内存的生命周期,否则容易出现内存泄漏的问题,因为涉及到内存管理的问题。概念 数组长度为0,也叫柔性数组,其主...