我们通常认为,在中断中,不能执行耗时的操作,否则会影响系统的稳定性,尤其对于嵌入式编程。 对于带操作系统的程序而言,可以通过操作系统的调度,将中断处理分成两个部分,耗时的操作可以放到线程中去执行,但是对于没有操作系统的情况,又应该如何处理呢? 比较常见的,我们可能会定义一些全局变量,作为flag,然后在mainloop中不停的判断这些flag,再在中断中修改这些flag,最后在mainloop中执行具体的逻辑,但是这样,无疑会增加耦合,增加程序维护成本。 cpost cpost正是应用在这种情况下的一个简单但又十分方便的工具,它可以特别方便的进行上下文的切换,减少模块耦合。 cpost链...

OTA概述 大家好,我是一个软件升级包。这几天呢,我将会进行一次神奇的网络之旅,从开发者的电脑中,一直跑到终端嵌入式设备中。 大家都把我的这个旅游过程叫做 OTA,也就是在线升级。 那么啥叫 OTA 呢?全称是:OvertheAirTechnology,其实就是通过网络来把一个新的软件包从服务器上下载下来,更新到设备上。 首先有一个问题:为什么叫软件升级包,而不叫固件升级包呢? 其实在本质上,固件也是属于软件,大家都是用代码写出来的嘛! 虽然这两个说法很近似,但是有一部分小伙伴还是在狭义上对它们进行了一些区分。 既然如此,我们也就暂且把它俩进行一下区别: ...

编码规范,没有最好,只有最合适,有但不执行不如没有。 1编码原则 1.1可读性原则 (1)清晰第一清晰性是易于维护程序必须具备的特征。维护期变更代码的成本远远大于开发期,编写程序应该以人为本,计算机第二。一般情况下,代码的可阅读性高于性能,只有确定性能是瓶颈时,才应该主动优化。 (2)简洁为美简洁就是易于理解并且易于实现。代码越长越难以看懂,也就越容易在修改时引入错误。提倡通过简洁明了的代码来提升代码可靠性。废弃的代码要及时清除,重复代码应该尽可能提炼成函数。 (3)风格一致所有人共同分享同一种风格,为后期维护,和代码交接带来便捷。 1.2设计原则 (1)开放封闭原则对于扩展是开放的,...

“嵌入式驱动和应用,哪个更难?哪个更锻炼自己?”类似的问题经常有网友拿来讨论和交流。 我在嵌入式这行搞开发10年有余了,算不上经验丰富,但站在过来人的角度,只想说:驱动和应用相辅相成,没有谁更难一说,做好了,都难! 现在的嵌入式比20年前的要求更高,软硬件、应用场景也更复杂了,除了驱动层和应用层,中间层也是重要的一层。 当然,在不同场景下分层也有不同的讲究,比如RT-Thread(Smart版本)的软件架构: 暂不说20年前,就是10年前搞嵌入式开发,大部分中小公司对嵌入式开发的岗位要求都不算高,你懂一些基本原理,哪怕没有独立开发过项目,都能找到一个开发(研发)的工作。 而现在呢,你学了R...

在敲代码的时候,我们会给变量一个初始值,以防止因为编译器的原因造成变量初始值的不确定性。 对于数值类型的变量往往初始化为0,但对于其他类型的变量,如字符型、指针型等变量等该如何初始化呢? 数值类变量初始化 整型、浮点型的变量可以在定义的同时进行初始化,一般都初始化为0。 1intinum=0; 2floatfnum=0.00f; 3doublednum=0.00; 字符型变量初始化 字符型变量也可在定义的同时进行初始化,一般初始化为'\0'。 1charch='\0'; 字符串初始化 字符串初始化的方法比较多,我这里简单介绍三种,因为字符串本质上是由一个个字符组成的字符数组,所以其...

大家好,今天分享一篇关于嵌入式C编程中全局变量问题的文章。希望对大家有所启发。 嵌入式特别是单片机os-less的程序,最易范的错误是全局变量满天飞。 这个现象在早期汇编转型过来的程序员以及初学者中常见,这帮家伙几乎把全局变量当作函数形参来用。 在.h文档里面定义许多杂乱的结构体,extern一堆令人头皮发麻的全局变量,然后再这个模块里边赋值123,那个模块里边判断123分支决定做什么。 每当看到这种程序,我总要戚眉变脸而后拍桌怒喝。 没错,就是怒喝。我不否认全局变量的重要性,但我认为要十分谨慎地使用它,滥用全局变量会引申带来其它更为严重的结构性系统问题。 诸位看官,且听我细细道来 1、它...

一、项目概况 CLN17 电机驱动器是一款开源、紧凑、高性能的闭环步进电机驱动器,专为NEMA17外形尺寸电机设计。该驱动器提供先进的功能,如静音和平稳的运动、高精度的位置控制和节能功能,使其成为各种应用的理想选择,包括机器人、CNC机床和3D打印机。 二、板框图 三、项目特点 (1)位置控制和精度 🕹️闭环控制:电机驱动器支持闭环控制,集成编码器进行实时位置监控和调整,确保在具有挑战性的条件下实现精确运动。 📏精细定位:0.01度的卓越位置控制精度确保了位置信息的高效和低延迟处理,并将噪音降至最低,从而实现平稳运行。 🎯极其精确的无传感器泊车:先进的无传感器泊车算法无需...

让我们一步一步地来看这个过程。 步骤1: 用户在浏览器中输入一个URL(比如www.bytebytego.com),然后按下回车键。首先,我们需要将这个URL转换成一个IP地址。通常,这个映射关系会被存储在缓存中,因此浏览器会在多个缓存层中查找IP地址:浏览器缓存、操作系统缓存、本地缓存和ISP(互联网服务提供商)缓存。如果浏览器在缓存中找不到这个映射关系,它会请求DNS(域名系统)解析器来解析这个URL。 步骤2: 如果IP地址在任何缓存中都找不到,浏览器会去DNS服务器执行递归式的DNS查找,直到找到IP地址为止。 步骤3: 现在我们有了服务器的IP地址,浏览器会向服务器发送一个HTT...

Linux中内存管理 内存管理的主要工作就是对物理内存进行组织,然后对物理内存的分配和回收。但是Linux引入了虚拟地址的概念。 虚拟地址的作用 如果用户进程直接操作物理地址会有以下的坏处: 1、用户进程可以直接操作内核对应的内存,破坏内核运行。 2、用户进程也会破坏其他进程的运行 CPU中寄存器中存储的是逻辑地址,需要进行映射才能转化为对应的物理地址,然后获取对应的内存。 通过引入逻辑地址,每个进程都拥有单独的逻辑地址范围。 当进程申请内存的时候,会为其分配逻辑地址和物理地址,并将逻辑地址和物理地址做一个映射。 所以,Linux内存管理涉及到了以下三个部分: 1、物理内存 物理内存的组织 ...

1、前言 嵌入式固件一般分为BootLoader和App,BootLoader用于启动校验、App升级、App版本回滚等功能,BootLoader在cpu上电第一阶段中运行,之后跳转至App地址执行应用程序。 因此,在发布固件的时候,会存在BootLoader固件和App固件;此时我们期望是将BootLoader固件和App固件合并成为一个固件,这样在量产时只需烧录一次即可。 2、传统方式 一些传统的方法都是“土办法”,没什么毛病,但比较繁琐。 项目种类增加,或者版本发布频繁时更加体现出繁琐性,且易出错,操作稍微失误可能导致固件不完整;烧录不完整的固件,机子变“砖头”。 烧录两次,分别烧...

   由于C++解释器比C语言解释器占用的存储空间要大500k左右。为了节省有限的存储空间、降低成本,同时也为了提高效率,将用C++语言写的源程序用C语言改写是很有必要的。 C++与C最大的区别,就是C++中的类的概念和特性,将C++改为C的问题,就转换成如何将类化去的问题。 方法有两种: 第一种是将C++中的面向对象特征去掉,先全部理解源代码的逻辑,然后改写;第二种是在C中保留面向对象的部分特征,用结构体实现类的功能。 第一种方法,对于类的数目很少的情况还可以,如果类的数目比较多,全部理解源代码,然后重写就很耗时间,而且很容易出错,更甚者,如果遇到大的项目想全...

01 前言 这里和大家简单分享一下我的看法。题主应该想要讨论的是嵌入式软件,下面说一下个人观点; 嵌入式的硬件属性; 嵌入式的岗位需求; 嵌入式的学习曲线; 嵌入式的薪资; 02 嵌入式的硬件属性 与Java不同,一台电脑就可以练习大部分的技能;嵌入式可以说是电子技术的一个细分方向,更多时候会接触到更加底层的东西,这时候,难免会和硬件打交道。 通常来说嵌入式软件,主流的有单片机开发,Linux开发,这些就需要在硬件实体上进行操作,特别是单片机开发和Linux驱动的开发,就经常要拿个示波器,在电路板上测来测去,然后再结合代码不断的Debug,才可以定位问题,最后甩锅给...

  VSCode几乎是所有的程序员必备的工具之一,据说全球一般的开发者都使用过VSCode这款工具。 今天分享一篇VSCode实现远程办公相关的文章。   1、概  述    通常,我们都是每天到工作的办公室进行办公,但是,如果下班回家,或者出差,此时如果马上需要重要的文件,或者升级一下代码,是不是必须要回到办公室才行啊? 但是,如果你电脑配置了远程办公,这种问题就迎刃而解了。 首先说下VSCode远程开发的工作原理,大致是这样的: VSCode远程开发原理 下面结合Win10、Linux云主机给大家...

  显示屏接口一般有I2C、SPI、UART、RGB、LVDS、MIPI、EDP和DP等。下面简要总结一下。 01中小屏接口I2C、SPI、UAR 一般3.5寸以下的小尺寸LCD屏,显示数据量比较少,普遍采用低速串口,如I2C、SPI、UART。 I2C: I2C总线是半双工,两线。 I2C总线的工作速度分为3种: S(标准模式):100Kbps,即100/8=12.5KB/s F(快速模式):400Kbps,即400/8=50KB/s HS(高速模式):3.4Mbps,即3.4M/8=435KB/s 超高速模式:5Mbit/s,即5M/8=525KB/s SPI: S...

以良好的方式编写Cclass  假设现在我们要实现一个复数类complex,在类的实现过程中探索良好的编程习惯。 ①Header(头文件)中的防卫式声明 complex.h: ifndef__COMPLEX__ define__COMPLEX__ classcomplex { } endif 防止头文件的内容被多次包含。 ②把数据放在private声明下,提供接口访问数据 ifndef__COMPLEX__ define__COMPLEX__ classcomplex { public: doublereal()const{returnre;} doubleimag(...

1.1概述 比例(Proportion)积分(Integral)微分(Differential)控制器(PID控制器或三项控制器)是一种采用反馈的控制回路机制,广泛应用于工业控制系统和需要连续调制控制的各种其他应用。 PID控制器连续计算误差值e(t)作为所需设定点(SP)和测量过程变量(PV)之间的差值,并应用基于比例、积分和导数项(分别表示为P、I和D)的校正,因此得名。 r(t)是期望的过程值或设定点(SP),y(t)是测量的过程值(PV)。 1.2历史发展 1911年,第一个PID控制器是由ElmerSperry开发的。 1922年,俄裔美国工程师尼古拉斯·米诺斯基(Nicola...

C代码提供了足够的灵活性,因此对于大部分工程师来说都很难把握。 本文介绍了写好C代码需要遵循的10个最佳实践,并在最后提供了一个工具可以帮助我们分析C代码的健壮度。 原文:10BestpracticestodesignandimplementaCclass。 1.尽可能尝试使用新的C标准 到2022年,C已经走过了40多个年头。新的C标准实际上简化了许多令人沮丧的细节,提供了新的现代方法来改进C代码,但让开发人员认识到这一点并不容易。 以内存管理为例,这可能是C中受到最多批评的机制。多年来,对象分配都是由new关键字完成的,开发人员一定得记住在代码的某个地方调用delete。“现代C”解决...

   PID控制应该算是非常古老而且应用非常广泛的控制算法了,小到热水壶温度控制,大到控制无人机的飞行姿态和飞行速度等等。在电机控制中,PID算法用得尤为常见。 一、位置式PID 1.计算公式 在电机控制中,我们给电机输出的是一个PWM占空比的数值。话不多说,直接上位置式PID基本公式: 控制流程图如下: 上图中的目标位置一般我们可以通过按键或者开关等方式编程实现改变目标值,测量位置就是通过stm32去采集编码器的数据。 目标位置和测量位置之间作差就是目前系统的偏差。送入PID控制器进行计算输出,然后再经过电机驱动的功率放大控制电机的转动去减小偏差,最终达...

感谢关注!   本期话题 现在越来越多的嵌入式设备支持远程自动升级,不需要再借助下载器。这样对于设备的维护非常方便。 当然若使设备支持远程升级,需要编写支持升级的程序代码,可以称之为BootLoader。 也就是说,将设备的程序代码分为两部分:BootLoader和APP。 BootLoader负责升级APP以及引导APP运行。APP负责实现设备的业务处理功能,也就是设备的核心功能代码。 对于Cortex-M系列的单片机来说,若要实现BootLoader安全跳转到APP,需要进行一些配置。 本文就以STM32单片机为例,来聊一聊实现BootLoader跳转的关键配置步骤。 聊一...

     不管你玩硬件还是做软件,你的世界都少不了计算机最核心的——CPU。   01CPU是什么? CPU与计算机的关系就相当于大脑和人的关系,它是一种小型的计算机芯片,通常嵌入在电脑的主板上。 CPU的构建是通过在单个计算机芯片上放置数十亿个微型晶体管来实现。 这些晶体管使它能够执行运行存储在系统内存中的程序所需的计算,所以,也可以说CPU决定了你电脑的计算能力。 02CPU实际做什么? CPU的工作核心是从程序或应用程序中获取指令并且执行计算。 这个过程一共有三个关键阶段:提取,解码和执行。 CPU先从系统的RAM中提取指令...

关注 更多

空空如也 ~ ~

粉丝 更多

空空如也 ~ ~