matlab 周立功can_隐藏在CAN协议底层的编码方式——到底是大端还是小端?

1699973f4649a1a41ab6fe3bdc68a58c.png

当我们想要讨论CAN协议底层发送到数据线上的二进制信号的编码方式时,最值得关注的两点是:字节编码Endianness)和比特顺序Bit Numbering)。

先一句话揭晓答案:

CAN协议的字节编码是大端编码,比特顺序是逆序

使用CANOE提供的CAN报文编辑工具,可以直观地看到CAN报文在内存中如下图所示:

b68493182a79602d0674c6b50001e79c.png

一般情况下,对于汽车控制器的开发人员来说,是不需要知道CAN报文的编码方式的,因为通常会购买一整套的CAN协议栈代码包,来完成报文组装的工作。

不过如果开发或维护过AutoSAR的CAN协议栈的话,就会知道,CAN协议栈通过构建若干静态表的方式,将信号在内存中的Buffer、信号的起始和结束比特位、报文在内存中的Buffer等串联在一起。每一个信号都有一对Read和Write(Receive/Send)接口,间接地对信号的Buffer进行操作。所以,应用开发者只通过调用接口,将信号值写入信号的Buffer时,CAN协议栈就会自动将信号值填入报文Buffer的对应位置,并且在报文下一个发送周期将新的报文发送到CAN总线。

什么是字节编码?

不论任何数据,在现代电子和计算机系统里进行存储或传输,最终都是以二进制的形式发生的,这里的讨论不包括早期的三进制计算机和现在最新的量子计算机。受限于存储器单元尺寸或总线宽度,数据会被按8bit、16bit、32bit、64bit等长度分段切割。不同的存储器,存放被分段的二进制数据时,会使用不同的顺序,这就是不同的字节编码

也就是说,当数据长度超过8bit时,数据的存放顺序才会被字节编码影响

字节编码有大端编码(Big-Endian)、小端编码(Little-Endian)和混合编码(Bi-Endian or Middle-Endian)三种。

,三种字节编码方式如下所示:

  • 小端编码

9ec490b31056a54de20b3a0985086fe8.png
  • 大端编码

fb3a1568b9ec0f7b8a3b2b8eb0bbf3a1.png
  • 混合编码,抱歉这不是CAN协议支持的格式,CANOE生成不了图片了,只能以0x0A0B0C0D为例,用表格表示一下吧:
0x0B | 0x0A | 0x0D | 0x0C

什么是比特顺序?

其实比特顺序算是汽车行业的术语,并不是很标准的一个定义,用于表示一个信号在一段消息中占据的Bit位置。通常比特顺序分为正序反序两种,也就是通常当我们谈到八成计算机、通信协议、存储器等的Byte中的Bit的顺序时,它都是正序的。而只有当我们谈到CAN协议时,它才有可能是反序的。换句话说,CAN信号也有可能使用正序的比特顺序,毕竟它是人为定义的。

以一个16Bit长的信号为例,在大端编码的情况下,如下展示两种比特顺序:

  • 正序

a693ffb4e5bcdece09d67917f56353f3.png

如图所示,Sample_Signal_6从第15Bit开始,到第0Bit结束。

  • 逆序

e16dc5a211762f32a96b2f908c68100c.png

也就是说,Sample_Signal_6从第8Bit开始,到第7Bit结束。这就变得在逻辑上有些奇怪了。目前为止,我也没查到CAN协议为什么要选择逆序的比特顺序,如果有知道原因朋友,请不妨向我透露一下。

熟悉CAN协议的同学,可能也听说过Intel格式和Motorola格式。那么,

什么是英特尔格式(Intel Order),什么又是摩托罗拉格式(Motorola Order)?

小端编码格式被称为英特尔格式,而大端编码格式也被称作摩托罗拉格式,这两种说法是等价。不论采用哪一种格式,字节编码在计算机系统中都是处于最底层的存在,要么体现在内存中字节的排列、要么体现在通信线上的码流的字节顺序,在现代计算机系统中,自动就被处理了,所以这一切对绝大多数程序开发人员来说,是透明的。

正因如此,现在已经很少讨论,为什么字节编码格式会和两家科技巨头的名字产生关系了。而且我搜索了许久,发现中文世界主要是CAN总线工程师会用Intel格式和Motorola格式的说法,却没人讨论这种说法的缘由。所以我决定对这个历史问题进行了一番探索。

最早的计算机都是大端编码。1965年前后,IBM在开发IBM System/360时,使用了大端编码格式,而后IBM开发出的一系列元祖级计算机System/370,、ESA/390、z/Architecture、Series/1等等,都是继承了这一格式。所以,大端编码为什么不叫“IBM格式”?

032b055070c2a1d3e0c64d0521d5b7c1.png
史前巨兽——IBM System/360

在这一时期,上古计算机大佬DEC(在2002年被HP吞并)开发出的PDP-10系列同样使用大端编码。可是,接下来在生产16位机PDP-11系列时,DEC却剑走偏锋,使用了一种现在被称为“混合编码”的格式。现在我们已经很陌生了,但是PDP-11可以说是那个时代最重要的计算机产品,在生涯服役期间创下了60万台的销量,一举为DEC打下计算机半壁江山。PDP-11的设计激发了Intel X86和Motorola的设计理念,同时其搭载的操作系统部分设计,也对MS-DOS产生了深远的影响。甚至现在大名鼎鼎的UNIX,第一次正式亮相也是搭载在PDP-11系列上,顺便证明了C语言在计算机编程的优越性。

307d2e82d01a2fb0b5e26ab99b253e3e.png
生涯销量60w台的PDP-11

IBM为了与PDP-11竞争,生产出同样是16位机的Series/1,为了提升竞争力,IBM决定把PDP-11的UNIX系统移植到Series/1上,在这次的移植中,人类第一次遭遇了字节编码差异产生的bug,这就是著名的“NUXI问题”。

IBM工程师最早移植的一段Unix函数中,有本应一个打印一串“Unix”字符串的功能,可是在实际运行时,打印出的确实“nUxi”。这是因为在混合编码的PDP-11上,“Unix”字符串在内存中的存储顺序为:

"n" | "U" | "i" | "x"

系统在读取时做了字节顺序调整。可是在大端编码的Series/1上,内存中顺序是本来就是:

"U" | "n" | "i" | "x"

系统用同样的方法调整字节顺序,反而造成了错误。

2ccbd5bbc578bb6d06e05dd50daf709b.png
遇到NUXI问题的IBM Series/1

其实,虽然早期的IBM芯片使用的是大端编码,但是后来在PowerPC时代使用的却主要是混合编码了

说完了IBM,接下来聊一聊英特尔。

那个计算机芯片军备竞赛如火如荼的时代,英特尔还是场中名不见经传的参赛者。他们接到了一个重要的生意,为CTC(Computer Terminal Corporation,早期PC大佬,现在也只剩名字还流传了)的Datapoint 2200供应芯片。这台Datapoint 2200是小端编码的计算机,因此英特尔也用小端编码设计他们的8008。虽然8008的设计周期并没有赶上Datapoint 2200,以至于2200不得不选用其他的替代方案,但是8008经验却为Intel提供了宝贵的财产。

212f66762cc791d8414f441946d6737d.png
黄金散热器和黄金PIN脚的Intel 8008

首先,Intel 8008的指令集,在后继者——“网红爆款&时代宠儿”——Intel 8080上被继承,并且最终演化成为大名鼎鼎的x86指令集。

其次,小端编码在英特尔x86家族上被继承下来,以至于直到现在,最新的Intel x86或AMD64或x86-64家族的芯片上,即使已经能够兼容大端和小端编码了,但是实际上在最低层使用的仍旧是小端编码,只是系统多增加了一步自动转换的操作。

9444227683659171a13677301db73968.png
时代之子——8080,同样拥有黄金散热器和PIN脚

又说道摩托罗拉这边,没什么特别的故事了。他们家的芯片,直到变成Freescale为止都是以大端编码为主。现在Freescale都已经变成NXP了,即使产品已经引入了ARM架构,也和那个Motorola没关系了。

至于ARM架构,我们知道ARM是很“年轻”的芯片公司,再加上他们只做设计不从事生产的经营模式,产品没有那么多历史包袱。在ARM3之前都是小端编码,而之后一直以混合编码为主导。

讲到这里,答案应很清晰了,在计算机历史的长河里,Intel始终是小端编码阵营的开拓者,而Motorola的整个生涯都在大端编码的领土耕耘。所以,现在人们把“Intel 编码”等同于小端编码,而“Motorola 编码”等同于大端编码。

可是AMD也是小端编码阵营的忠实信徒,为什么没有“AMD 格式”的说法呢?

其实,大端和小端,或者说Intel格式或者Motorola格式,像那个时代的很多设计方案一样,并不是某种预知未来般的抉择,仅仅是一种更具随机性的二选一。于是,在机缘巧合之下,一方选择了大端编码,而另一方选择了小端,却变成了一种传承或者执念。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499020.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

samba服务器新建文件权限,Ubuntu中安装samba服务器创建文件共享的方法及普通用户设置共享的问题解析...

Ubuntu中安装samba服务器创建文件共享的方法及普通用户设置共享的问题解析发布时间:2011-01-04 19:10:00 作者:佚名 我要评论本文是基于ubuntu桌面版进行操作说明的。前面的设置都是管理员进行的,这里说的管理员就是可以使用sudo命令&am…

flashpaper打印机没有被正确安装_没有正确保存与安装,可导致80%的轴承提早失效...

轴承损坏可谓司空见惯,可您是否知道,80%的轴承提早失效是因为没有正确地安装。轴承的正确安装,不仅可以增加轴承的使用寿命,降低成本,还可以大大提高生产效益。轴承安装与常规其他部件安装有很大区别,为了实…

rabbitmq实例_RabbitMQ不得不知道的点

RabbitMQ的优缺点优点这边的流量削峰功能主要应用在秒杀活动中,在秒杀活动中一般因为流量过大,导致应用挂掉,为了解决这个问题,在应用前端、库存系统前端加入消息队列,在订单系统中,服务器收到用户的请求后…

图片优化_网站里的图片应该如何优化

我们一直都在做网站关键词、内页关键词、标签等。但很多朋友都忽略了网站里的图片如何优化。近年来百度图片识别、360图片识别都在不断升级功能上已经很完善了,所以我们应该对网站图片进行优化,应该做seo的朋友们重视起来, 下面笔者跟大家分享…

rabbitmq 取消消息_mall整合RabbitMQ实现延迟消息

本文主要讲解mall整合RabbitMQ实现延迟消息的过程,以发送延迟消息取消超时订单为例。项目使用框架介绍RabbitMQRabbitMQ是一个被广泛使用的开源消息队列。它是轻量级且易于部署的,它能支持多种消息协议。RabbitMQ可以部署在分布式和联合配置中&#xff0…

vue 将行转换成对象_Vue简化版实现

Vue整体结构Vue: 把data中的成员注入到Vue实例,并且把data中的成员转换成getter, setterObserver: 劫持对象的所有属性, 如有变动可拿最新的值, 通知DepCompiler:解析每一个元素中的指令/插值表达式, 替换成相应的数据Dep: 发布者…

python 如何修改字典的key值_如何使用python技术完成数据集缺失值多种应用场景的滤除或填充?...

前言在数据处理的过程中,我们应该都有这样的体会,本质上数据处理与分析是相互协作,彼此成就的过程。比如,我们会用数据分析统计数据集中的缺失值、异常值,更直观的也会进阶到数据可视化的部分(到达该部分一般是成了文章…

python graphics 清空 图_【手把手教你】使用Python玩转金融时间序列模型

01引言上一篇推文【Python量化基础】时间序列的自相关性与平稳性着重介绍了时间序列的一些基础概念,包括自相关性、偏自相关性、白噪声和平稳性,以及Python的简单实现。本文在此基础上,以沪深300指数收益率数据为例,探讨如何使用P…

postman linux_Postman使用

postman简介官网https://learning.getpostman.com/用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具。今天给大家介绍的这款网页调试工具不仅可以调试简单的…

java与MySQL做购物系统_java Swing mysql实现简单的购物系统项目源码附带指导视频教程...

大家好,今天给大家演示一下由Java swing实现的一款简单的购物程序,数据库采用的是mysql,该项目非常简单,实现了管理员对商品类型和商品的管理及用户注册登录后浏览商品、加入购物车、购买商品等功能,旨在学习Java 图形…

mysql pdm_mysql 生成pdm

1.条件1.1 工具powerDesigner16.51.2 mysql数据库地址或脚本1.3 mysql-connector-odbc-5.3.4-winx64.msi2.操作步骤2.1 database > change DBMS 选择Mysql5.02.2 打开powerDesigner16.5工具, file > reverse Engineer > database确定,则生成对应的pdm.3.图形列表中展示…

java 调用htm中js函数_从 node.js Web应用中调用 WASM 函数 | WebAssembly 入门教程

文中所有的代码都可以在 https://github.com/second-state/wasm-learning/tree/master/nodejs/hello 中找到在之前的教程中,我们讨论了如何从 Web 浏览器中的 JavaScript 应用程序访问 WebAssembly 函数。WebAssembly 快问快答从 Rust 开始入门 WebAssembly | WebAs…

vba cad 读取宏的路径_openpyxl 第三篇 lt;工作表的读取和写入gt;

1、打开表格文件from openpyxl import load_workbook wb load_workbook(r"文件路径工作簿文件全名")2. 查看有哪些sheet页sheet_names wb.sheetnames print(sheet_names)3. 读取指定的sheet页sheet1 wb[指定工作表的名字]4.单元格的使用#写 sheet1.cell(row3,colu…

mysql 一致性读_MySQL半一致性读原理解析-从源码角度解析

1、什么是半一致性读A type of read operation used for UPDATE statements, that is a combination of read committed and consistent read. When an UPDATE statement examines a row that is already locked, InnoDB returns the latest committed version to MySQL so tha…

飞秋发送文件对方无法接收_微信新功能,发送高清图片和视频终于不会被压缩了...

今天,扎比从微博中刷到了腾讯微信团队的最新微博,称微信支持发送高清图片视频不被压缩,而且给好友发送的文件容量上限也变得更大了。发送教程一般情况下,我们使用微信给好友发视频和图片时都会被压缩。而今天扎比分享的是一个不会…

张仰彪第二排序法_C++之排序

常见的各种排序算法复杂度快速排序1.原理假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边&am…

mysql1440秒未活动_phpMyAdmin登陆超时1440秒未活动请重新登录

本文章总结了关于phpMyAdmin登陆超时1440秒未活动请重新登录解决方法,有需要的朋友可参考本文章。问题现象:现象一:phpmyadmin在使用过程中经常出现“登陆超时(1440秒未活动),请重新登录”;现象二:phpmyadm…

python3读取jpg_python3读取图像并可视化的方法(PIL/Pillow、opencv/cv2)

原图:使用TensorFlow做图像处理的时候,会对图像进行一些可视化的操作。下面,就来列举一些我知道的图像读取并可视化的方法。 1. Pillow模块 1.1 Pillow模块的前生 Pillow就是python2中的 PIL 模块。PIL模块(Python Imaging Librar…

mysql一对多增删改查_SpringBoot+MySql+ElementUI实现一对多的数据库的设计以及增删改查的实现...

场景业务中经常会用到一对多的数据库的设计与数据的增删改查的实现。比如要实现一个对手机应用配置允许访问的权限的业务。app与权限就是一对多的关系。即一个app可以拥有多个权限。注:实现首先设计数据库。要有一个app表、一个权限表、一个app与权限关联表。首先设…

python设置时间到后结束程序_Python设置程序等待时间

写代码时,特别是涉及到其他外部可执行文件调用时,通常会出现调用程序还未生成结果,后面的程序就自动执行的情况。而通常情况下,前一步调用的生成结果是下一步程序的输入文件,因此出现找不到该文件或打不开该文件的情况…