1.基于AbstractProcessor扩展MapStruct自动生成实体映射工具类
2.基于Embedded Coder 的源码AUTOSAR代码生成及MIL SIL PIL验证
3.ä¸è¡ä»£ç 解å³Excelå
容转List
4.linux设备驱动程序——设备树(0)-dtb格式
5.什么叫底层代码?
基于AbstractProcessor扩展MapStruct自动生成实体映射工具类
原文作者:京东物流 王北永 姚再毅
在日常的软件开发过程中,领域驱动设计(DDD)经常要求将价值对象(VO)、源码模型(MODEL)和实体(PO)等不同层次的源码模型进行互转。传统的源码属性拷贝方法存在效率低下、性能不佳的源码问题,尤其是源码时空猎人辅助源码在处理大量对象时,可能导致内存溢出(OOM)。源码为了解决这个问题,源码许多开发者转向使用工具类进行暴力属性拷贝,源码尽管这种方法在某些场景下可以提高效率,源码但同时也带来了诸如性能损失、源码代码冗余等风险。源码
现有的源码解决方案中,MapStruct是源码一个基于JSR 标准的库,它允许在编译期自动生成属性映射的源码代码。MapStruct通过注解处理器(Annotation Processor)在编译时处理注解,从而在源代码级别生成优化的映射逻辑。该库通过修改抽象语法树(AST)来实现这一功能,具体步骤包括生成AST、调用注解处理器、修改AST并最终生成修改后的字节码。
然而,MapStruct的使用仍存在一些局限性。每当引入新的领域模型时,开发者需要手动编写转换接口或方法,这在处理多个模型间的双向映射时尤其繁琐,如A到B、B到A、List到List等转换。为解决这一问题,本文提出了一个扩展方案,旨在通过将MapStruct的定义直接应用于模型的类或字段,自动根据模型上的自定义注解生成转换接口。生成的接口与原有MapStruct功能兼容,保持了原有的过生日代码源码转换逻辑,同时减少了手动编码的工作量。
在实现这一扩展方案时,关键依赖了AbstractProcessor类以及实现了JSR 标准的注解处理器。通过AutoService注解,无需手动维护META-INF/services目录,简化了注册流程。JavaPoet库则提供了生成Java文件的强大能力,简化了代码生成过程。
具体实现步骤包括定义新的注解(如AlpacaMap和AlpacaMapField)以及自动生成接口(AlpacaBaseAutoAssembler)。这些注解和接口的定义与MapStruct紧密集成,允许在编译期自动生成所需的转换接口和实现类。通过这种方式,开发者可以更轻松地管理和扩展映射逻辑,无需重复编写转换代码。
实践表明,这种扩展方案极大地提高了映射逻辑的可维护性和可扩展性。在应用示例中,通过定义模型类和字段的注解,自动生成了转换接口和实现类,从而实现了模型间的高效互转。通过Spring容器引用生成的接口实例,开发者能够轻松实现多种模型之间的数据转换,显著提高了开发效率。
总结而言,本文介绍的扩展方案旨在通过简化映射接口的生成过程,增强MapStruct的灵活性和适应性,从而为开发者提供更高效、更可靠的属性映射解决方案。通过这种方式,开发团队能够更专注于业务逻辑的实现,而将映射细节交由自动化工具处理,极大地提升了开发效率和代码质量。
基于Embedded Coder 的AUTOSAR代码生成及MIL SIL PIL验证
生成符合 AUTOSAR 标准的 C 代码和 ARXML 描述,通过使用 Simulink 编码器和 Embedded Coder 软件,裴波周期源码可以构建 AUTOSAR 组件模型。此模型将生成算法 C 代码,并导出符合 AUTOSAR 经典平台规范的 ARXML 描述。在 Simulink 中进行测试或集成到 AUTOSAR 运行时环境中。
首先打开要从中生成 AUTOSAR C 代码和 ARXML 说明的组件模型。使用 open_system(“autosar_swc”) 来打开一个示例模型。若要优化代码生成的模型配置设置,推荐使用 Embedded Coder 快速入门。通过从“应用”选项卡中打开该应用,并在 “AUTOSAR” 选项卡上单击“快速启动”来完成快速启动过程。选择“输出”窗口中的符合 AUTOSAR 的输出选项 C 代码。快速入门软件将指导您完成配置步骤。
在生成代码之前,请检查 AUTOSAR 字典中的 XML 选项设置。在“AUTOSAR”选项卡上,选择“代码接口”> AUTOSAR 字典”。在 AUTOSAR 字典中,选择“XML 选项”。配置参数包括将“导出的 XML 文件”打包设置为“模块化”,以便将 ARXML 导出到模块化文件中。这样将生成 modelname_component.arxml、modelname_datatype.arxml 和 modelname_interface.arxml 等文件。
完成模型的配置后,生成符合经典平台规范的 AUTOSAR C 代码和 XML 组件说明。在模型窗口中按 Ctrl+B 生成模型。生成过程将 C 代码和 ARXML 说明生成到模型生成文件夹中。生成完成后,将打开代码生成报告。通过执行这些步骤,可以确保模型的正确配置和生成。
要从已配置为 AUTOSAR 经典平台的模型生成符合 AUTOSAR 标准的 C 代码和 ARXML 组件说明,需确保模型的架构版本与 AUTOSAR 标准相匹配。首次导入或为模型选择 AUTOSAR 系统目标文件会将架构版本参数设置为默认值 4.3。导入 ARXML 文件时,公众号发布源码导入程序将检测模式版本并在模型中设置模式版本参数。例如,基于架构 4.3 修订版 4.3.0 或 4.3.1 的导入将设置架构版本参数为 4.3。
生成 AUTOSAR 模型时,代码生成器会导出 ARXML 说明并生成符合当前架构版本的 C 代码。例如,架构版本为 4.3 时,导出将使用架构 4.3(修订版 4.3.1)的导出架构修订版。在导出 AUTOSAR 软件组件前,检查所选架构版本。如有需要更改,可使用模型配置参数为架构版本生成 XML 文件。
最大短名称长度的指定范围为 到 个字符(包括 和 )。默认值为 个字符。使用模型配置参数“最大短名称长度”来设置此值。启用 AUTOSAR 编译器抽象宏可以独立于平台生成编译器指令,这有助于在 位平台上优化代码效率,而无需为每个编译器单独移植源代码。
根级矩阵 I/O 配置允许在生成的 C 代码中保留多维数组的维度,增强代码集成。如果应用设计需要列主数组布局,则可以配置 ARXML 导出以支持根级矩阵 I/O。默认情况下,对于列主阵列布局,软件不允许根级矩阵 I/O。启用此功能,可以指定支持使用一维数组的根级矩阵 I/O。
配置完成 AUTOSAR 代码生成和 XML 选项后,生成代码。通过生成组件模型,将生成符合 AUTOSAR 的 C 代码和 AUTOSAR XML 描述到模型生成文件夹中。生成过程会生成一个或多个型号名称 *.arxml 文件,具体取决于“导出的 XML 文件打包”设置为“单个文件”还是“模块化”。这些文件将包含模型名称、小程序编程源码组件描述和其他相关组件信息。
将 AUTOSAR XML 组件描述合并回 AUTOSAR 创作工具中,以便利用已分区的文件结构进行合并。在 AUTOSAR 创作工具和基于 Simulink 模型的设计环境中,代码生成器保留 AUTOSAR 元素及其通用唯一标识符(UUID),以支持模型的往返传输。
使用 AUTOSAR 4.0 代码替换库,可以生成与 AUTOSAR 标准紧密一致的函数。此代码替换库允许自定义代码生成器以生成兼容 AUTOSAR 标准的 C 代码。在 MATLAB 和 Simulink 查找表索引与 AUTOSAR MAP 索引之间存在差异时,代码替换软件会转置 AUTOSAR MAP 例程的输入参数。浏览支持的 AUTOSAR 库例程并配置代码生成器使用 AUTOSAR 4.0 代码替换库。
为了支持 AUTOSAR 模型的 MATLAB 主机代码验证,AUTOSAR Blockset 提供了 IFX、IFL、MFX 和 MFL 例程的主机实现。使用这些实现作为模型启用软件在环(SIL)验证,而处理器在环(PIL)验证则适用于在生产目标硬件上验证目标代码。
配置并运行模型的 SIL 仿真,以验证生成的 AUTOSAR C 代码。使用测试工具执行相关操作以检查组件模型与生成代码之间的等效性。对于多实例软件组件,可构建配置为多个实例化的 AUTOSAR 软件组件模型,并导入先前版本中的 AUTOSAR 代码进行观察。
在进行 AUTOSAR 代码生成时,需注意以下限制:未选中“仅生成代码”复选框时,生成模型时会提示只有在使用 AUTOSAR 系统目标文件构建可执行文件的情况下才能使用 AUTOSAR 系统目标文件。此外,总线元素尺寸保留在导出的 ARXML 中,并在模型配置为“以行为主”时生成代码。C++ 为 AUTOSAR 自适应应用生成的样式范围枚举类在头文件中生成,以方便集成。
了解这些关键步骤和注意事项后,即可高效地利用 Embedded Coder 和 Simulink 进行基于 AUTOSAR 的代码生成、验证和部署过程。
ä¸è¡ä»£ç 解å³Excelå 容转List
使ç¨POI
ä¸ä¸ªStringæ°ç»ï¼ç¨æ¥åå¨excelåç对åºçmodelçå±æ§
ä¸ä¸ªMap<String,Object>:key为Stringæ°æ®åçå¼ï¼Value为对åºåçå¼
éè¿BeanUtilså°Map转æ¢æBean
1ã使ç¨åå°è·åmodeléé¢çå±æ§ï¼æ·»å å°String[]ãå½ç¶modeléé¢çå段æä¸äºæ¯exceléé¢æ²¡æçï¼é£æä¹åå¢ï¼å½ç¶æ¯Filterï¼è¿æ ·å¯ä»¥å ¼å®¹ææçmodel,åªéè¦æ ¹æ®é¡¹ç®æ åµå®ç°èªå·±çfilterï¼è¿æ»¤æä¸æ³è¦çå段å³å¯ãè¿éæç¹è¦æ³¨æçï¼modeléé¢çå段è¦è·exceléé¢çåç顺åºä¸è´ï¼ä¸ç¶å°±åºç°å¼ å ææ´äºã
2ã使ç¨ValueConvert è¿è¡æ°æ®ç±»åç转æ¢ï¼modeléé¢çå段ä¸å¯è½é£ä¹å·§å ¨é½æ¯Stringãæ以éè¦ä¸ä¸ªæ°æ®ç±»å转æ¢ç±»ï¼æ ¹æ®ä¸å¡éè¦ä½å¯¹åºç转æ¢
æºç Github
linux设备驱动程序——设备树(0)-dtb格式
设备树的一般操作方式是:开发人员根据开发需求编写dts文件,然后使用dtc将dts编译成dtb文件。
dts文件是文本格式的文件,而dtb是二进制文件,在linux启动时被加载到内存中,接下来我们需要来分析设备树dtb文件的格式。
为什么要了解设备树dtb文件的格式
dtb作为二进制文件被加载到内存中,然后由内核读取并进行解析,如果对dtb文件的格式不了解,那么在看设备树解析相关的内核代码时将会寸步难行,而阅读源代码才是了解设备树最好的方式,所以,如果需要更透彻的了解设备树解析的细节,第一步就是需要了解设备树的格式。
dtb格式总览
dtb的格式是这样的:
dtb header
但凡涉及到数据的记录,就一定会有一个总的描述部分,就像磁盘的超级块,书的目录,dtb当然也不例外,这个描述头部就是dtb的header部分,通过这个header部分,用户可以快速地了解到整个dtb的大致信息。
header可以用这么一个结构体来描述:
magic
设备树的魔数,魔数其实就是一个用于识别的数字,表示设备树的开始,linux dtb的魔数为 0xddfeed.
totalsize
这个设备树的size,也可以理解为所占用的实际内存空间。
off_dt_struct
offset to dt_struct,表示整个dtb中structure部分所在内存相对头部的偏移地址
off_dt_strings
offset to dt_string,表示整个dtb中string部分所在内存相对头部的偏移地址
off_mem_rsvmap
offset to memory reserve map,dtb中memory reserve map所在内存相对头部的偏移地址,
version
设备树的版本,截至目前的最新版本为.
last_comp_version
最新的兼容版本
boot_cpuid_phys
这部分仅在版本2中存在,后续版本不再使用。
size_dt_strings
表示整个dtb中string部分的大小
size_dt_struct
表示整个dtb中struct部分的大小
alignment gap
中间的alignment gap部分表示对齐间隙,它并非是必须的,它是否被提供以及大小由具体的平台对数据对齐和的要求以及数据是否已经对齐来决定。
memory reserve map
memory reserve map:描述保留的内存部分,这个map的数据结构是这样的:
这部分存储了此结构的列表,整个部分的结尾由一个数据为0的结构来表示(即physical_address和size都为0,总共字节)。
这一部分的数据并非是节点中的memory子节点,而是在设备开始之前(也就是第一个花括号之前)定义的,例如:
这一部分的作用是告诉内核哪一些内存空间需要被保留而不应该被系统覆盖使用,因为在内核启动时常常需要动态申请大量的内存空间,只有提前进行注册,用户需要使用的内存才不会被系统征用而造成数据覆盖。
值得一提的是,对于设备树而言,即使不指定保留内存,系统也会默认为设备树保留相应的内存空间。
同时,这一部分需要位(8字节)对齐。
device-tree structure
device-tree structure:每个节点都会被描述为一个struct,节点之间可以嵌套,因此也会有嵌套的struct。
structure的的结构是这样的:
device-tree strings
device-tree strings:在dtb中有大量的重复字符串,比如"model","compatile"等等,为了节省空间,将这些字符串统一放在某个地址,需要使用的时候直接使用索引来查看。
需要注意的是,属性部分格式为key = value,key部分被放置在strings部分,而value部分的字符串并不会放在这一部分,而是直接放在structure中。
dtb文件解析示例
光说不练假把式,下面我就使用一个简单的示例来剖析dtb的文件格式。
下述示例仅仅是一个演示demo,不针对任何平台,为了演示方便,编写了一个非常简单的dts文件。 /dts-v1/; / {
编译当前dts文件,获取对应的dtb文件。
鉴于dtb文件为二进制文件,普通编辑器打开显示乱码,我们使用ultraEdit查看,它将数据以进制形式显示:
整个dtb文件还是比较简单的,图中的红色框出的部分为header部分的数据,可以看到:
整个头部为字节,进制为0x,从头部信息中off_mem_rsvmap部分可以得到,reserve memory起始地址为0x,上文中提到,这一部分使用一个字节的struct来描述,以一个全为0的struct结尾。
后字节全为0,可以看出,这里并没有设置reserve memory。
structure 部分
上文回顾:每一个属性都是以 key = value的形式来描述,value部分可选。
偏移地址来到0x(0x+0x),接下来8个字节为,根据上述structure中的描述,这是OF_DT_PROP,即标示属性的开始。
接下来4字节为,表明该属性的value部分size为字节。
接下来4字节是当前属性的key在string 部分的偏移地址,这里是,由头部信息中off_dt_strings可以得到,string部分的开始为,偏移地址为0,所以对应字符串为"compatible".
之后就是value部分,这部分的数据是字符串,可以直接从右侧栏看出,总共字节的字符串"hd,test_dts", "hd,test_xxx",因为字符串之间以0结尾,所以程序可以识别出这是两个字符串。
可以看出,到这里,compatible = "hd,test_dts", "hd,test_xxx";这个属性就被描述完了,对于属性的描述还是非常简单的。
按照固有的规律,接下来就是对#address-cells = <0x1>的解析,然后是#size-cells = <0x1>...
然后就是递归的子节点chosen,memory@等等都是按照上文中提到的structure解析规则来进行解析,最后以结尾。
与根节点不同的是,子节点有一个unit name,即chosen,memory@这些名称,并非节点中的.name属性。
而整个结构的结束由来描述。
一般而言,在位系统中,dtc在编译dts文件时会自动考虑对齐问题,所以对于设备树的对齐字节,我们只需要有所了解即可,并不会常接触到。
好了,关于linux设备树dtb文件格式的讨论就到此为止啦。
什么叫底层代码?
底层代码是指被封装好的代码,底层代码写的就是比较原始,比较基础的代码。底层代码编写是非常接近机器的编程,使用底层开发语言(如C或汇编)。这与使用高级语言(例如Python,Java)的程序员进行编程不同。对于java来说,底层代码一般是指框架的实现代码,这些代码一般都是一些常用代码或比较接近于原始的代码,这些代码封装好,可以方便复用和调用。而对一些操作系统来说,底层代码可能就是c或者汇编,写底层代码就是做底层开发。比如java的Map类,底层代码实现:
扩展资料
编写底层代码一般要比较深厚的功底,对程序设计,代码涉及的各个方面,性能,耦合度,复用性都要很深的掌握和考虑,熟练掌握设计模式,良好的编程习惯,代码优雅,数据结构,精通各种算法。
很多java框架被淘汰,除了本身有致命的bug外,还有就是有性能更好,使用更方便的框架出现,而这些都是靠底层代码实现来决定的。
参考资料:百度百科-底层开发2024-12-22 20:40
2024-12-22 19:49
2024-12-22 19:27
2024-12-22 19:08
2024-12-22 18:54
2024-12-22 18:53