氢气球

记得小时候我妹妹出生不久大约也就半岁的时候,我和我爸从街上回家路上看到卖氢气球的,就买了一个黄色可以飘起来的气球,记得是那种稍微长条状的。回到家里边我妹妹可开心了,我一进卧室的门我妹妹就笑个不停,是那种真的一直笑一直笑,我们稍微拿气球逗一逗就一直笑。 再后来很多很多年,甚至最近几年前,我妈妈还提到过这件事,印象中是我妈妈坐在沙发上对我说的。可是现在我的娃到了玩气球的时候,我和我爸妈说起来了我妹妹小时候这件事,我爸妈竟然不记得了!虽然这件事情过去二十多年,可是前几年不超过5年我妈妈还主动和我说起过,而现在怎么就不记得了。我于是又问我爸,以及说了很多细节,但是我爸妈都是说这么多年过去了,怎么记得起来。不应该啊不应该啊,前几年还主动和我说呢。 后来我有又到过这件事,可是我妈妈只是说我妹妹小时候也玩过氢气球,但是对于我说的这个细节再也想不起来了。二十多年确实有点久了,我真担心很多记忆就像这件事情一样在不经意间就消失。我打算逐步开始我和爸爸妈妈还有我妹妹的日常,尤其是有过一段时间的事情,让这些温馨的回忆能够永久记录下来,而不至于随着时间而流逝。从这个氢气球开始,记录往日的点滴。

氢气球 Read More »

中国体验卡

上个月有位德国同事出差来到中国,周一到周六一共差不多5天时间。他是我在德国最直接对接的同事,所以我这几天需要密集陪同,来处理每一天满满当当的行程。 当他来到办公室首先我和同事一致的惊讶就是太年轻了,他说只有27岁,硕士毕业也就才一年多,来之前就听他说特别地感激他的老板,能够将中国区这一块业务让他独立负责,并且现在还给他中国出差的机会,来代表德国他们整个部门来到我们部门做业务交流。现在看到他的外表以及知道他仅仅正式工作一两年,确实带入他我也能感受到被信任的感觉。 这几天工作中认真细致一丝不苟地态度很能说明为何他能够得到老板的赏识,但是我今天想记录的不是这个点,而是对于一个欧洲年轻人,让他来遥远的中国出差一周,对于中国的感受是什么。在他出发前听他说他是有点担心和些许害怕的,毕竟和自己生活的环境太不一样并且太远了,同时又是充满了期待,对未知的世界充满好奇。他提到来之前做了很多的功课,查阅了北京的一些知识,还多公司附近地图做了很多的了解。 白天基本上就是忙忙碌碌干活了,也就午饭晚饭时间有机会带他尝尝中国的美食。刚来的时候问他喜欢吃什么有什么不吃的,他说不吃内脏,OK那去除内脏中国的美食还是有很多。刚来的时候我同事们陪的他,据说吃的海底捞和烤鸭,反馈非常的满意很是喜欢。后来中午我们带他去吃新疆餐馆大盘鸡,他一边说有点辣有点辣,一边使劲往嘴里塞说好吃好吃。同时还点了一个馕泡羊肉,给他介绍说这是新疆披萨,他蘸着那个汤一块接一块停不下来,还有给他点了新疆羊肉串,告诉他这是新疆BBQ,他也是边吃边说好辣但是又停不下来。 看他这么喜欢中国的美食,并且对于新鲜事物也不抗拒有一颗体验的心,我们决定带他吃了一顿川菜,不吃内脏把很多菜给排除了,那我们想着,吃点德国吃不到了,那就吃个皮蛋吧。于是点了擂椒皮蛋。他甚至之前都没见过这玩意儿,那天我也学到了一个有意思的词,皮蛋英文叫做century egg,也Hundred- year Egg,据说是看着像百年臭蛋。那个德国人惊讶的眼神看着这玩意儿脸上写满了难以置信,开始问我们这个是不是那种里边有个小鸡的蛋,我们说不是不是,就是鸡蛋的不同做法。他竟然动筷子去试了,这对于一个外国人简直不可思议。然后他反馈说有点太辣了,味道很奇特,不是他最喜欢的那种,但是也不差。当时还点了一个川菜名菜宫保鸡丁,他吃了好多,感觉他还是传统的国人喜欢吃那种甜甜的东西。 他出差时间特别紧完全没有休息,我们把工作内容压缩再压缩,终于在周五下午有一会儿时间,赶在四点故宫关门前走马观花进去带他就去溜达了一圈。问他需要一个德语讲解器吗他说不用,说讲解器信息对他来说太多了,他在有限时间内整体感受一下就是最好的。结果是在故宫文创店待了好久,买了好多纪念品给他的亲朋好友。。。逛完故宫最后一顿吃饭的时间,吃过晚饭他就该去机场了,我们决定带他去吃铜锅涮肉,想着多一些北京特色于是点了一个乾隆白菜和几个麻酱烧饼,到周五他筷子已经特别的溜了,吃了一口乾隆白菜惊讶地说这白菜怎么也这么好吃。。。又吃了一口刚出锅还热乎着的麻将烧饼,外观很像德国的面包,但是吃上一口那个德国人又是赞叹到不行,又同时把另外同时的一个给吃掉了。真正到了吃涮锅时候,蘸的麻酱也是让这个德国人欲罢不能,很多人可能夹起来肉只

中国体验卡 Read More »

德国亚马逊直邮爱他美

德国亚马逊直邮爱他美,是一条我实测成功的海淘路径。很多妈妈在选择奶粉路线时,会被真假难辨的代购、物流不稳定的海淘流程等问题纠结。于是我决定把这条自己走过的路写出来,给大家一个靠谱参考。以下内容是我从下单到收货的全过程,穿插一些实用提示与风险说明,希望能帮你把可能踩到的坑降到最低。 在进入正文之前,我先说说为什么选择德国亚马逊直邮。相比许多代购渠道,它在安全性上更有保障:亚马逊自营或平台背书,售后、物流体系更健全;而在价格方面,从德国本地站点购买时,商品会自动剔除德国本土消费税,这里就省下了一部分成本;此外,操作流程相对清晰,类似国内电商路径,新手也能快速上手。当然,这条路并不完全无风险:汇率波动、物流延误、海关抽查、退换货难题,都是需要提前有所预期的。 接下来我按时间顺序把操作流程写出来。第一个步骤是打开德国亚马逊(amazon.de):https://amazon.de 在搜索框里输入奶粉名称(如 “Aptamil Profutura 2”),在搜索结果中最好选择标注为 “Verkauf und Versand durch Amazon”(即亚马逊自营)那类商品,因为售后更可靠。我一般会避开第一行的广告位,点自然排序的结果。如果商品有多个包装规格(比如单罐、六罐、十二罐装等),我偏好原箱或大包装——这样包装更完整、运输更稳妥。 接下来点击详情页,在这里我们选择6个的选择,这款爱他美原箱是6罐,选择这个6个的很大概率直接连着原箱发,包裹就更加稳固。可看到6罐一共是155.7欧。然后点击右边的加入到购物车。 然后点击网页右上角购物车,进入购物车页面,再次确认下我们选的商品正确性,没问题的话选择继续。 现在到了付款页面了,这里需要填地址以及用于付款的信用卡信息。不知道为什么从这个页面开始网页内容变成了德语,在这里点击ändern填入中国的地址,基本上按照省市县填写拼音。在下图点击第二个红框填入信用卡信息,Mastercard或者Visa的卡号有效期卡背后的CVV。 填完这两项后会又回到这个页面,会让你选择快递。这里看到亚马逊全球标准快递(AmazonGlobal Standand)预计10月17日送达,也就是说预计耗时12天(下单日为10月5日),快递费是36.96欧。另一个亚马逊全球特快(SmazonGlobal Express-Zustellung)耗时10天,快递费是51.54欧。我选择了标快。 从上边右侧可以看到这次购物费用详单,奶粉价格是130.86欧,与我们之前看到的155.7价格低的原因是我们收货地址已经不在德国,在德国本土的消费税已经自动去除掉了。然后第二项包装快递费用是34.96欧,第三项是中国的进口税(消费税)是17.04欧。总费用是184.86欧。按照2025.10.05欧元汇率8.36换算平均一罐的费用就是8.36*184.86/6=257.57元,如果考虑到银行费用啥的大约就是265元左右到手。 点击最下边按钮就是立即购买,然后会看到成功页面,以及邮件通知。同时会有银行的扣款信息。 至此就可以坐等收货了。各种途径尝试下来,这个可能是最方便简单同时最具可靠性的方式和途径了。对代购以及国内平台不放心的朋友们,可以照着尝试尝试,如果你觉得有帮助或者说跟着教程海淘成功了,记得回来帮我点个赞啊 。

德国亚马逊直邮爱他美 Read More »

深度学习工作站系统重装步骤记录

最近需要配置一台CUDA环境深度学习工作站,打算把流程都记录一下,以防每次都得现查。 首先下载Linux镜像,我这里用的是Ubuntu24.04: https://ubuntu.com/download/desktop 然后制作一个USB镜像启动盘,这次我用的Ubuntu官网推荐的小工具,免安装并且只有3个按钮:选择镜像,选择U盘,烧录! 挺好用的推荐! balenaEtcher:https://github.com/balena-io/etcher/releases 接下来就是将BIOS选择U盘启动了,各个品牌电脑差异挺大的,按照自己实际情况去操作。然后选择全新安装Ubuntu,多数情况下直接默认选项安装就好。 系统装好后,我习惯先把当前版本的系统软件更新到最新: 当前这台工作站是公共的,需要给每个人分配一个帐号,可以在桌面环境操作,也可以通过命令完成,可以参考下边一篇记录: Ubuntu添加新用户并加入sudo组 如果工作站有中文输入需求的话,比如我目前记录这篇博文,还需要加一个中文输入法,可以看我这篇记录: Linux 安装中文输入法 接下来安装Python环境,不建议直接使用系统的Python来配置各种库,出现了问题太难修复了。建议使用Anaconda,各个环境相互不干扰。Anaconda的安装是通过官网的一个sh脚本: https://www.anaconda.com/download/success 下载后对其赋予一个执行权限,然后在终端里运行: 根据交互一步一步安装,最后一步询问要不要将Conda加入到开机初始化列表中,建议yes,不然后边每次使用Conda切环境需要手动找Anaconda安装文件夹,很麻烦。 安装完毕后,熟悉Anaconda的可以直接使用Conda来管理Python环境,若不太熟悉的话可以使用图形化的一个工具,在终端输入:anaconda-navigator 建议不要在base环境做开发,最好是每个项目有一个单独的环境,再使用conda安装pytorch,我个人没有按照Pytorch官网指导的使用pip安装,我个人经验是既然使用了Conda就尽量全Conda环境,尽量避免和pip混着用,以免一些未知的问题。在这里需要看下本机CUDA的版本,要做到Python版本、CUDA版本以及Pytorch版本相互保持一致。对应关系表在Pytorch官网可以查到。 经查询我需要安装2.5.1版本的Pytorch:conda install pytorch=2.5.1 接下来我们装个IDE,运行个实例看一看。官网下载VS Code然后使用下列命令安装: sudo dpkg -i ‘/home/v2x/Downloads/code_1.102.0-1752099874_amd64.deb’ 将自己用Anaconda建立的Python环境设为VSCode的默认解释器,按照Anaconda官方指导操作一下: https://www.anaconda.com/docs/tools/working-with-conda/ide-tutorials/vscode 之后运行一个示例程序,看下pyTorch以及CUDA是否都已经OK: 从Terminal的输出若看到True以及对应的网卡型号,那么说明基础环境已经完毕。 当需要远程连接到这台设备的话,发现SSH连不上,这是由于Ubuntu安装后默认没有sshd服务端。按照下列指导操作一下即可: Ubuntu 开启SSH连接 一些其他可能必备的工具: 最后再记录一下将U盘烧录成一个启动盘后,怎样恢复。按照通常的格式化format不管在windows还是linux都是解决不了的,可以参考下列记录解决: https://blog.shuspieler.com/1223/ 大致就这些了,祝炼丹顺利!

深度学习工作站系统重装步骤记录 Read More »

Vector DaVinci学习笔记:数据类型、接口以及SWC定义

在我学习SOME/IP过程中,涉及到了AUTOSAR常用的数据类型定义,手头上正好有Vector 的DaVinci工具,想着能否从AUTOSAR层面再递进一个层次对这个话题的学习,研究研究能否用DaVinci复刻一个之前一直用的那个SOME/IP示例数据库。 我手头有DaVinci的Developer和Configurator的License,可我没有参与具体的项目没有SIP包,所以我的电脑连Configurator装都装不上去,联系Vector售后看是否有Demo版本的SIP,至少采购DaVinci的License花了钱的至少能让我熟悉熟悉,可惜是沟通了好久无果,遗憾只能只学习学习DaVinci Developer,暂时没机会去了解Configurator了。 详细研究了一段时间Developer这个工具,我意识到我并不能从0复刻出来之前那个数据库。根据AUTOSAR体系结构的定义最高抽象为三层:应用软件层(Application Layer),运行时环境层(Runtime Environment, RTE)和在微控制器上运行的基础软件层(Basic Software, BSW)。而DaVinci Developer更多是对应用软件层做接口设计,对于系统相关的设定是不在其负责的范围内。对于我想要做的事情:设定ADAS和CAMF两个SWC并位于两个ECU或两个域中,其通过SOME/IP进行连接,传输的内容是一个多层嵌套的复杂结构体,这三件事可能只有第三个可以在Developer工具中完成,甚至ADAS和CAMF之间的接口,都体现不出来这是一个SomeIP Service,下边会具体介绍。 我的是Classic AUTOSAR工具,其主要编程语言是C,在图形化界面设计完成各个功能模块SWC后,可以生成对应的Contract Phase Headers 和Implementation Templates,从中可以看到工具将其定义的数据类型整理成C语言支持的数据结构,以及通过大量的宏定义将一些常量命名为人类友好可读的形式。还有就是工具定义了很多的接口用于SWC与之后的RTE进行功能调用数据传输。对于功能模块SWC也生成了空函数,便于后期具体逻辑填入从而实现完整的功能。 整体来说我对Vector DaVinci Developer的理解是,帮助我们在一个C语言功能开发的项目中定义头文件,通过工具的严谨性来保证代码开发方式下人类容易发生的低级错误,在此同时也会对C语言的灵活性做出一定的限制,避免一些C语言骚操作的使用不当造成未知的隐患。整体能感受到工具的目是降低数据类型定义的复杂度和出错概率,提高C语言语法使用的正确性。我们一步一步看一下工具的使用吧。 首先在DaVinci Developer中新建一个Workspace,对于要使用的AUTOSAR的版本我选择了最新的,在这儿如果是具体项目使用,就需要和整个项目所用的版本保持一致。从这个下拉框我们也可以看到,对于AUTOSAR版本的定义之前是X.Y.Z的形式,从某一个节点后改成了RYY-MM的格式,现在这种形式感觉直观了很多。 接下来我们整体看下这个工具的主界面,比较常用到的就是下边的几个框,其中1是来查看我们定义的不同元素的视图切换按钮,通过Types/Packages/Files不同维度,来看我们定义的Data Types/ Constants/ Components 等不同层级的元素。框2即为查看具体内容的地方。这次学习笔记后边大部分内容主要就是介绍这里边的各个项。 图3的框是灰的,在手册中看到这是由于我的Workspace是单独由DaVinci Developer生成而造成的,如果是配合了DaVinci Configurator的话,框3的功能既可以解锁。不过通过其他的途径我们可以使用其部分内容比如Software Design,Data Type Mapping等,后边也会有提到。 框4是的按钮可以按照AUTOSAR标准来检查我们的设计和配置是否有错误。可以帮我们做一些标准一致性上的检查,还是很实用的。框5是看我们鼠标当下选中的元素的具体属性信息的。 模仿之前数据库我计划是设计ADAS/CAMF两个SWC,之间的数据接口使用的TrafficSignDetection结构体。我额外设计了一个叫做Preprocessing的SWC,来模拟一个DistanceToSign的输入。在DaVinci Developer设计SWC时候有Composition Component Types 和Application Component Types两个概念,主要的区别是Composition可以理解成功能整体,而Application是组成整体的最小模块。Composition可以包含其他的Composition和Application,而Application是最小逻辑单位了不能再继续拆分。在这里我配置了一个ADAS_CAMF_Composition,我们假设这即为摄像头自动驾驶系统,然后这个系统由三个子模块组成:ADAS, CAMF 和Preprocessing,如下图。 双击我们新建的Composition,即进入了Software Design的界面了。可以看下图我这里的结构,一个Composition下挂3个Application,选中顶层Composition可在中间Interface Graphic界面看整个功能的对外接口,当前我的示例中输入为一个DistanceToSign_Application_Port_Interface_Comp_Input, 输出为DistanceToSign_Application_Port_Interface_Comp_Output。 切换在Structure Graphic视图,可以直观看到整个功能里边的模块是信号怎么流传的。我的学习示例中整个功能唯一的输入先送到Preprocessing模块,然后再原封不动透传到ADAS模块,假设再ASAS里我们做了一些处理,然后输出一个TrafficSignDetection结构体到CAMF,再在CAMF里边做一些处理,输出一个DistanceToSign作为整个功能的输出。 接下来从0开始看下这个例程中数据类型是怎么配置的。以Speed和signDistance为例,下边截图是对于Speed的Unit、CompuMethod 以及 Int To Phys

Vector DaVinci学习笔记:数据类型、接口以及SWC定义 Read More »

德国中国(新生儿)疫苗对比

要准备着给即将到来的新生儿打疫苗,了解到有很多必须接种的有一些是自费接种的,搞不明白哪些是真的推荐自费的哪些是医院用来营收的,我想着对比一下德国和中国的疫苗免疫体系,计划从中找点启发。 首先是中国儿童免疫程序表: 接下来是德国的儿童免疫程序表: ✅ 共同接种的疫苗项目(中德都有) 疾病 中文疫苗名称 英文缩写(中国) 德国对应名称 说明 乙肝 乙肝疫苗 HepB Hepatitis B 接种时间略有差异,中国更早 卡介苗(结核) 卡介苗 BCG – 德国不常规接种,仅推荐给高风险人群(非普种) 脊髓灰质炎 脊灰灭活疫苗、脊灰减毒活疫苗 IPV, bOPV Poliomyelitis 德国只用灭活疫苗(IPV) 百日咳 百白破疫苗(含) DTaP Pertussis 同为联合疫苗成分 白喉 百白破疫苗 / 白破疫苗 DTaP / DT Diphtherie 同上 破伤风 百白破疫苗 / 白破疫苗 DTaP / DT Tetanus 同上 麻疹 麻风腮三联疫苗 MMR Masern 接种时间略有不同

德国中国(新生儿)疫苗对比 Read More »

在德国补打疫苗推荐

下边这一段是之前朋友想我咨询在德国需要补哪些疫苗我给到的回复,当时研究了好久自己补了很多,所以时不时就有朋友问,之前我就把这一段发给他们,现在感觉可以记录在这里,有需要在德国补打疫苗的可以参考一下: 疫苗推荐更新:刚刚和医生详细沟通了一下,并且拿我自己总结的小时候打过的疫苗让医生看看哪些需要补打,很多错过的就错过了,主要是针对婴幼儿时期容易生的病。剩下的还有这些: DPPT(破伤风、白喉、骨髓灰质炎和百日咳): 每十年补打一Hepatitis A&B(甲肝乙肝): 每十年补打一次Influenza(流感): 每年一针所以小时候应该都打过,只是国内不知道要不要每十年补打,我身边人包括自己做到这一要求的不多。所以可以和医生讲价情况补打一次MMR(麻疹、腮腺炎、风疹):我上次没问医生也没主动提这个疫苗,今天问了下医生说小时候没接种啊!刚刚查了一下这个疫苗中国2008年是加入的免疫计划,所以2008年之前出生的可能没有接种过。而这个疫苗在德国是儿童时期强制接种的。医生说现在很多公共场合区域就需有对这个疫苗的接种证明。我今天医生这个需要再打,医生说以前接种过得找接种的地方去查记录,没有记录的就要重新接种,医生讲,医生看记录时要注意,一些疫苗的接种需要有 MMR 接种证明才能上岗。于是今天被捅住打了一针 MMR。 注意:DPPT 需要打一针,Hepatitis 需要打 3针,第一针第二针间隔1个月,第二针第三针间隔6个月。另外不同疫苗之间最短间隔 4周,如果不同疫苗间隔少于4周,需要医生评估。像今天我打 MMR 同周上次甲肝乙肝刚过去 2周,违背了疫苗注射的推荐间隔4周的要求,就是护士拿着接种单去找医生做了二次确认才来给我注射。 最终版总结:DPPT(破伤风、白喉、骨髓灰质炎和百日咳):每十年补打一针,Hepatitis A&B(甲肝乙肝):每十年补打一次,三针Influenza(流感):每年,一针MMR(麻疹、腮腺炎、风疹):2008年前出生,在德国生活推荐补打,2针 Reference:https://www.bundesgesundheitsministerium.de/themen/praevention/impfungen/schutzimpfungen.html http://www.caixin.com/2020-01-04/101500751.html http://www.chinacdc.cn/jkzt/ymyjz/zswd_10960/201904/t20190426_201664.html https://www.chinacdc.cn/jkyj/mygh02/jswj_mygh/myfw_mygh/202505/U020250528538419216264.pdf

在德国补打疫苗推荐 Read More »

SomeIP学习笔记:使用CANoe调试/仿真SomeIP服务

从上一篇文章(SomeIP学习笔记:基础知识)的介绍可看出SOME/IP标准预先定义了很多很实用的数据类型,可在实际项目中可能处于兼容性的需求,不完全依照上边数据类型原始定义使用,可能会结合着信号矩阵有进一步的定义,比如说有Offset和Scale的设置等。 接下来记录一下用CANoe怎样调试或者模拟AUTOSAR环境下的SOME/IP通信,在这里我使用的是CANoe SP5的一个SOME/IP例程:Basic AUTOSAR SOME/IP Event,如下图。 这个样例是使用Simulation Setup模式结合了一个ARXML创建的,已经有了很好的Pannel,对于我们学习Simulation消息订阅很方便。在下边两个框CAMF和ADAS,我们可以点击Enable Service或者Subscribe Service, 从上边的Trace窗口可以看到对应的服务端、客户端相应的Offer Service、Find Service、Subscribe Event group以及Stop Subscribe Event group的报文。 这个报文其实现原理主要依赖了三大块:CANoe的SOME/IP协议栈、示例ARXML数据库以及几个节点的CAPL代码。 其中示例ARXML数据库定义了一个服务端(Provider: CAMF)和一个客户端(Consumer: ADAS),规定了其支持的服务类型:即一个名叫ADASDisplayInfo的Event 事件通知,然后这个事件传输的变量叫做DetectedTrafficSign,类似于一个结构体,里边有SignType、DistanceToSign以及Realiabiliy变量,以及每个变量的更加细致的定义。 然后CAPL代码一方面实现了对于变量的填充,另一方面调用CANoe的SOME/IP协议栈进行Event Notification的发送以及SD服务发现事件订阅的过程。 最后SOME/IP协议栈提供了底层的交互支持,以及对CAPL的API调用的支持,从而非常简单实现服务发现订阅以及发送接收。 在这个例程默认的界面下,可以尝试点击那些按钮来从trace看服务端怎样发送报文Offer一个Service,以及客户端怎样发送报文Find 一个Service,以及服务订阅上后ACK是什么样,还有到了真正Event Notification的报文是什么样。这对于基础的SOME/IP报文熟悉还是非常有帮助的。 而截至目前所能模拟的通信都很依赖ARXML对于Service的定义,我想记录的更多的是对于自定义SOME/IP的学习以及调试方法。以这个ARXML中的服务为例,首先我们需要将其转换成CANoe可编辑的模式,使用CANoe自带的小工具将其转换成可编辑的数据库格式vCODM。 接下来就用不到这个例程了,我们把刚刚转换号的vCODM数据库存到某个文件夹,然后以此为例记录一下怎样使用CANoe的SOME/IP协议栈来自定义数据库模拟一个服务。 我们新建一个空的工程,使用Communication Setup模式,然后在红框1 和红框2处倒入刚才我们转换完成的数据。红框3我们下一步再点击,接下来将两个节点设置成仿真模式,以及将Real Bus换成Simulated Bus模式,现在运行一下看看效果。 点击运行后到Trace窗口看到,并没有像Simulation Setup 的例程那样有Service Offer、Service Find 以及Subscribe信息。 这个区别的主要原因是例程中数据库并没有开启服务发现SD协议,而例程中通过CAPL命令实现了Service Offer以及Service Subscribe。由于我们新建的没有这些脚本,所以从Trace来看并没有任何SOME/IP相关的数据。 在一开始我们了解到SOME/IP有一个SD服务发现的协议,在这儿没有起作用,是因为在数据库中,示例数据库这个设置处于关闭状态。我们在刚才按钮3的地方进入数据库编辑页面,然后将Discovery Technology协议从None 改成SOME/IP Service Discovery,这样子协议栈就会自动执行服务发现过程,保存运行然后我们再观察Trace窗口,有时候需要重新加载一下数据库才能生效。 现在看到已经有了Service Offer、Service Find、Subscribe Event group

SomeIP学习笔记:使用CANoe调试/仿真SomeIP服务 Read More »

SomeIP学习笔记:基础知识

在整车功能开发以及调试过程中,ECU与ECU之间使用车载以太网的比例越来越多,所以区别于之前的CAN总线报文的,对于以太网数据包的抓取和分析越来越普及了,而其中又绕不开SOME/IP,每一个搞过车载功能开发都或多或少接触过或者使用过SOME/IP。我在了解这个协议过程中走了不少弯路,后来发现并没那么复杂,于是打算把自己的心得记录下来。 主要从3个角度记录我所学习的SOME/IP,首先是一些基本的知识,其次是怎样用Vector CANoe来调试一个结合了AUTOSAR通信,包括怎样在CANoe里边调整数据库实现自定义调试;最后做一个实践,使用开源的SOME/IP协议栈vsomeip,来和我们CANoe的SOME/IP协议栈做一个真实的通信。 SOME/IP基础知识 SOME/IP是基于TCP/UDP/IP协议之上的应用层协议,很像网络开发中前后端交互的HTTP的方式。如果之前做过前后端的开发,对于客户端和服务器的连接有一定的知识储备,那么在了解SOME/IP的过程中会觉得很简单的。SOME/IP依托于TCP或UDP,所有的数据都是作为TCP/UDP的Payload通过IP协议进行传输。可以理解成在Payload中又做了进一步的切分,并且比特位以及长度做了事先约定,例如下图中的前16个Bit固定为Service ID,紧接着的16个Bit为Method ID或者Event ID。 目前网络中常见的SOME/IP学习路径和学习资料,包括我之前看的一些,大多是在CAN总线技术路线以及实现方式的基础上介绍SOME/IP的特点以及技术细节的,很多从以太网IP以及UDP和TCP开始讲起,然后再说到SOME/IP的各种Header头部还有服务订阅等等内容,这样的一个学习路径,非常容易把很多的类似的概念参合到一起,比如IP层、UDP、TCP以及SOME/IP都有Header头部,IPv4和IPv6头部又不一样,TCP的三次握手四次挥手和SOME/IP的Subscribe订阅以及UDP和Notification,太太太容易混淆了。可能看了好久还觉得云里雾里,觉得这个太高深了,其实真的SOME/IP没啥,将其理解成ECU之间的HTTP类似协议,下层依赖的TCP/UDP和电脑手机服务器用的没有任何区别,明白这个就已经学会了一大半。关于车载以太网和普通以太网的区别,我在另外一个学习记录贴中有记录,一句话总结就是物理层数据链路有区别,到了IP层以上就完全一样了。 不过从另外一个角度也可以理解,很多汽车软件的开发人员是从传统技术栈比如CAN总线时代过来的,对于以太网的了解不像互联网人那样深入,所以有一定的需求再详细了解一些IP/TCP/UDP的知识。我的建议是将这两部分分开学习,先回顾一下计算机网络,七层协议啥的,再了解一个应用层协议比如HTTP,最后再详细学习SOME/IP,绝对会事半功倍,发现真的好简单,半天时间SOME/IP入门足够。 另外在车载应用开发中,SOME/IP的Payload部分填充,考虑到和其他ECU以及功能的兼容性问题,会使用AUTOSAR的规则定义方式,这和CAN总线的Frame帧非常的像。在CAN总线Data Field数据场一次最多传输8字节,通常会把这对应的64个比特拆分成传输数据的最小量,比如一个布尔型只分配1个比特,然后一个0-255的Uint8只分配8个比特,总共8字节64比特能拆分成很多个Signal信号,从而有限的资源传输更多数据,各个Bit对应的Signal信号长度以及数据类型的记录成一个表格,即得到了CAN总线数据库DBC。在车载SOME/IP开发中Payload部分多数情况下也沿用了类似的思路,所以在Payload部分解析也需要一些额外的信号矩阵,结合了SOME/IP支持的数据结构和AUTOSAR数据结构,就能组合出很多复杂的结构体,实现更多上层应用间的数据传输。 这样的实现方式也可以很好的复用迁移传统汽车行业稳定成熟的软件解决方案,在必要的情况下,只需要在传输层做一些技术更新,核心逻辑不需要任何变动,从而降低潜在的风险。但是这一块是互联网人来做汽车软件的话,可能就不是很熟悉了,尤其对于不常见的Bit位的数据拆分,再结合这大端小端数据类型,还有信号矩阵有Scale放大缩小以及Offset偏移,八成互联网人转过来的开发第一次会搞错。建议之前对于汽车总线了解较少的开发人员可以系统学习一下CAN总线以及结合项目了解一下AUTOSAR信号矩阵,可以避免很多低级的错误。 传统车载网络CAN总线在面向信号的数据传输中,发送方会根据自身需求(如数值更新或变更时)主动发送信息,而无需考虑网络中是否有接收方当下需要这些数据。与之不同的是面向服务的数据传输模式即发送方仅当网络中至少存在一个接收方需要该数据时才会进行传输。这种方式的优势在于避免了不必要的数据对网络及所有连接节点造成的负载。因此,面向服务的数据传输要求服务器必须通过某种方式获知哪些接收方正在等待其数据。在SOA架构中,服务是构成系统的基本单元,它代表了系统中的某个功能或操作。服务通过明确的接口与外界进行交互,实现了功能的封装和重用。SOA架构的核心就是服务,它通过将应用程序划分为一系列的服务来降低系统的复杂度,提高系统的灵活性和可维护性。在SOA中,服务是通过其接口被定义和访问。接口是服务与外界交互的桥梁,它定义了服务的输入、输出和行为规范。在SOA架构中,以太网通信作为服务的传输载体,负责在不同的ECU或服务之间传递数据和信息,根据AUTOSAR平台的规范与推荐,一般选择以太网应用层协议SOME/IP协议或者DDS协议作为跨域通信协议。 在SOME/IP协议中,服务接口被明确划分为三种类型: Event、Field、Method,每种类型都服务于不同的通信需求。 Event and Field Notification 服务器基于活跃订阅发送的内容可呈现两种格式:事件通知(Event Notification)和字段通知(Field Notification)。这两种格式的共同特性是事件驱动生成机制,但其数据结构存在本质差异: 事件通知Event:采用自包含的静态快照形式,其字段填充的属性仅反映事件触发时的瞬时状态,与历史事件无任何关联 字段通知Field:包含具有时序关联性的动态值,除当前值外还隐含历史状态。因此字段可扩展为包含Getter/Setter方法,允许客户端对目标内容进行读写操作。 需要特别说明的是,在SOME/IP协议中,事件总是以事件组(Event group)的形式进行组织,客户端仅能订阅整个事件组,而无法单独订阅组内某个特定事件。Field的Setter/Getter 方法遵循请求/响应(REQUEST/RESPONSE)模式,变更通知则通过事件机制实现,所有订阅操作都需通过SOME/IP服务发现(SOME/IP Service Discovery)协议完成。 Method 另一种数据交换方式是通过方法调用(Method Call)实现信息传递。客户端通过发起远程过程调用(Remote Procedure Call, RPC),触发目标服务器上的函数执行。具体流程如下: 调用过程:客户端通过网络发送请求来调用服务器函数,该请求可包含作为参数传递至被调用方法的数据; 响应机制:服务器执行函数后,可能通过响应消息向客户端返回执行结果。 需注意,当客户端主动调用函数时,通常意味着需要获取返回数据,通常被称作RR模式(Method Request with Response),但服务器方法也可能不返回任何值(Void类型),常被称作FF模式(Method Fire & Forget),此时客户端在确认方法被成功调用后即完成整个流程。 Service Discovery 为了让客户端能够获知当前可用的服务,SOME/IP-SD(服务发现协议)提供了两种动态服务发现机制: 服务提供(Offer Service): 服务器通过该机制向网络宣告其提供的所有可用服务 每个设备通过组播(multicast)方式广播消息 消息内容包含该设备提供的所有服务列表 传输层采用UDP协议 服务查找(Find

SomeIP学习笔记:基础知识 Read More »