在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

NVM Block連續寫及Default Value問題分析

832065824 ? 來源:汽車電子嵌入式 ? 2023-07-25 14:22 ? 次閱讀

前言

NVM這塊還只停留在按需求配置階段,遇到問題不能深入分析。本系列文章將從遇到的問題或者提出的疑問著手,一起來更深入學習AUTOSAR架構下的存儲協議棧。目前遇到的問題和疑問如下:

1.通過RTE接口連續讀寫NVMBlock會影響其他Block的讀寫嗎?

2.沒有配置NVMRom Block的default value且沒有寫過NVM Block,通過RTE接口去讀NVMBlock讀到的是什么值?

3.Fee模塊中的Block的長度更改會造成NVM Block在Flash中重排嗎?中間插入NVMBlock了?

本文使用的AUTOSAR配置工具為:Vector公司的Davinci工具

正文

1.應用SWC讀寫NVMBlock的兩種方式

入下圖所示,Vector的AUTOAR配置工具Davinci Developer提供兩種方式配置SWC使用NVM的服務。

方式一:SWC和NVM直連。NVM提供5個標準接口供SWC使用,SWC可以直接通過C-S接口直接讀寫NVMBlock。這種方式適用于NVMBlock僅被一個SWC訪問的場景

209011d6-2a7f-11ee-a368-dac502259ad0.png

圖1:SWC和NVM直連

如下圖所示,在Developer中直接配置SWC中的Service Need的NvM_Block_NeeDs即可配置NVM服務。

2103632a-2a7f-11ee-a368-dac502259ad0.png

圖2:配置NvMBlockNeed

最后在Rte_SWC.h生成的讀寫NvM_Block的接口如下所示,Rte接口直接封裝了NvM的標準接口(NvM_ReadBlock, NvM_WriteBlock, NvM_GetErrorStates)。

# define Rte_Call_NvMService_AC3_SRBS_NvBlockNeed_ PortName _GetErrorStatus(arg1) (NvM_GetErrorStatus((NvM_BlockIdType)57, arg1))
# define Rte_Call_NvMService_AC3_SRBS_NvBlockNeed_ PortName _ReadBlock(arg1) (NvM_ReadBlock((NvM_BlockIdType)57, arg1))
# define Rte_Call_NvMService_AC3_SRBS_NvBlockNeed_ PortName _WriteBlock(arg1) (NvM_WriteBlock((NvM_BlockIdType)57, arg1))

方式二:SWC通過NonvolatileMemoryBlock訪問NVM。Davinci提供一個類似NvM User的NonvolatileMemoryBlock的中間模塊,SWC配置普通的S-R接口和NonvolatileMemoryBlock連接,NonvolatileMemoryBlock模塊通過標準的S-R接口和NvM連接。SWC通過NonvolatileMemoryBloc來讀寫NvM模塊。這種方式適用于多個SWC訪問同一個NvM Block的場景

213708f6-2a7f-11ee-a368-dac502259ad0.png

圖3:SWC通過NonvolatileMemoryBlock訪問NVM

如下圖所示,使用方式二需要配置中間NonvolatileMemoryBlock模塊,然后在SWC和NonvolatileMemoryBlock分別配置S-R的讀寫接口,然后進行連接即可。

217557c8-2a7f-11ee-a368-dac502259ad0.png

圖4:配置NoVolatileMemoryBlock

如下所示,生成的Rte_SWC.h中SWC讀寫NvM Block的接口僅僅是讀寫一個名為Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName全局變量。

FUNC(Std_ReturnType, RTE_CODE) Rte_Read_SWC_Pp_NvData_PortName_Rx_Element_NvData_PortName(P2VAR(uint8, AUTOMATIC, RTE_SWC_APPL_VAR) data) /* PRQA S 1505, 3206 */ /* MD_MSR_Rule8.7, MD_Rte_3206 */
{
  Std_ReturnType ret = RTE_E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */
  Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
  Rte_MemCpy(data, Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName, sizeof(NvData_PortName)); /* PRQA S 0314, 0315, 0316 */ /* MD_Rte_0314, MD_Rte_0315, MD_Rte_0316 */
  Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
  return ret;
}




FUNC(Std_ReturnType, RTE_CODE) Rte_Write_SWC_Pp_NvData_PortName_Tx_Element_NvData_PortName(P2CONST(uint8, AUTOMATIC, RTE_SWC_APPL_DATA) data) /* PRQA S 1505, 2982 */ /* MD_MSR_Rule8.7, MD_Rte_2982 */
{
  Std_ReturnType ret = RTE_E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */
  Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
  Rte_MemCpy(Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName, data, sizeof(NvData_PortName)); /* PRQA S 0314, 0315, 0316 */ /* MD_Rte_0314, MD_Rte_0315, MD_Rte_0316 */
  Rte_OsApplication_QM_Core0_DirtyFlags.Rte_DirtyFlag_NonVolatileMemoryBlock_NVBlockDescriptor_PortName = 1U;
  Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
  /* scheduled trigger for runnables: NonVolatileMemoryBlockTriggerRunnable */
  (void)SetEvent(AplTask_10ms_Core0, Rte_Ev_Run_NonVolatileMemoryBlock_NonVolatileMemoryBlockTriggerRunnable); /* PRQA S 3417 */ /* MD_Rte_Os */
  return ret;
}

然后NvM也通過Rte_SetMirror_xxx/Rte_GetMirror_xxx接口來更新這個Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName全局變量。


FUNC(Std_ReturnType, RTE_CODE) Rte_SetMirror_NonVolatileMemoryBlock_NVBlockDescriptor_PortName(P2CONST(void, AUTOMATIC, RTE_APPL_DATA) NVMBuffer) /* PRQA S 3112 */ /* MD_Rte_3112 */
{
  Std_ReturnType ret = E_NOT_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */
  CONST(uint16_least, RTE_CONST) size = sizeof(NvData_PortName);
  if (size <= 100U) /* PRQA S 2991, 2995 */ /* MD_Rte_2991, MD_Rte_2995 */ /* COV_RTE_NVMBUFFER_SIZE */
  {
    Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
    Rte_MemCpy32(Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName, NVMBuffer, size); /* PRQA S 0314, 0315, 0316 */ /* MD_Rte_0314, MD_Rte_0315, MD_Rte_0316 */
    Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
    ret = E_OK;
    }
  return ret;
}


FUNC(Std_ReturnType, RTE_CODE) Rte_GetMirror_NonVolatileMemoryBlock_NVBlockDescriptor_PortName(P2VAR(void, AUTOMATIC, RTE_APPL_VAR) NVMBuffer) /* PRQA S 3112 */ /* MD_Rte_3112 */
{
???Std_ReturnType?ret?=?E_NOT_OK;?/*?PRQA?S?2981?*/?/*?MD_MSR_RetVal?*/
  CONST(uint16_least, RTE_CONST) size = sizeof(NvData_PortName);
  if (size <= 100U) /* PRQA S 2991, 2995 */ /* MD_Rte_2991, MD_Rte_2995 */ /* COV_RTE_NVMBUFFER_SIZE */
  {
  Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
  Rte_MemCpy32(NVMBuffer, Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName, size); /* PRQA S 0314, 0315, 0316 */ /* MD_Rte_0314, MD_Rte_0315, MD_Rte_0316 */
  Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
  ret = E_OK;
  }
  return ret;
}

2.RAMBlock和ROMBlock

RAMBlock最后在代碼中體現就是一個全局變量(存放在棧Ram中),ROMBlock在代碼中體現就是一個const 全局變量(存放在Data Flash中)。RamBlock是一定會有的,Rom Block是可配置的。其中最主要的就是default value的配置。

方式1配置RAMBlock和ROMBlock:

方式1是SWC通過NvM Block Needs直接訪問NvM,如果配置了Default Value就配置了ROMBlock。

21af5d24-2a7f-11ee-a368-dac502259ad0.png

圖5:NvM Block Needs配置RAM和ROM Block

方式2配置RAMBlock和ROMBlock:

方式2是SWC通過NonvolatileMemoryBlock間接訪問NvM,Rom Block通過勾選來配置,InitValue也就是Default value也可配置。

21e64d0c-2a7f-11ee-a368-dac502259ad0.png

圖5:NonvolatileMemoryBlock配置RAM和ROM Block

RAMBlock對應的代碼:

VAR(Nvdata_PortName, RTE_VAR_INIT) Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName;

ROMBlock對應的代碼:

CONST(Nvdata_PortName, RTE_CONST_DEFAULT_RTE_CDATA_GROUP) Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName_ROM_NVBlockDescriptor_PortName = {
0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U
};

關于Default Value:

22117446-2a7f-11ee-a368-dac502259ad0.png

如SWS_NvM_00388所訴,在ECU啟動階段,如果配置了ROMBlock,NvM_ReadAll會把ROMblock中的default value拷貝到RAMBlock。

22411eb2-2a7f-11ee-a368-dac502259ad0.png

如SWS_NvM_00085所述,如果沒有配置ROMBlock,則RAMBlock的值需要應用來保證。在Davinci Developer中可以配置RAM Block的Init Value,也可以讓RAMBlock有一個初始值。

如果,我們既沒有配置RAMBlock的Initvalue,也沒有配置ROMBlock,也從沒有寫過NvBlock,那么我們第一次去讀的RAMBlock是.BSS段的一個全局變量(未初始化的全局變量在.BSS段),而MCU上電后會對.BSS段作清零的操作,也就是說我們會讀到0。

3. 應用SWC讀寫NVM過程

SWC通過NonvolatileMemoryBlock讀NvM Ram Block:SWC就是讀一個名為Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName的全局變量,也就是RAMBlock。

FUNC(Std_ReturnType, RTE_CODE) Rte_Read_SWC_Pp_NvData_PortName_Rx_Element_NvData_PortName(P2VAR(uint8, AUTOMATIC, RTE_SWC_APPL_VAR) data) /* PRQA S 1505, 3206 */ /* MD_MSR_Rule8.7, MD_Rte_3206 */
{
  Std_ReturnType ret = RTE_E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */
  Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
  Rte_MemCpy(data, Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName, sizeof(NvData_PortName)); /* PRQA S 0314, 0315, 0316 */ /* MD_Rte_0314, MD_Rte_0315, MD_Rte_0316 */
  Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
  return ret;
}

SWC通過NonvolatileMemoryBlock寫NvM Ram Block:SWC就是寫一個名為Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName的全局變量,也就是RAMBlock。同時會設置一個更新Flag,SetEvent觸發一個OSTask事件。

FUNC(Std_ReturnType, RTE_CODE) Rte_Write_SWC_Pp_NvData_PortName_Tx_Element_NvData_PortName(P2CONST(uint8, AUTOMATIC, RTE_SWC_APPL_DATA) data) /* PRQA S 1505, 2982 */ /* MD_MSR_Rule8.7, MD_Rte_2982 */
{
  Std_ReturnType ret = RTE_E_OK; /* PRQA S 2981 */ /* MD_MSR_RetVal */
  Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
  Rte_MemCpy(Rte_NonVolatileMemoryBlock_NVBlockDescriptor_PortName, data, sizeof(NvData_PortName)); /* PRQA S 0314, 0315, 0316 */ /* MD_Rte_0314, MD_Rte_0315, MD_Rte_0316 */
  Rte_OsApplication_QM_Core0_DirtyFlags.Rte_DirtyFlag_NonVolatileMemoryBlock_NVBlockDescriptor_PortName = 1U;
  Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
  /* scheduled trigger for runnables: NonVolatileMemoryBlockTriggerRunnable */
  (void)SetEvent(AplTask_10ms_Core0, Rte_Ev_Run_NonVolatileMemoryBlock_NonVolatileMemoryBlockTriggerRunnable); /* PRQA S 3417 */ /* MD_Rte_Os */
  return ret;
}

NonvolatileMemoryBlock的Runnable被Event事件激活調用NvM_WriteBlock:

RTE_LOCAL FUNC(void, RTE_CODE) NonVolatileMemoryBlockTriggerRunnable(void)
{
  if (Rte_OsApplication_QM_Core0_DirtyFlags.Rte_DirtyFlag_NonVolatileMemoryBlock_NVBlockDescriptor_PortName == 1U)
  {
    NvM_RequestResultType NvM_ErrorStatus = 0;
    (void)NvM_GetErrorStatus(NvMConf_NvMBlockDescriptor_NonVolatileMemoryBlockNVBlockDescriptor_PortName, &NvM_ErrorStatus);
    if (NvM_ErrorStatus != NVM_REQ_PENDING)
  {
    Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
    Rte_OsApplication_QM_Core0_DirtyFlags.Rte_DirtyFlag_NonVolatileMemoryBlock_NVBlockDescriptor_PortName = 0;
    Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
    (void)NvM_WriteBlock(NvMConf_NvMBlockDescriptor_NonVolatileMemoryBlockNVBlockDescriptor_PortName, NULL_PTR);
  }
  else
  {
    Rte_DisableOSInterrupts(); /* PRQA S 1881, 4558 */ /* MD_Rte_Os, MD_Rte_Os */
    Rte_NvBlockPendingFlags.Rte_NvBlockPendingFlag_NonVolatileMemoryBlock_NVBlockDescriptor_PortName = 1U;
    Rte_EnableOSInterrupts(); /* PRQA S 1881, 4558, 2983 */ /* MD_Rte_Os, MD_Rte_Os, MD_Rte_2983 */
    }
  }
}

NvM_WriteBlock調用NvM_QueueJob將Job排隊:

FUNC(Std_ReturnType, NVM_PUBLIC_CODE) NvM_WriteBlock(NvM_BlockIdType BlockId, P2CONST(void, AUTOMATIC, NVM_APPL_DATA) NvM_SrcPtr)
{
    Std_ReturnType returnValue = E_NOT_OK;
    uint8 detErrorId = NVM_E_NO_ERROR;


    const NvM_RamMngmtPtrType NvM_RamMngmt_ptloc = NvM_GetMngmtAreaPtr(BlockId);
    if(NvM_WriteProtectionChecks(NvM_RamMngmt_ptloc) == TRUE) /* SBSW_NvM_FuncCall_PtrParam_BlockMngmtArea */
    {
    /* PRQA S 0311, 0316 1 */ /* MD_NvM_11.5_CastLossOfConst, MD_NvM_11.5_JobQueue_CastVoidPtrToObjPtr */
    if (NvM_QueueJob(BlockId, NVM_INT_FID_WRITE_BLOCK, (NvM_RamAddressType)NvM_SrcPtr)) /* SBSW_NvM_FuncCall_PtrParam_QueueJob */
    {
if(NvM_SrcPtr==NULL_PTR)
    {
NvM_EnterCriticalSection();
NvM_RamMngmt_ptloc->NvRamAttributes_u8|=(NVM_STATE_VALID_SET|NVM_STATE_CHANGED_SET);/*SBSW_NvM_AccessBlockManagementArea*/
NvM_ExitCriticalSection();
    }
    returnValue = E_OK;
  }
}


return returnValue;
} 

NvM_QueueJob會判斷隊列是否已經Full,如果Full則Job被丟棄,如果沒有Full,則Job入隊列:

FUNC(boolean, NVM_PRIVATE_CODE) NvM_QueueJob(NvM_BlockIdType BlockId,
NvM_InternalServiceIdType ServiceId,
NvM_RamAddressType RamAddress
)
{
  boolean retVal = FALSE;
  boolean queueFull;
  boolean blockAlreadyPending;
  /* get block management area */
  const NvM_RamMngmtPtrType ramMngmtPtr =
  ((BlockId & NVM_DCM_BLOCK_OFFSET) != 0u) ? (&NvM_DcmBlockMngmt_t) : (&NvM_BlockMngmtArea_at[BlockId]);
  #if(NVM_JOB_PRIORISATION == STD_ON)
  const uint8 priority = (uint8)NvM_BlockDescriptorTable_at[NVM_BLOCK_FROM_DCM_ID(BlockId)].BlockPrio_u8;
  /* NvM_HighPrioQueue is only the right queue if block has an immediate priority, current job is a
  write-job and requested block is not a DCM-Block. Otherwise NvM_NormalPrioQueue is right queue. */
  P2VAR(NvM_JobQueueType, AUTOMATIC, NVM_PRIVATE_DATA) usedQueue =
  ((priority == 0u) && (ServiceId == NVM_INT_FID_WRITE_BLOCK) && ((BlockId & NVM_DCM_BLOCK_OFFSET) == 0u)) ?
  (&NvM_HighPrioQueue) : (&NvM_NormalPrioQueue);
  #else
  P2VAR(NvM_JobQueueType, AUTOMATIC, NVM_PRIVATE_DATA) usedQueue = &NvM_NormalPrioQueue;
  #endif
  /* #200 critical section (Reason: During accessing the job queue, it shall not be possible to access it from another task) */
  NvM_EnterCriticalSection();
  /* check queue fill status before queuing the block! */
  queueFull = (usedQueue->EmptyList == NVM_LIST_END);
  blockAlreadyPending = (ramMngmtPtr->NvRamErrorStatus_u8 == NVM_REQ_PENDING);
  /* #210 queue is not full and the requested block isn't already pending */
  if((queueFull == FALSE) && (blockAlreadyPending == FALSE))
  {
    /* #211 find next free element in queue */
    const NvM_QueueEntryRefType elem = NvM_QueuePop(&usedQueue->EmptyList); /* SBSW_NvM_FuncCall_PtrParam_Queue */
    CONSTP2VAR(NvM_QueueEntryType, AUTOMATIC, NVM_PRIVATE_DATA) elemPtr = &NvM_JobQueue_at[elem];
    /* #212 setup and queue NvM job */
    elemPtr->BlockId   = BlockId; /* SBSW_NvM_AccessJobQueue */
    elemPtr->RamAddr_t = RamAddress; /* SBSW_NvM_AccessJobQueue */
    elemPtr->ServiceId = ServiceId; /* SBSW_NvM_AccessJobQueue */
    #if(NVM_JOB_PRIORISATION == STD_ON)
    elemPtr->JobPrio = priority; /* SBSW_NvM_AccessJobQueue */
    #endif
    NvM_QueuePush(&usedQueue->SrvList, elem); /* SBSW_NvM_FuncCall_PtrParam_Queue */
    /* #213 set the block status to NVM_REQ_PENDING */
    ramMngmtPtr->NvRamErrorStatus_u8 = NVM_REQ_PENDING; /* SBSW_NvM_AccessBlockManagementArea */
    /* block queued and pending, return successfully */
    retVal = TRUE;
    }
  return retVal;
}

綜上所述,SWC讀寫NvM接口的時候,其實讀寫的是一個Ram Block的全局變量。調用寫NvM的接口時會觸發NonvolatileMemoryBlock的NonVolatileMemoryBlockTriggerRunnableOs調用,NonVolatileMemoryBlockTriggerRunnable根據Block的寫Flag調用NvM_WriteBlock,NvM_WriteBlock中調用NvM_QueueJobNvM_QueueJob根據隊列是否Full來將Job入隊列。

也就是說,如果有SWC一直在頻繁的調用寫NvM的接口,就會導致NvM的隊列Full,導致其他的SWC的寫NvM Block的請求被丟棄,最終對外表現是NvM存不進去。

Ps: 本人就遇到過隊列大小配的太小,導致SWC的NvM寫請求被丟棄的問題。。。

4. 問題回答

問題1:通過RTE接口連續讀寫NVMBlock會影響其他Block的讀寫嗎?

答:會。如果SWC連續寫NvM Block,且NvM模塊的隊列大小配置太小,就會導致NvM模塊的隊列Full后SWC的寫請求被丟棄。

問題2:沒有配置NVMRom Block的default value且沒有寫過NVM Block,通過RTE接口去讀NVMBlock讀到的是什么值?

答:要看有沒有配置NvM Ram Block的InitValue。如果配置NvM Ram Block的InitValue,那么讀到的就是NvM Ram Block的InitValue,如果沒有配置,讀到的就是0。

問題3:Fee模塊中的Block的長度更改會是的NVM Block在Flash中重排嗎?中間插入NVMBlock了?

答:還沒研究透徹,請關注本公眾號的后續文章。

5.總結

搞清楚了NVM的基本概念后,配置都比較容易。難的是出現問題后怎么查問題,因為NvM和Fee/EA,Fls/EEProm模塊的實現還是很復雜的,常見的問題如下:

nSWC開發者抱怨NvM數據存不進去

nSWC開發者抱怨NvM數據在ECU復位變成了默認值

nSWC開發者抱怨NvM數據在ECU復位后改成了異常值

如果,存儲協議棧配置本身沒有問題,常見的原因如下:

nNvM隊列配置太小,以及SWC在頻繁的請求寫NvM

nSWC在下電前把自己的Block寫成了默認值,這個時候,我們可以通過修改NvM Block的Default Value為另一個值來證明不是NvM本身的問題,是SWC自己寫了個Default value。

n用來接收NvM讀數據的SWC的全局變量復位后并不是直接從NvM讀取數據,而是從Back Ram(復位后內容不清除)中讀取數據,Back Ram異常后導致接收NvM數據的全局變量內容錯亂。

如果不是以上的問題,那就可能是NvM本身或者ECU系統出問題了,這就需要深入分析NvM源碼加調試了。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • RAM
    RAM
    +關注

    關注

    8

    文章

    1386

    瀏覽量

    116516
  • AUTOSAR
    +關注

    關注

    10

    文章

    370

    瀏覽量

    22328
  • ecu
    ecu
    +關注

    關注

    14

    文章

    911

    瀏覽量

    55349
  • NVM
    NVM
    +關注

    關注

    1

    文章

    42

    瀏覽量

    19314
  • Flash單片機
    +關注

    關注

    0

    文章

    111

    瀏覽量

    9640

原文標題:AUTOSAR架構下NVM Block連續寫及Default Value問題分析

文章出處:【微信號:汽車電子嵌入式,微信公眾號:汽車電子嵌入式】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    NVRAM Manager(NVM)模塊詳細介紹

    存儲協議棧負責ECU中非易失性數據的存儲管理。存儲協議棧的分享包括NVM、MemI、Ea、Fea、Eep、Fls模塊的詳細介紹及代碼分析,具體的項目實戰請關注本號的后續文章,本篇為NVRAM Manager(NVM)模塊詳細介紹
    發表于 09-15 11:43 ?6049次閱讀

    錯誤7發生于Get LV Class Default Value.vi

    本帖最后由 路的追逐 于 2015-12-30 11:28 編輯 我的程序關于報表生成的,在開發環境可以運行,生成EXE后運行系統報錯。“錯誤7發生于Get LV Class Default Value.vi”但依賴關系里是有這個Vi一起打包的,請問這是怎么回事?
    發表于 12-14 16:39

    DEFAULT強制IDELAY_VALUE為0的FIXED和DEFAULT之間的區別是什么?

    為什么,DEFAULT強制IDELAY_VALUE為0的FIXED和DEFAULT之間的區別是什么?如果我想能夠使用inc端口,我認為這會迫使我進入VARIABLE,對吧?SIM_TAP_DELAY有哪些單位
    發表于 07-25 13:49

    怎么使用程序存儲器作為NVM

    您好,我在MCU上使用程序內存的一部分作為NVM(非易失性存儲器)。我已經設法和讀,但是現在我面臨的問題是,我想避免編譯器覆蓋我用于NVM的程序內存空間。MCU是PIC32 MX230F064 D。程序存儲器的最后一頁是
    發表于 09-18 10:31

    如何將NVM示例的讀取/寫入區域從32KB更改為4KB?

    pic32mx_u***_sk2as,NVM驅動器設置為動態的。這個例子進行擦除和32K隨機操作從NVM媒體啟動地址(0x9D010000)開始的NVM內存區域。一系列的確認動作后,
    發表于 03-25 10:41

    怎么讀寫NVM

    我正在運行一個PIC32 MX795,使用MPLAB 8.70。我正在嘗試給NVM一個值,然后再讀取它。這是我的代碼:#define NVM_PROGRAM_PAGE 0x9D007C00
    發表于 04-01 09:04

    怎么一個文件保存在內部NVM

    HI論壇,我一直試圖一個文件保存在內部NVM。與此并行,我的UC被配置為USB MSD。這很好,我甚至可以文件。問題是我必須斷開設備與USB的連接并重新連接才能看到文件中的變化。從FS庫中,我
    發表于 04-06 10:49

    NVM是什么

    NVM是什么?
    發表于 12-30 07:02

    IE Default Behaviors Handbook

    IE Default Behaviors Handbook TARGET | target版本:DHTML Object Model 讀/語法:XML  < Element
    發表于 01-10 23:17 ?24次下載

    什么是NVM

    非易失性存儲器   NVM是指非易失性存儲器,目前在智能卡上采用的主要包括:EEPROM和Flash。 NVM通常用來存放程序和數據,對于智能卡而言,大多把應用程序和數據、文件
    發表于 08-05 10:08 ?2.3w次閱讀

    IntelliJ IDEA Default Keymap

    IntelliJ IDEA Default Keymap
    發表于 07-12 16:05 ?0次下載

    如何使用新型NVM存儲系統支持高并發訪問提高處理速度

    I/O系統軟件棧是影響NVM(Non-Volatile Memory)存儲系統性能的重要因素。針對NVM存儲系統的讀寫速度不均衡、有限壽命等問題,設計了同異步融合的訪問請求管理策略;在使用異步策略
    發表于 08-14 17:02 ?16次下載
    如何使用新型<b class='flag-5'>NVM</b>存儲系統支持高并發訪問提高處理速度

    盡可能限制NVM操作的數據庫日志方案NVRC

    Memory)容量有限問題的首選技術。隨著數據庫系統中NVM的引入,傳統的日志技術需要考慮如何適應NVM特性。首先總結了已有的面向NMM的日志技術研究,進而提出了一種盡可能限制NVM
    發表于 04-08 10:50 ?14次下載
    盡可能限制<b class='flag-5'>NVM</b><b class='flag-5'>寫</b>操作的數據庫日志方案NVRC

    面向非易失性內存文件的NVM模擬與驗證

    現有非易失性內存文件系統都以DRAM模擬非易失性內存(Non- Volatile memory,NVM)進行測試,而沒有充分考慮兩者間的時延和磨損特性差異,使得測試結果無法準確反映文件系統在
    發表于 05-07 11:05 ?13次下載

    AUTOSAR NvM Block的Native、Redundant和Dataset有什么區別?

    Native數據是NVM塊中存儲的原始數據,是應用程序需要讀寫的數據。Native數據只在NVM塊中存儲一份,如果數據損壞或丟失,將無法恢復。因此,在寫入Native數據時,需要確保數據的可靠性和一致性。
    的頭像 發表于 04-06 10:29 ?4704次閱讀
    主站蜘蛛池模板: 免费啪啪小视频 | 欧美成人 色 图 | 国产美女视频黄a视频全免费网站 | 色老成人精品视频在线观看 | 性生i活一级一片 | 国产精品三级 | 色婷丁香 | 岛国三级在线看 | 日本三级网站在线观看 | 高清欧美性xxxx成熟 | 98pao强力打造高清免费 | 天天爽天天操 | 色香欲亚洲天天综合网 | 国产欧美亚洲精品 | 色偷偷888欧美精品久久久 | 日韩精品视频免费在线观看 | 69er小视频 | 日本美女黄色一级片 | 失禁h啪肉尿出来高h健身房 | 乱好看的的激情伦小说 | 午夜免费视频福利集合100 | 一区二区三区四区视频 | 在线看欧美成人中文字幕视频 | 国产亚洲美女 | 久久va| 天堂bt在线网bt | 日本不卡视频免费 | 久久久久青草 | 四虎影院精品 | 午夜久久久久久网站 | 国产精品嫩草影院人体模特 | 天天操天天干天天透 | 色综合久久88色综合天天 | 国产精品伦视频观看免费 | 天堂网在线视频 | 美女免费观看一区二区三区 | 久操中文| 亚洲精品色一区色二区色三区 | 91国在线啪精品一区 | 天天操天天透 | 天天爽天天操 |