Autosar Nvm模块实战:手把手教你配置ECU数据持久化(含代码示例)

AUTOSAR NvM 基础篇(一) NvM block model 一个block就是以字节为单位的连续的序列,他可以被细分为Data block和CRC block,Data block用于存放user data, CRC block则存放根据userdata算出的对应的checksum。 根据block存放的位置不同,我们可以将block分为以下三种: ►ROM block ► permanent RAM block ► temporary RAM block 如果一个block位于rom,那么他就叫ROM data bloc 阅读详情

Autosar Nvm模块实战:手把手教你配置ECU数据持久化(含代码示例)

如果你正在开发汽车电子控制单元(ECU),并且被那些需要在断电后依然“记住”自己状态的参数所困扰——比如车辆的累计里程、发动机的标定数据、用户自定义的座椅位置,甚至是诊断系统记录的故障码——那么你肯定绕不开AUTOSAR架构中的Nvm模块。这个模块就像是ECU的“长期记忆中枢”,负责将关键数据从易失的RAM搬运到非易失的存储器中,确保下次上电时,系统还能记得之前发生了什么。

然而,对于许多初次接触AUTOSAR的工程师来说,Nvm模块的配置和使用手册往往显得抽象而复杂。各种Block、Job、CRC校验、异步操作等概念交织在一起,让人不知从何下手。本文的目的,就是抛开那些冗长的理论文档,从一个实战开发者的视角,带你一步步搭建一个可用的Nvm数据持久化框架。我们会从最基础的数据块定义开始,深入到配置工具的操作细节,最后给出可以直接集成到项目中的代码示例和排错思路。无论你是负责底层软件配置,还是应用层需要调用Nvm接口,这篇文章都能为你提供一条清晰的路径。

1. 从零开始:理解Nvm模块的核心配置项

在动手写代码之前,我们必须先在配置工具(如Vector的DaVinci Configurator、ETAS的ISOLAR-A等)里把Nvm模块的“骨架”搭好。这个过程决定了数据如何被组织、存储和访问。

1.1 定义你的第一个NvM Block

NvM Block是数据管理的最小逻辑单元。你可以把它理解为一个带有特定格式和属性的“数据包裹”。创建一个Block时,你需要决定以下几件事:

  • Block ID: 这是Block的唯一身份证,通常是一个枚举值。在代码中,我们通过这个ID来指定要读写哪个数据。
  • Block Size: 数据块的大小。这必须和你实际要存储的数据结构体大小严格一致,多一个字节少一个字节都会导致读写错误。
  • RAM Buffer: 这是数据在RAM中的镜像。应用层平时读写操作的都是这个RAM缓冲区。Nvm模块负责将这个缓冲区的内容同步到非易失存储器。
  • NV Storage: 指定数据最终存储在哪种物理介质上,比如内部Flash、外部EEPROM或者Data Flash。这需要和MCAL层的驱动配置相匹配。
  • CRC校验机制: 为了保证数据完整性,几乎每个Block都需要启用CRC校验。Nvm模块在写入时会计算CRC并一起存储,读取时会重新计算并比对,以此发现数据是否损坏。

一个典型的、用于存储车辆里程数据的Block配置可能看起来像这样(以配置工具中的关键参数为例):

配置项示例值说明
NvMBlockDescriptorNvM_Block_0Block的逻辑名称
Block ID0x0101唯一的标识符
Block Size4 (字节)存储一个uint32类型的里程值
RAM Block Address&Odometer_RamBuffer指向RAM缓冲区的指针
NV DeviceFee_Device关联到Flash EEPROM仿真层设备
CRC CalculationCRC-8 或 CRC-16根据数据长度和可靠性要求选择
Immediate WriteFALSE采用延迟写入,减少Flash磨损
Default Data{0x00, 0x00, 0x00, 0x00}出厂默认值(0公里)

注意: Immediate Write(立即写入)选项需要谨慎使用。如果设为TRUE,每次调用NvM_WriteBlock都会立即触发物理存储器的写操作,这对于关键安全数据是必要的,但会显著增加Flash的擦写次数,影响寿命。对于里程、用户设置等非关键数据,建议使用延迟写入,让Nvm模块在后台选择合适的时机批量写入。

1.2 配置NvM与底层驱动的关联

Nvm模块本身并不直接操作硬件。它通过一个叫做Fee (Flash EEPROM Emulation) 或 Ea (EEPROM Abstraction) 的中间层来访问Flash。你需要建立NvM Block与Fee/Ea模块的关联。

  1. 在Fee模块中创建逻辑扇区: 在Fee配置中,你需要定义一个或多个逻辑扇区(Logical Sectors),并指定其大小和所在的物理Flash扇区。这个大小应该能容纳你分配给它的所有NvM Block(包括CRC等管理数据)。
  2. 在NvM中关联Fee设备: 回到NvM配置,为你创建的Block选择对应的Fee设备(如上表中的Fee_Device)。
  3. 配置存储映射: 更精细的配置下,你甚至可以指定某个Block存储在Fee逻辑扇区中的具体偏移地址。不过,通常Fee模块会自动管理Block的存放位置,实现类似“磨损均衡”的效果。

这个关联过程是打通软件逻辑和物理存储的关键一步,配置错误会导致数据根本无法写入或读取。

2. 代码实战:初始化、读写与状态管理

配置完成后,我们进入激动人心的编码环节。这里的所有代码示例都基于AUTOSAR标准API,具有很好的可移植性。

2.1 模块初始化与主函数调用

Nvm模块的初始化必须在操作系统启动后、应用层任务开始前完成。通常放在main函数或一个高优先度的启动任务中。

/* 包含必要的头文件 */
#include "NvM.h"

void System_Init(void) {
    Std_ReturnType ret;

    /* 初始化底层Fee/Flash驱动(略) */
    Fee_Init(&Fee_Config);

    /* 初始化NvM模块,传入配置结构体 */
    ret = NvM_Init(&NvM_ConfigRoot);
    if (ret != E_OK) {
        /* 处理初始化失败,可能记录致命错误或进入安全状态 */
        Debug_Print("NvM_Init failed!");
    }

    /* 启动操作系统... */
}

初始化之后,Nvm模块的异步任务调度需要依靠其MainFunction来驱动。这个函数必须被周期性地调用,例如放在一个1ms或10ms的定时任务中。

void Task_10ms(void) {
    /* 调用NvM主函数,处理队列中的读写任务、触发回调等 */
    NvM_MainFunction();
}

提示: NvM_MainFunction的调用周期需要根据你的系统负载和NvM操作延迟来权衡。调用太频繁可能浪费CPU资源,调用太稀疏则可能导致延迟写入的响应太慢。

2.2 实现数据的写入与读取

假设我们已经配置好了一个Block ID为ODOMETER_BLOCK_ID的里程数据块,并在头文件中定义了对应的RAM缓冲区。

/* 在头文件中定义 */
#define ODOMETER_BLOCK_ID    (0x0101U)
extern uint32 Odometer_RamBuffer; /* 在.c文件中定义 */

/* 应用层代码:更新并保存里程 */
void Odometer_Update(uint32 newDistance) {
    Std_ReturnType writeRet;
    NvM_JobResultType jobResult;

    /* 1. 更新RAM缓冲区 */
    Odometer_RamBuffer = newDistance;

    /* 2. 请求NvM将RAM数据写入非易失存储器 */
    writeRet = NvM_WriteBlock(ODOMETER_BLOCK_ID);
    
    if (writeRet == E_OK) {
        /* 写入请求已成功加入队列 */
        Debug_Print("Odometer write request queued.");
    } else {
        /* 请求失败,立即处理错误(如Block ID无效) */
        Debug_Print("NvM_WriteBlock request failed: %d", writeRet);
        return;
    }

    /* 3. (可选)等待写入完成(轮询方式,适用于简单场景) */
    do {
        NvM_GetJobResult(ODOMETER_BLOCK_ID, &jobResult);
        /* 此处可以添加超时机制,避免无限等待 */
    } while (jobResult == NVM_JOB_PENDING);

    if (jobResult == NVM_JOB_OK) {
        Debug_Print("Odometer saved successfully.");
    } else {
        Debug_Print("Odometer save failed: %d", jobResult);
        /* 可能需要重试或恢复默认值 */
    }
}

/* 应用层代码:上电时读取里程 */
void Odometer_ReadOnStartup(void) {
    Std_ReturnType readRet;
    NvM_ErrorStatusType errorStatus;

    /* 1. 请求NvM从非易失存储器读取数据到RAM缓冲区 */
    readRet = NvM_ReadBlock(ODOMETER_BLOCK_ID);
    
    if (readRet != E_OK) {
        /* 读取请求失败 */
        Odometer_RamBuffer = 0; /* 使用默认值 */
        return;
    }

    /* 2. 检查读取操作的结果和数据的有效性 */
    NvM_GetJobResult(ODOMETER_BLOCK_ID, &jobResult); /* 等待完成,同上 */
    NvM_GetErrorStatus(ODOMETER_BLOCK_ID, &errorStatus);

    if ((jobResult == NVM_JOB_OK) && (errorStatus == NVM_E_OK)) {
        /* 读取成功且数据CRC校验通过 */
        Debug_Print("Odometer read: %lu km", Odometer_RamBuffer);
    } else if (errorStatus == NVM_E_CRC_ERROR) {
        /* 数据校验失败,可能存储器数据损坏 */
        Debug_Print("Odometer data corrupted! Loading default.");
        (void)NvM_RestoreBlockDefault(ODOMETER_BLOCK_ID); /* 恢复默认值 */
    } else {
        /* 其他错误 */
        Debug_Print("Odometer read error. Job: %d, Status: %d", jobResult, errorStatus);
    }
}

2.3 使用回调函数进行异步处理

轮询NvM_GetJobResult的方式虽然简单,但效率较低,且会阻塞任务。更优雅的方式是使用回调函数。这需要在NvM配置中为Block启用回调功能。

/* 在配置工具中为ODOMETER_BLOCK_ID启用回调,并指定回调函数名,例如 `NvM_Odometer_JobEndNotification` */

/* 在代码中实现回调函数 */
void NvM_Odometer_JobEndNotification(NvM_BlockIdType BlockId, NvM_JobResultType JobResult) {
    /* AUTOSAR规范要求此函数为可重入的,避免使用全局变量等非安全操作 */
    if (BlockId == ODOMETER_BLOCK_ID) {
        if (JobResult == NVM_JOB_OK) {
            /* 写入或读取成功 */
            /* 可以设置一个标志位,通知应用层任务 */
            Odometer_SyncFlag = TRUE;
        } else {
            /* 操作失败 */
            Odometer_ErrorFlag = TRUE;
            /* 可以考虑触发恢复机制 */
        }
    }
}

/* 应用层写入代码变得更简洁 */
void Odometer_Update_Async(uint32 newDistance) {
    Odometer_RamBuffer = newDistance;
    Odometer_SyncFlag = FALSE; /* 清除完成标志 */
    (void)NvM_WriteBlock(ODOMETER_BLOCK_ID);
    /* 函数立即返回,不等待。后续由回调函数设置Odometer_SyncFlag */
}

3. 高级话题:多块数据、队列管理与错误恢复

当你的ECU需要管理数十甚至上百个NvM Block时,事情就变得复杂了。你需要考虑写入策略、队列拥塞和复杂的错误恢复场景。

3.1 管理多个相关数据块:使用NvM Multi Block

有时,一组逻辑上紧密关联的数据(比如一个复杂结构体的所有成员)会被拆分成多个NvM Block。AUTOSAR提供了Multi Block的概念来原子化地管理它们。

  • 配置: 在配置工具中创建一个Multi Block,将多个标准的Single Block添加为其成员。
  • 操作: 当你对Multi Block调用NvM_WriteBlock时,NvM模块会保证其所有成员Block要么全部写入成功,要么全部失败(在可能的技术范围内),这有助于维护数据的一致性。
  • 限制: Multi Block的操作是序列化的,可能会比操作单个Block更耗时。

3.2 理解任务队列与优先级

NvM内部维护着一个任务队列(Job Queue)。所有的ReadBlock、WriteBlock、RestoreBlockDefault等请求都会被放入这个队列。NvM_MainFunction负责从队列中取出任务执行。

  • 队列深度: 在配置中有一个NvMQueueSize参数。如果队列满了,新的请求会返回E_NOT_OK。你需要根据系统最大可能并发请求数来设置这个值。
  • 优先级: 每个Block可以配置一个优先级(如NVM_PRIORITY_HIGH)。高优先级的任务会被优先处理。这对于安全相关的关键数据写入非常重要。
  • 写入挂起: 当一个Block的写入请求还在队列中等待或正在执行时,如果又收到同一个Block的新写入请求,后一个请求的行为取决于配置(是覆盖前一个,还是被忽略)。

3.3 构建健壮的错误处理机制

车载环境恶劣,Flash存储器可能出错,电源可能突然中断。你的代码必须能应对这些情况。

  1. CRC校验失败: 这是最常见的错误。处理流程通常是:
    if (NvM_GetErrorStatus(blockId, &errorStatus) == E_OK) {
        if (errorStatus == NVM_E_CRC_ERROR) {
            /* 步骤1:尝试读取备份块(如果配置了冗余存储) */
            /* 步骤2:如果备份也失败,则标记数据块无效 */
            (void)NvM_InvalidateBlock(blockId);
            /* 步骤3:恢复默认值,并尝试写入,以修复该存储位置 */
            (void)NvM_RestoreBlockDefault(blockId);
        }
    }
    
  2. 写入失败(NVM_JOB_FAILED): 可能由于Flash物理损坏、电压不稳等原因。策略可以是:
    • 重试有限次数(例如3次)。
    • 如果重试失败,将数据暂存到另一个健康的Block或区域(如果可用)。
    • 上报诊断事件(DTC),提示需要维护。
  3. 电源中断保护: 这是NvM和底层Fee/Ea模块需要共同解决的问题。它们通常采用以下机制:
    • 原子写入: 对一个数据块的写入操作,即使在电源中断时,也能保证其管理数据(如CRC、状态字)和数据本身不会处于半完成的不一致状态。要么是旧数据,要么是新数据。
    • 冗余存储: 同一份数据存储两份(甚至三份)。读取时进行多数表决,提高可靠性。

4. 调试与验证:让数据持久化可靠运行

配置和代码都写好了,但怎么知道它真的在工作呢?以下是一些实用的调试和验证方法。

4.1 使用调试器与内存视图

这是最直接的方法。在调试环境中:

  1. 在NvM_WriteBlock调用前后设置断点。
  2. 观察对应的RAM缓冲区(如Odometer_RamBuffer)的值是否被正确修改。
  3. 单步执行,确保函数返回E_OK。
  4. 运行NvM_MainFunction若干周期后,通过调试器的内存查看窗口,直接查看Flash或EEPROM映射的地址区域,确认数据是否已被写入物理存储器。你需要对照芯片手册和Fee配置,找到正确的地址。

4.2 注入故障进行测试

为了验证错误处理逻辑,你需要模拟错误。

  • 模拟CRC错误: 在调试器中,手动修改Flash中某个Block的数据区或CRC区,制造一个CRC校验错误。然后触发读取操作,观察你的代码是否正确地进入了NVM_E_CRC_ERROR的处理分支,并恢复了默认值。
  • 模拟写入失败: 这比较困难,但可以通过Hook底层Fee的写函数,让其返回错误码,来测试上层NvM和应用层的反应。
  • 电源循环测试: 在数据写入过程中(特别是NvM_MainFunction正在处理队列时),直接给ECU断电再上电。检查上电后,之前正在写入的数据是否处于有效且一致的状态(要么是旧值,要么是新值,不能是损坏的值)。

4.3 关键日志与跟踪

在生产代码中植入详细的日志输出,是定位线上问题的关键。

void NvM_Odometer_JobEndNotification(...) {
    Log_Write("NvM CB: Block=0x%04X, Result=%d", BlockId, JobResult);
    /* ... */
}

/* 在应用层调用处也添加日志 */
Log_Write("Req Write Odometer: %lu", newDistance);

通过分析这些日志的时间戳和顺序,你可以清晰地看到NvM任务的排队、执行、完成的全过程,对于诊断偶发的写入超时或顺序错乱问题非常有帮助。

配置和使用AUTOSAR Nvm模块确实是一个需要耐心和细致的工作,它涉及从配置工具到应用代码的整个链条。我自己的经验是,在项目早期就建立一个简单的、包含完整“配置-写入-读取-错误处理”流程的测试工程,反复验证。这样当后期复杂功能叠加时,你能快速判断问题是出在NvM配置、底层驱动还是应用逻辑上。记住,数据持久化的可靠性直接关系到车辆的功能和用户体验,多花时间在前期设计和测试上,绝对物有所值。

AUTOSAR存储栈详解与应用:NvM、MemIf、Fee模块实践 存储栈的主要作用是管理ECU内部的非易失性数据,确保数据在上电和下电周期中能够持久化存储。本文详细介绍了AUTOSAR存储栈的三个关键模块:NvM、MemIf和Fee,并通过实例代码展示了它们在实际项目中的应用。存储栈的设计为汽车ECU的软件开发提供了强大的数据持久化支持,有助于提高软件的可靠性和可维护性。✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进❤欢迎关注我的知乎:对error视而不见代码获取、问题探讨及文章转载可私信。☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。👇。 阅读详情

相关推荐

Autosar Nvm模块

AUTOSAR NVM模块负责ECU非易失性数据管理,提供数据持久化与可靠性保障。核心功能包括:1)数据块读写(通过NvM_WriteBlock/ReadBlock实现RAM与存储器的同步);2)数据一致性维护(CRC校验、版本管理);3)存储器抽象(屏蔽硬件差异);4)支持立即/延迟写入模式。模块通过标准API(如NvM_InvalidateBlock处理错误,NvM_GetJobResult查询状态)提供服务,确保关键数据(标定参数、故障码等)的安全存储。

qq_39675344的博客 832

Autosar NvM 详解

一、AutoSAR Memory Stack整体概述前言 在AutoSAR架构除了横向看包含APP/RTE/BSW/MCAL等分层架构之外,对于BSW(包含MCAL)对纵向的不同功能协议栈也作了详细的划分,主要包括通信栈、内存栈、CDD、IO操作相关的纵向栈、系统服务栈、信息安全相关的协议栈,今天介绍的NvM属于内存栈的管理模块,整个内存栈在AutoSAR的定义如下所示: 在内存栈中包含服务层(NvM)、抽象层(MemIf、EA、EEP、Fee)、MCAL(Fls、SPI等)几个模块。 AutoS

king110108的专栏 1万+

AUTOSAR NvM模块实战:手把手教你配置Native/Redundant/Dataset三种Block

本文深入解析AUTOSAR NvM模块中Native、Redundant、Dataset三种Block的配置实践与避坑指南。通过Vector Davinci Configurator工具链,详细讲解各类Block的配置逻辑、CRC校验、冗余机制及多套数据管理方案,帮助开发者提升ECU数据存储的可靠性与性能。特别针对汽车电子系统中的严苛环境,提供数据完整性保障与调试技巧。

weixin_30697239的博客 591

AUTOSAR学习笔记_NVM详解

AUTOSAR学习笔记_NVM详解

daizhifeng123468的博客 8551

AUTOSAR BswM模块的‘隐藏关卡’:与NVM模块联调时,如何确保ECU下电不掉数据?

本文深入探讨了AUTOSAR BswM模块与NVM模块联调时确保ECU下电不掉数据的关键技术。通过分析BswM与NVM的深度握手机制、多模块协同时序设计及故障模式防护策略,揭示了如何构建数据持久化的最后防线,有效降低数据丢失概率,提升系统可靠性。

weixin_33690963的博客 431

汽车ECU开发必看:AUTOSAR存储管理模块NvM的5个实战技巧

本文聚焦汽车ECU开发中AUTOSAR存储管理模块NvM的实战应用,分享了五个源自量产项目的核心技巧。内容涵盖Class 3配置的精细调优、稳健冗余策略的构建、读写性能的毫秒级优化、典型工程问题的解决方案以及高效的集成测试方法,旨在帮助开发者规避常见陷阱,实现可靠、高效的存储方案。

weixin_29192211的博客 277

Classic AUTOSAR深入浅出系列 - 【第四篇-F】NVRAM Manager(NvM)与持久化配置

NVRAM Manager(NvM)与持久化配置 NvM是AUTOSAR中管理非易失性存储的核心模块,解决ECU数据持久化问题。它通过抽象NvM Block概念,将"物理存储"转化为"语义化数据管理",提供: 安全机制:CRC校验、冗余存储、掉电保护 写入策略:延迟写、批量写、条件触发 恢复方案:ROM默认值、多副本恢复 典型应用流程: 应用仅操作RAM镜像 NvM控制实际写入时机 系统安全状态时批量写入 异常时自动恢复数据 相比直接操作Flash,NvM提供了量产级

yuanmenghao 1620

核心要点解析AUTOSAR软件开发中的NVM模块

深入剖析AUTOSAR软件开发中NVM模块的工作机制与设计要点,帮助开发者理解数据持久化存储的关键实现方式,提升系统可靠性与配置管理效率。

weixin_42502040的博客 1117

当数据有了记忆:AUTOSAR NvM如何守护ECU的“数字灵魂”

本文深入探讨AUTOSAR NvM(非易失性存储管理器)在ECU中的核心作用,解析其如何通过分层架构、数据校验与冗余机制,确保配置参数等关键数据的可靠存储与生命周期管理。NvM是车辆个性化设置与自适应学习功能的基石,守护着ECU的“数字灵魂”。

moon9的博客 559

通俗解释AUTOSAR网络管理中Nvm配置相关策略

深入浅出讲解AUTOSAR网络管理中与Nvm相关的配置策略,帮助开发者理解节点状态保持与恢复机制,提升系统可靠性与通信效率。

weixin_42327217的博客 684

AutoSAR配置与实践(实践篇)13.6 如何添加一个NVM BLOCK (PIM类型)

NvM提供了NvM_ReadPRAMBlock/NvM_WritePRAMBlock一对API可以对这个固定地址(永久地址)的RAM块进行读写操作。配置这样的地址,我们称之为PerInstanceMemory(PIM),它存在于RTE中,SWC可以通过Rte_Pim接口访问。与Nv Block Descriptor类型的差异在于PIM类型适用于单个SWC访问,而Descriptor类型一般是多个SWC共同访问一个Block。两种类型的优劣势在之前有介绍,不清楚的可以回头看看7.5章节的介绍。

nihaoljq2010的博客 2118

AUTOSAR图解==>AUTOSAR_SWS_NVRAMManager

AUTOSAR非易失性存储器管理器(NvM)是AUTOSAR标准架构中的一个关键基础软件模块,负责管理和抽象ECU中的非易失性存储器访问。它为上层应用软件提供统一的接口来存储和检索持久性数据,同时屏蔽了底层存储介质(如EEPROM或Flash)的具体细节。数据持久化:在ECU关闭后保持数据数据完整性:通过CRC校验确保数据完整性抽象接口:提供统一API,屏蔽底层实现差异块管理:支持多种类型的数据块管理方式作业处理:提供异步处理机制和优先级队列错误处理:提供完善的错误检测与报告机制。

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 2615

AutoSAR配置与实践(深入篇)7.5 NVM架构、存储形式及隐式显式同步

模块简介:全称NVRAM Manager ,存储服务管理模块。主要提供抽象数据存储,在上电读取下电存储数据,支持Immediately存储数据,将 NV data在ROM和RAM之间建立关联。全称Memory Abstraction Interface,存储抽象接口模块。实现存储数据Block在内部Flash或者外部EEP的分离操作。全称Flash EEPROM EMULATION,FLASH模拟模块。FEE实现对Flash的数据Block的抽象和动态数据的Layout。

nihaoljq2010的博客 4696

AUTOSAR CP NvM 模块解析

摘要:AUTOSAR架构中的NvM模块是汽车电子系统的关键组件,负责非易失性数据存储管理。该模块采用分层设计,实现上层应用与底层存储硬件的解耦,支持多种数据块类型(Native、Redundant、Dataset)和三级API配置。其核心功能包括数据持久化、错误恢复、安全保护(CRC校验、加密等)及两种同步机制。开发中需注意读写性能优化、数据安全及布局变更等问题。NvM模块通过标准化接口简化了存储管理,提升了软件的可靠性和可移植性。(149字)

autosar_org的博客 802

Arxml文件可视化:当汽车软件架构遇见交互式设计工具

本文探讨了Arxml文件在汽车电子系统开发中的可视化技术,结合AUTOSAR架构标准,介绍了如何利用现代Web技术构建交互式设计工具。通过三维组件关系图、动态数据流展示和版本对比等功能,显著提升开发效率和架构评审质量,适用于MBD和ASPICE开发流程。

weixin_29050271的博客 429

SAP资产按每天折旧功能介绍

注意:此处在计算百分比时将30天作为剩余使用寿命,因为SAPS/4HANA中的计算是通过考虑购置第一年的折旧总天数来进行的。这是因为我在计算总使用寿命时只使用了365天,如果剩余使用寿命大于1年,SAPS/4HANA会将闰年规范化为365天。此功能仅对确定使用寿命或剩余寿命百分比的折旧键有用,如果需要,这种折旧到日的解决方案可以应用于需要每天计算折旧的跨行业(任何国家/行业)。注意:这里在计算百分比时考虑了2天,因为364天已经过期,但目前我们到达2024年,使用寿命为366天。它只会在下一年生效。

yanzibing99的博客 1562

深入理解AUTOSAR模式管理:BswM如何协同DCM、NVM实现ECU状态安全切换

本文深入解析AUTOSAR模式管理中BswM模块如何与DCM、NVM协同工作,确保ECU状态安全切换。通过分析通信模式切换、NVM操作同步等核心机制,揭示BswM在整车电子架构中的仲裁逻辑设计要点,帮助开发者实现符合功能安全要求的ECU状态管理方案。

weixin_30316097的博客 391

主流算力卡性能对比分析

超大规模AI训练/HPC:优先选择NVIDIA H100或AMD MI300X,需关注显存带宽和多卡互联能力。企业级AI训练:NVIDIA A100性价比更高,生态成熟。国内自主可控需求:华为昇腾910B是首选,支持液冷和低功耗设计。本地AI推理/游戏:NVIDIA RTX 4090或RTX 5090性价比突出,但需注意显存容量限制。边缘计算/低功耗场景:华为昇腾310或清微智能TX536(能效比6.3TOPS/W@INT8)更合适。

m0_69867914的博客 7809

[AutoSar]BSW_Memory_Stack_007 FEE 模块介绍

[AutoSar]BSW_Memory_Stack_007 FEE 模块介绍

汽车-嵌入式-工作笔记-autosar 3618

攻克JESD204B多ADC同步:从时钟对齐到数据对齐的实战解析

本文深入解析了JESD204B多ADC同步的系统性挑战与实战解决方案。从确保设备时钟同源、精确捕获SYSREF信号,到管理接收端弹性缓冲区与释放点,文章提供了从时钟对齐到数据对齐的完整调试路径与排查清单,是攻克高速数据采集系统中多片ADC同步难题的实用指南。

weixin_29231725的博客 197

Ubuntu下安装Hive3.1.2教程(附MySQL安装方法及安装包)

文章目录前言一、安装Hive1. 下载压缩包并解压2. 安装Hive3. 配置环境变量4. 修改配置文件二、MySQL安装与配置1. 安装MySQL2. 安装MySQL jdbc包3. 为Hive创建MySQL账号三、验证Hive安装及错误处理1. 启动Hadoop2. 启动hive3. 运行Hive实例总结 前言 Hive 的安装需要建立在 Hadoop 的之上(类似于Hbase),关于 Hadoop 的单机安装以及伪分布式安装可以参考作者的另两篇博客: Ubuntu下单机安装Hadoop详细教程(附

程序必须为人类阅读而编写,并且仅仅碰巧可以让机器执行 1万+
上一篇: Perforce+Docker+CentOS三件套:新手避坑指南与权限配置全解析
下一篇: Cisco Packet Tracer(思科模拟器)入门指南--从零开始搭建网络拓扑
人间清醒863
博客等级 码龄3年 33粉丝 1544原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值