0%

端口port

网络技术中,端口(Port)大致有两种意思:一是物理意义上的端口,比如,ADSL Modem、集线器交换机路由器用于连接其他网络设备的接口,如RJ-45端口、SC端口等等;二是逻辑意义上的端口,一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。计算机“端口” 是英文port的义译,可以认为是计算机与外界通讯交流的出口。

常见端口

常见就是http80,https443,ssh22,FPT21,SSL465.

邮箱发送25或者587,使用SSL加密465

邮箱接收110,SSL加密995.

更多可以查考下面的博客

【计算机网络】端口详解【概念、作用、分类、常见端口】_计算机网络端口的作用-CSDN博客

一般用到的是1到65535,其中0不使用。 1-1023为知名端口(Well-Known Ports)。 1024-49151为用户端口(Registered ports)。 49152-65535称为动态端口(Dynamic Ports)。

端口的实际意义

端口号是用来标识同一台计算机上运行的不同网络应用或服务的标识符。IP地址标识的是一台计算机(或者说一个网络接口),而端口号则标识的是该计算机上具体的应用程序或服务。

当你有一个应用使用了12345端口去访问网络时,回传的数据确实会通过这个端口号返回到你的应用。更具体地说,操作系统会根据IP地址找到相应的计算机,然后根据端口号将数据交给在这个端口上监听的应用程序。

总结一下:

  1. IP地址:定位到具体的设备。
  2. 端口号:定位到设备上运行的具体应用程序或服务。

当你在某个端口(如12345)上启动一个应用程序时,操作系统会确保网络数据包中带有该端口号的数据能够正确传递到这个应用程序中。

修改端口

这个一般分为编程和应用,编程期间,就是可以选择没用到的端口或者多路复用来选择端口,这个是开发层面的了。

应用层,一般就是开应用怎么处理和设计,windows也是可以选择静态网络ip和端口。举个例子咯,我们使用git访问github,总是访问不了,然后显示443错误,这个就是https连接超时了,解决办法,把本地vpn设为静态的本地ip和端口,然后修改git的https也为本地地址和ip

1
2
git config --global http.proxy 127.0.0.1:<你的端口号>
git config --global https.proxy 127.0.0.1:<你的端口号>

LCD

这个不论是MCU还是linux软件开发,都是一个非常常用的输出功能,还有就是LCD+电阻组合成触摸显示屏,LCD的原本名称是液晶显示屏,所以博客就说显示功能了。

LCD显示

不论是MCU还是linux,都是调用厂商提供好的lcd代码进行二次开发,也是把项目添加进去,mcu就把源码加入项目编译即可。linux就是添加lcd设备,写好驱动和设备号,等待上层应用调用,这个调用一般都是直接内存映射过去的,这样可以减少毛刺和传输速度慢的问题。

LCD得到数据之后,显示是要一段时间的。所以,主控在发送数据之前,得确保LCD出于空闲状态,此时就会去查询状态,空闲之后才发送数据,lcd接收数据就开始显示,显示完毕之后再回复设置为空闲状态,进行下一轮。

阻塞问题

根据上面这个流程,就可以知道传输是一个问题,但是等待LCD空闲,这个过程导致主控阻塞等待这也是一个重要因素,为了解决这个问题,就可以利用CPU里面得概念了,就是流水线。

双缓冲

问题就出在,显示的过程中,是无法发送数据的,如果,有两个缓冲区是不是就可以一个用于显示一个用于缓冲呢,这样再显示的过程中,就可以立刻发送空闲,让主控去发数据过来,从而节省阻塞时间。

为什么这样节约时间呢?

原因是,主从设备之间处理速度,一般都是比不过设备自身内部处理速度的。主从通信是要握手,是要双方都就绪才是有效的,而设备内部切换和操作就是瞬间的,就是一个顺手的事情。对于LCD来说就是一个切换指针指向的操作,一下子就可以执行完毕了,但是传输过程是需要确认双方状态的,所以,这个过程才是真正卡脖子的过程。

三缓存

就是在双缓冲的基础上面,再加一个缓冲区,进步增加效果和帧率,三缓存就真的真的够用了,再多就有些多余了,这就像电脑玩游戏一样,cpu到了8核之后,继续添加核心基本没有提升的,就是到了瓶颈了。

总结

缓冲区就是利用类似流水线的思想,把本应当下一帧做的事情,在当前时刻进行并行处理实现对下一个帧的部分事务,让下一帧可以更加快速高效执行,这其实是一个非常非常好的设计思路。

source insight

Sourceinsight(以下简称SI)是良许使用过的最好用,最顺手,最强大的编辑器,没有之一!它几乎支持所有的语言,包括:C,C++,ASM,HTML等等,能够自动创建并维护它自己高性能的符号数据库,包括函数、method、全局变量、结构、类和工程源文件里定义的其它类型的符号,对于大工程的源码阅读非常方便。

但是,作为Linux程序员,我们的代码一般放在Linux电脑里。Linux里也有一些好用的代码查看工具,比如sublime,以及著名的Vim。SI什么都好,但就是没有Linux版。如果我们一定要用前文介绍过的共享文件夹来实现。

为什么不用vs code?

vscode就是出了名的好用,这个好用不是说它特别厉害,而是特别好上手,好上手不代表它好用。有些东西是需要适应的,不是说,不好用就逃避,尤其看linux内核源码的时候,不用这个的话,真的会绝望的。

VScode和SourceInsight,到底哪个看源码爽?_vscode和source那个好用-CSDN博客

source insight用法

根据下面这个博客就可以配置啦,还可以得到学习版本哦

嵌入式开发神器—SourceInsight 4的使用教程(附安装包)_sourceinsight4-CSDN博客

总结

vscode是最好用的”农具“,source insight是最好用的”字典“。

.bss

BSS段(bss segment)通常是指用来存放程序中未初始化的或者初始值为0的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。

.data

数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配

.txt

代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新 分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变 量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进后出特点,所以 栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

自定义段

其实根据上面这些东西,你就会发现,其实,他们都是段,我们可以打开一个mcu的map文件,就会发现。

.data 是存在rom的,但是他们运行的时候会被加载到sram之中,会被映射load过去。

.bss 是直接在ram空间的。

txt是写在rom,注意了所有函数都是写在rom的,因为函数是不变的,只是一个输入输出的过程,所以它是不变的。

堆栈这两个,是可以直接手动修改的,看map也知道它们的起始地址和大小

所以,我们可以自己使用section来定义属于自己的段

shell

cli命令行,mcu和linux想要实现cmd的话,都是使用section来开辟属于自己的地址,这个初始化在函数执行之前,开辟一个shell结构体,然后调用入口函数和出口函数,就可以实现链表的插入,这个结构体内部就是,一个string,一个函数指针,一些状态。使用方法,比如usart中断触发的时候,就可以在进行轮询判断,然后执行对应的函数指针。

OS_malloc

有些os是有自己的malloc函数,这不是c库的,其实c库函数就是从那个堆空间选一段空闲连续的空间。所以,我们也可以在sram中选择一个起始地址,选择大小,然后就可以编写一个OS_malloc,指向我说开辟的section地址,这样就可以实现c库的malloc功能。

总结

其实,这些段,就是最基础的编译需求,也是留给我们开发人员很多空闲的部分,搞嵌入式,对于sram和rom是要非常了解的才行。注意了自己开辟的地址,不要冲突了,比如写mcu,自己的代码100kb,然后你用一个section指向一个0x8019000以内的,那就冲突了,程序都会有问题的,还有就是sram的地址也不要冲突了

起因

我在和一个朋友讨论bootloader的时候,他提出了他的设计思路,也就是状态判断的一个设计,这个设计,确实是我没想到的,也就是bootloader得到上一次复位的原因,是掉电复位,看门狗,还是软件复位

复位寄存器

这个寄存器不会因为断电而丢失,STM32中,RCC的寄存器和功能因芯片的不同而不同,但RCC_CSR寄存器是众多STM32种都具有的一个。

但是,rcc_csr寄存器也是在sram中的数据,掉电就会丢失,因为需要有备用电源,就是一般有那种备用电源的设备上面。其实也可以理解,一般有稳定电源的mcu也不会担心掉电问题,备用电源(电池)就是因为要低功耗啊,才可能出现主电池没电问题。

作用

开机的时候,可以根据上一次的行为来知道为什么复位。

  • 可以利用看门狗喂狗的功能:跳转app,如果app没喂狗就说明了app有问题,直接复位失败,几次之后就立起来标志位,并发送给云端,说明当前固件错误的问题。
  • 利用掉电复位来报警,因为电池的供电本来就是一个不稳的情况,一般mcu在2.2v就能启动了,1.8v就不能工作了,一般都是有pvd中断的,可以结合pvd+掉电复位来报警提醒电量不够。
  • 软件复位,可以直接用于ota,软件层面接收到数据,bootloader接收到是软件复位就开始了升级了,也是一个设计。
  • 监控mcu状态是否合理,多次复位,肯定是有问题的,可以把复位原因每次都发送云端,这样方便修改和调试,找到问题。

当然功能还是以查询状态,然后针对这个状态,做出一些措施而已。有联网的措施,有本地的措施,有程序自检的措施,主要是看产品设计和定位。

总结

我个人认为还是物联网方面需要这个功能,如果只是一些普通的项目,一般都是没问题的,只要通过了测试,很多问题都是可以的,反而因为需要远程4g或者wifi的fota,这个很可能出现网络问题,传输问题等。而且物联网总是需要实时监控的,有这个功能,也方便管理和及时ota来修复应用层问题。

BSDiff

BSDiff是一种可执行文件的二进制差异构建和应用修补工具。

作者为Colin Percival,早在2003年就已经写好了这个工具。官网是Binary diff,不过看来已经下载不到资源,处于不维护的状态。这个可以说是非常非常老的东西了,不过已经稳定的东西,就不用修改了,这世上的屎山可不少,维护的人却是越来越少了,只要它是稳定独立的、模块化的,大家也就都不会去动他。

增量更新BSDiff算法溯源和原理解析

就是类似于linux、windows的那些补丁一样,linux本身也是有利用补丁来实现替换,这样就不用修改整个文件,只需要修改差异化部分进行替换就好了。

为什么要BSDiff

我们常见的OTA,都是把整个bin都传过去,或者自己的一些压缩算法,帧头帧位,组包,校验、MD5等方法,保证整个文件的完全传输,有的时候固件很大很大,上百上千KB的时候,不论是用tcp还是udp传输都是有大小传输限制的,大概也就是1000个字节左右,所以,就会有多个包,还要加上自定义的协议等操作,中间只要出现网络的问题,很可能就会导致下载失败,然后bootloader就直接丢弃了下载数据。

总的来就是,尽量减少对外通信的时间,不要过度依赖外部网络,因为物联网设备工作在什么场景都可能的,不是说在实验室和公司的那种环境,所以,传输的数据越短越少,就越稳定越可靠,然后通过主控、处理器自己去处理这个差异补丁,反过来得到固件。在主控、处理器内部进行拷贝覆盖原本应用,校验、测试处理等。

MCU实现

我也是参考了下面这个博客才有的想法,确实是一个很好的开源项目,总的来说,原理就是调用BSDiff算法库(就算是源码,我估计你也不愿意看的,稳定的东西,用就好了,肯定涉及很多内存方面的东西,估计跟FS有的一比),对更新好的数据,进行处理。

在STM32中使用bsdiff算法实现差分升级(bootloader)_差分升级算法-CSDN博客

linux实现

linux补丁指令入门

Linux patch命令教程:如何在Linux中应用和创建补丁(附实例详解和注意事项)-CSDN博客

这个实现可以查考下面这个博客,不过就是一些命令行操作了,就更见简单了,其实就是文件系统那一套设计思路,进行对应数据修改+索引追加和指向,然后最后重新生成差分包,算法得到这个生成的差分包,就知道该怎么修改了,有点簇的味道了。

增量更新BSDiff算法溯源和原理解析_bsdiff原理-CSDN博客

总结

BSDiff的原理和技术非常成熟,可以用于apk的差分,不过在mcu之中也是可以使用这种方法,把这个功能写到引导之中,通过BSDiff算来就可以做到,只下载差异化部分,然后自动更新固件的功能。自然不可能只有BSDiff,如下博客,还有其他的方法,本质都是差不多的原理,通过差异化来生成文件,进行替换。

Xdelta3 bsdiff Courgette三种差分算法比较-CSDN博客

DNS