nvram读写方法
- 格式:doc
- 大小:22.00 KB
- 文档页数:2
1、打开升级工具:。
2、进入升级工具界面,如下图:建议将升级软件放到UpgTool下的UpgData文件夹,并解压到对应的软件版本目录,不要解压到当前文件夹。
如下图所示:①在升级工具界面,选择,弹出提示,选择“否”不退出程序;选择“是”退出程序。
②在升级工具界面,选择,弹出提示选择“否”不退出程序;选择“是”退出程序。
③在升级/下载软件后,自动把软件的版本号改为售后软件的版本号,比如下载的软件版本号是“i6_A_1.00”,下载到手机上之后,进“*#225#”查看,版本号会变成“i6*A*1.00”。
下载的软件版本号是“i18_E_1.24a”,下载到手机上之后,进“*#225#”查看,版本号会变成“i18*E*1.24a”。
在主界面按“Ctrl+Alt+Shift+A”组合键切换是否开启,默认为开启,关闭后会在主窗口标题栏显示“(非售后使用版)”的字符串,如下图:开启和关闭后,升级成功后,手机开机进入*#225#查看软件版本号要正确。
3、串行端口:插入升级线或TRACE线,串行端口自动识别,如下图:注意,每台电脑自动识别的端口可能不一致,但要能自动识别。
对于用US B线升级的机,升级时,串行端口设置为USB数据线串口,如下图:(K201和i18就用数据端口)简单模式下:高级模式下:*#06#查询手机的IMEI码,并记录IMEI码。
4、正常升级:①鼠标左键单击“步骤1”图标,在提示框内选择存放升级软件的文件夹,如“步骤2”所示,最后选择确定,如“步骤3”所示。
软件加载完成后,如下图所示:选择“正常升级”,进入升级过程,在升级过程中,所以选项反灰显示(除停止任务、退出程序选项),如下图所示:手机产品测试作业指导书_UpgTool升级工具这时手机的RF参数被保存在升级工具的CalData文件夹中,以手机的IMEI码命名。
如下图所示:需要检查文件名称与第3步中记录的IMEI码保持一致,如果不一致,需要向工程师提出。
所看过的对24系列I2C读写时序描述最准确最容易理解的资料,尤其是关于主从器件的应答描述和页写描述,看完后明白了很多。
关于页写的描述,网络上绝大部分范程都没提到页写时的数据地址必须是每页的首地址才能准确写入,而且如果写入超过一页的数据会循环覆盖当前页的数据。
关于IIC总线I2C总线:i2c总线是Philips 公司首先推出的一种两线制串行传输总线。
它由一根数据线(SDA)和一根时钟线(SDL)组成。
i2c总线的数据传输过程如图3所示,基本过程为:1、主机发出开始信号。
2、主机接着送出1字节的从机地址信息,其中最低位为读写控制码(1为读、0为写),高7位为从机器件地址代码。
3、从机发出认可信号。
4、主机开始发送信息,每发完一字节后,从机发出认可信号给主机。
5、主机发出停止信号。
I2C总线上各信号的具体说明:开始信号:在时钟线(SCL)为高电平其间,数据线(SDA)由高变低,将产生一个开始信号。
停止信号:在时钟线(SCL)为高电平其间,数据线(SDA)由低变高,将产生一个停止信号。
应答信号:既认可信号,主机写从机时每写完一字节,如果正确从机将在下一个时钟周期将数据线(SDA)拉低,以告诉主机操作有效。
在主机读从机时正确读完一字节后,主机在下一个时钟周期同样也要将数据线(SDA)拉低,发出认可信号,告诉从机所发数据已经收妥。
(注:读从机时主机在最后1字节数据接收完以后不发应答,直接发停止信号)。
注意:在I2C通信过程中,所有的数据改变都必须在时钟线SCL为低电平时改变,在时钟线SCL为高电平时必须保持数据SDA信号的稳定,任何在时钟线为高电平时数据线上的电平改变都被认为是起始或停止信号。
作为一种非易失性存储器(NVM),24系列EEPROM使用的很普遍,一般作为数据量不太大的数据存储器。
下面总结一下其应用的一些要点。
从命名上看,24CXX中XX的单位是kbit,如24C08,其存储容量为8k bit,即1k Byte=1024 Byte。
我们为什么要讲NVRAM 本文是《让我们谈谈NVRAM》专题的一部分在计算机硬件领域,必不可少的一个设备就是存储器,信息化的处理离不开对信息的保存,因此各式各样的存储器也就呈现在我们的面前,而半导体存储器就是其一。
在一台电脑中,我们最熟悉的半导体存储器主要用以下三种:•用于存储BIOS信息的EEPROM(Electrically Erasable Programmable Read Only Memory,电可擦写可编程只读存储器),数据在断电后仍可以保存,近几年用于BIOS存储的Flash RAM(闪存)也是EEPROM的一种。
•用于存储临时工作数据的DRAM(Dynamic Random Access Memory,动态随机访问存储器),数据要通过不断的刷新才能保留,断电后消失。
•用于在CPU中存储常用指令与数据的SRAM(Static Random Access Memory,静态随机访问存储器),数据无需刷新操作,但断电后消失。
通常的,我们将数据断电后仍能保留的半导体存储器称为“非易失性(或非发挥性)随机访问存储器”——Non-Volatile Random Access Memory,即NVRAM,而像DRAM与SRAM这样的存储器则就称为VRAM。
其实,严格的说,非易失性存储器应该叫NVM(Non-Volatile Memory),因为有些存储器的随机访问能力非常弱,但在本文,为了方便讲述则将它们统一称为NVRAM,这也是由于现有和未来的非易失性存储器都具备不错甚至是非常好的随机寻址能力,本文的重点也将围绕它们来展开。
我们今天为什么要讲NVRAM——这个不太令人熟悉的东西呢?因为NVRAM已经是目前乃至未来最重要的存储器之一,其风头甚至盖过了传统的,我们所熟悉的DRAM与SRAM。
由于DRAM与SRAM的VRAM特性,使在数据存储领域中受到了一定的限制。
其实每种存储器都有自身的限制,但VRAM特性让这些平时肩负着重要数据中转任务的存储器在某些场合就有些力不从心了。
eeprom读写程序详解EEPROM(Electrically Erasable Programmable Read-Only Memory) 是一种可编程只读存储器,可以在电信号的作用下进行擦写和改写。
它通常用于存储单片机或其他嵌入式系统中的数据、设置参数、配置文件等。
对于 EEPROM 的读写程序,需要考虑以下几个方面:1. 读操作:读操作通常包括以下步骤:- 等待上次读操作完成。
- 获取要读取的数据的单元地址。
- 将 EEPGD 位和 CFGS 位清零。
- 启动读操作控制位 RD。
- 等待本次读操作完成。
- 将该单元地址中对应的数据返回。
在读取 EEPROM 数据时,为了避免芯片在一瞬间无法获取到数据,需要给芯片一定的时间来稳定获取数据。
因此,在读取操作中需要加入等待步骤。
2. 写操作:写操作通常包括以下步骤:- 等待上次写操作完成。
- 获取要写的数据的单元地址。
- 将要写的数据写入 EEPROM 的单元中。
- 将 EEPGD 位和 CFGS 位清零。
- 启动写操作控制位 WP。
- 等待写操作完成。
在写操作中,为了确保数据的可靠性,需要将要写的数据写入EEPROM 的单元中,并等待写操作完成。
同时,在写操作过程中,需要注意避免对无关的单元进行写操作,以免损坏 EEPROM 芯片。
3. 中断处理:在 EEPROM 的读写操作中,通常需要加入中断处理机制,以便在读写过程中及时响应和处理异常情况。
例如,在读取 EEPROM 数据时,如果 EEPROM 芯片出现故障,可能会导致读取失败。
为了避免这种情况,可以在读取操作中加入中断处理机制,在读取失败时及时报警或采取相应的应对措施。
总之,EEPROM 读写程序的实现需要考虑多个方面的因素,包括读操作、写操作、中断处理等。
同时,需要考虑 EEPROM 芯片的特性和限制,以便实现高效、稳定、可靠的 EEPROM 读写操作。
NVRAM读写操作详解在MTK中,NVRAM是作为一个独立的task来运行的。
在nvram_main.c文件中,(代码有删减, 注释部分用黄色标出, 便于阅读)void nvram_task_main(task_entry_struct *task_entry_ptr){kal_get_my_task_index(&my_index);/* nvram special service */nvram_special_service();while (1){//从Q中得到消息receive_msg_ext_q(task_info_g[task_entry_ptr->task_indx].task_ext_qid, ¤t_ilm);stack_set_active_module_id(my_index, current_ilm.dest_mod_id);// 处理消息nvram_main(¤t_ilm);// 释放消息free_ilm(¤t_ilm);}}Nvram_main函数, 处理NVRAM相关的消息void nvram_main(ilm_struct *ilm_ptr){if (ilm_ptr != NULL){if ((ilm_ptr->msg_id >= MSG_ID_NVRAM_CODE_BEGIN) && (ilm_ptr->msg_id <= MSG_ID_NVRAM_CODE_END)){if (ilm_ptr->msg_id == MSG_ID_NVRAM_STARTUP_REQ){//STARTUP消息nvram_startup_handler(ilm_ptr);}else if (ilm_ptr->msg_id == MSG_ID_NVRAM_RESET_REQ){//RESET消息nvram_reset_handler(ilm_ptr);}else if (ilm_ptr->msg_id == MSG_ID_NVRAM_READ_REQ){nvram_read_handler(ilm_ptr); //READ消息}else if (ilm_ptr->msg_id == MSG_ID_NVRAM_WRITE_REQ){nvram_write_handler(ilm_ptr); //WRITE消息}else if (ilm_ptr->msg_id == MSG_ID_NVRAM_SET_LOCK_REQ){nvram_set_lock_handler(ilm_ptr); //LOCK消息, 比较多用在TST中}}} /* end of module main function */也可以看到NVRAM task处理几个消息.READ流程从NV中读取一个数据, 例如读取语言设置信息:ReadValue (NVRAM_SETTING_LANG, &data, DS_BYTE, &error);我们需要注明, NVRAM的LID, 读取数据存放的指针, 数据类型, 和返回错误信息的地址. #define ReadV alue(nId,pBuffer,nDataType,pError)\ReadValueInt(nId,pBuffer,nDataType,pError,__FILE__,__LINE__)ReadValue精简了两个参数, 不需要注明文件和第多少行, 方面了应用使用. 看一下ReadValueInt这个函数.我们来看看这个函数到底干了什么事情:S32 ReadValueInt(U8 nDataItemId, void *pBuffer, U8 nDataType, S16 *pError, S8 *fileName, S32 lineNumber){switch (nDataType){case DS_BYTE:{// byteDataReadFlag先记住这个标志, 它标志了byte的数据是否已经被读取, 所以从这里我们可以猜测, NVRAM的数据, 应该不是每次都从硬件读取的, 而是有缓存的(记住这个假设, 稍后验证)/* second time reading, it alwasy return one request item */if (byteDataReadFlag){// 这个注释就更加明白了/* Data is cached no need to read from NVRAM */memcpy(pBuffer, &byte_data[nDataItemId * nDataType], nDataType);status = DS_BYTE;error = NVRAM_READ_SUCCESS;}/* process first time reading all data and return first request item data */else{/* Read data from the NVRAM file */// 这才从NVRAM文件中读取// 这个BUFFER的大小, 8*512 = 4KU8 tempBuffer[NVRAM_CACHE_SIZE];// 这个函数重点分析status = ReadRecordInt(NVRAM_EF_CACHE_BYTE_LID,1,tempBuffer,sizeof(tempBuffer),&error,fileName,lineNumber);/* copy out all total reading data */// 把读取的数据copy到byte_data里面去memcpy(byte_data, tempBuffer, sizeof(tempBuffer));// 这个时候把这个flag置上了byteDataReadFlag = 1;/* return first request item data */memcpy(pBuffer, &byte_data[nDataItemId * nDataType], nDataType);status = DS_BYTE;error = NVRAM_READ_SUCCESS;}break;} /* End of case DS_BYTE */// 后面的SHORT, DOUBLE同样道理case DS_SHORT:{} /* End of case DS_SHORT */case DS_DOUBLE:{} /* End of case DS_DOUBLE */}*pError = error;return status;}ReadValueInt总结:这个函数, 就是把以前读好的三个数组的数据拿出来, 如果还没有从NVRAM读取到cashe 里面, 就读一次. 关键的函数是: ReadRecordInt.第一次读BYTE类型的数据之前, 三个数组都是空的, flag也是空的, 读一个之后, byte数据被从NVRAM文件中读入到cashe中, 放在byte的数组里面, byteflag也被置上了. 下次再读的byte, 就只需要从CACHE中读取就可以了. 同理, short和double数据也相同.来看看它是怎么做的#define ReadRecordInt(nFileId,nRecordId,pBuffer,nBufferSize,pError,fileName,lineNumber)\ AccessRecordInt(nFileId,nRecordId,pBuffer,nBufferSize, 1, pError, MMI_FALSE, MMI_TRUE, fileName,lineNumber)S32 AccessRecordInt (U16 nFileId, U16 nRecordId, void *pBuffer, U16 nBufferSize, U16 nRecordAmount, S16 *pError, pBOOL isWrite, pBOOL isValue,S8 *filename, S32 lineNumber) {MYQUEUE queueNode;S32 status = -1;U32 my_index;circularQ_check_enum circularQ_check_result = circularQ_check_never_check;static U8 nvram_req_count = 0;MMI_BOOL toPush;if (isWrite){//WRITE的先放一下, 先看READ的再说}else{// 发了一个消息SendNVRAMReadReq(nFileId, nRecordId, nRecordAmount);// 这个函数调用了Message.oslMsgId = MSG_ID_MMI_EQ_NVRAM_READ_REQ;//OslMsgSendExtQueue(&Message), 发了一个REQ消息到Q上去.}in_nvram_procedure++;// REQ消息发完了, 接下来就等RSP消息来while (1){/* if more than 1 access request exist, go through the circular Q */if ((nvram_req_count > 0) && (circularQ_check_result == circularQ_check_never_check)){circularQ_check_result = NVRAMCheckCircularQ(&queueNode, nFileId);}if (circularQ_check_result != circularQ_check_found){OslReceiveMsgExtQ(mmi_ext_qid, &queueNode);OslGetMyTaskIndex(&my_index);OslStackSetActiveModuleID(my_index, MOD_MMI);}// 这个标志位先置空, 不管, 先记住它toPush = MMI_FALSE;switch (queueNode.msg_id){// 这里列出了很多消息, 其他不管, 先找READ_RSP消息再说case MSG_ID_MMI_EQ_PLAY_AUDIO_RSP:case MSG_ID_MMI_EQ_STOP_AUDIO_RSP:case MSG_ID_MMI_EQ_EXE_GPIO_LEVEL_RSP:case MSG_ID_MMI_EQ_SET_VOLUME_RSP:case MSG_ID_MMI_EQ_KEYPAD_DETECT_IND:case MSG_ID_TIMER_EXPIRY:// 就它了case MSG_ID_MMI_EQ_NVRAM_READ_RSP:{mmi_eq_nvram_read_rsp_struct *readMessage;readMessage = (mmi_eq_nvram_read_rsp_struct *)queueNode.oslDataPtr;{if (readMessage->result.flag == MMI_OK){// 读成功了, 再比较一下数据大小是不是合格if (readMessage->length > nBufferSize){}else if (readMessage->length < nBufferSize){}else{memcpy(pBuffer, readMessage->data, readMessage->length);*pError = NVRAM_READ_SUCCESS;}status = readMessage->length;}OslFreeInterTaskMsg(&queueNode);}toPush = MMI_TRUE;break;}case MSG_ID_MMI_EQ_NVRAM_WRITE_RSP:}// 这个flag标志是否读取成功if (toPush == MMI_TRUE){ilm_struct ilm_ptr;flag = OslWriteCircularQ(&ilm_ptr);OslFreeInterTaskMsg(&queueNode);}}}AccessRecordInt总结:这个函数是个真正的读取函数, 发REQ消息给NVRAM TASK, 等待RSP消息, 得到读取数据.写入流程重点分析WriteValueInt这个函数S32 WriteValueInt(U8 nDataItemId, void *pBuffer, U8 nDataType, S16 *pError, S8 *fileName, S32 lineNumber){switch (nDataType){// 还拿BYTE来说case DS_BYTE:{// 已经从NVRAM 到CACHE里面了/* second time access, it always sets the request item */if (byteDataReadFlag){/* Data is cached no need to read from NVRAM */memcpy(&byte_data[nDataItemId * nDataType], pBuffer, nDataType);/* write into NVRAM module, if not wait for falshing directly */if (!byteDataWriteFlashFlag){status = WriteRecordInt(NVRAM_EF_CACHE_BYTE_LID,1,byte_data,NVRAM_CACHE_SIZE,&error,fileName,lineNumber);}status = DS_BYTE;error = NVRAM_WRITE_SUCCESS;}// 还没有读到CACHE里面/* process first time access all data and return first write item data */else{// 那就读到CACHE/* Read all data from the NVRAM file */status = ReadRecordInt(NVRAM_EF_CACHE_BYTE_LID,1,byte_data,NVRAM_CACHE_SIZE,&error,fileName,lineNumber);memcpy(&byte_data[nDataItemId * nDataType], pBuffer, nDataType);//读好了,就写吧/* write into NVRAM module, if not wait for falshing directly */if (!byteDataWriteFlashFlag){// 关键还是WriteRecordIntstatus = WriteRecordInt(NVRAM_EF_CACHE_BYTE_LID,1,byte_data,NVRAM_CACHE_SIZE,&error,fileName,lineNumber);}byteDataReadFlag = 1;status = DS_BYTE;error = NVRAM_WRITE_SUCCESS;}break;} /* End of case DS_BYTE */case DS_SHORT:{} /* End of case DS_SHORT */case DS_DOUBLE:{} /* End of case DS_DOUBLE */}}看看WriteRecordInt函数:S32 WriteRecordInt(U16 nFileId,U16 nRecordId,void *pBuffer,U16 nBufferSize,S16 *pError, S8 *filename, S32 lineNumber){// 打开文件handle = FS_Open((PU16) fileNameU, FS_CREATE_ALWAYS);{// 写文件retValue = FS_Write(handle, pBuffer, nBufferSize, &iBytes);}}WriteRecordInt总结:其实, 就做了一个写文件的操作, 但是每次都把CACHE里面的数据写到文件里面去.为什么不使用OFFSET的方式呢?写入的数据量也小呀.MP数据MP, for MTK/PMT common applications; 在nvram_common_config.c定义一般存放比较大的数据量, 不能BYTE, SHORT, DOUBLE来分类的那种.读取和写入使用另外接口, ReadRecord和WriteRecord, 直接通过文件读写操作.比如我们要做黑白名单, 就可以在MP这里做.。
162010,31(1)计算机工程与设计Computer Engineering and Design0引言NVRAM (non-volatile random access memory ,非易失性随机访问存储器)是广泛应用于网络路由器的一种存储器件。
它如同PC 上的CMOS ,作用是存放路由器的配置参数。
目前常见的NVRAM ,大都是静态SRAM ,即带有备用电源的SRAM ,它的实现最简单,同普通内存操作一样。
但是在实际应用中,不是所有的开发板都配备有静态SRAM 。
在这种情况下,如果使用该方案开发网络路由器,重新加入配备电源的SRAM 必须要重新排版,布线。
开发周期与开发成本将会大大增加。
因此,可以考虑在现有的硬件资源基础上,通过新的方式来实现NVRAM [1]。
本文就是以神州龙芯开发的CQ8401开发板为硬件平台,在自行裁剪和移植的嵌入式Linux 平台下,利用Nor Flash 来实现网络路由器的NVRAM 功能。
1NVRAM 新的实现方案分析由于NVRAM 仅用于保存启动配置文件(Startup-Config ),故其容量较小,通常在路由器上只配置32KB~128KB 大小的NVRAM 。
配备电源的SRAM 速度较快,是目前读写最快的存储设备,而成本也比较高。
一般的开发板所配备的Nor Flash空间足够大,在系统性能得到满足的前提下,可以把Nor Flash 分出一个区来当作NVRAM 使用。
SRAM 和Nor Flash 的对比分析,如表1所示。
网络路由器中的NVRAM 用于存放配置参数。
正常启动路由器后,NVRAM 中的内容会拷贝到内存一份,我们对路由器的设置实际上就是修改内存中的参数。
所以内存和NVRAM 中的内容可以不一样,直到使用write memory 将内存设置保存到NVRAM 。
在系统起来以后,我们可以根据需要修改配备参收稿日期:2009-07-17;修订日期:2009-09-18。
MTK平台NVRAM的使用首先明确几个概念:1.ROM(Read Only Memory\只读存储器):通常用来存储操作系统和内置程序,相当于MTK的Code Region,这部分的内容是写入后不允许修改的;2.RAM(Random Access Memory\随机访问存储器):相当于电脑内存了,特点是访问速度快,断电后数据会自动丢失,不会保存;3.NVRAM(NonV olatileRandomAccessMemory\非易失性随机访问存储器):指断电后仍能保持数据的一种RAM,用来存储一些需要在断电后能够保存的数据,比如我们手机的一些相关设置就需要保存在NVRAM中;下面以给出我们ds635项目的flash memory划分,ds635使用了一片128M的flash memory和一片64M的RAM,在custom_memorydevice.h这个文件中如下几行决定了我们flash memory的分区配置://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define NAND_BOOTING_NAND_FS_BASE_ADDRESS 0x02000000 这一行确定文件系统的起始地址,这里是0x02000000,说明我们分配的Code Region是32M,剩余的96M就是文件系统区域了;#define NAND_BOOTING_NAND_FS_SIZE 0x06000000 这一行确定文件系统的大小,0x06000000也就是96M了;#define NAND_BOOTING_NAND_FS_FIRST_DRIVE_SECTORS 180000 这一行确定文件系统的第一个分区的大小,如果没有额外的分区,可以将这一行设为0,这里我们的设置是180000,则文件系统的第一个分区大小是90000K,这样留给用户使用的话机空间大概是87M。
RAM的一般结构和读写过程RAM(Random Access Memory)是计算机中的一种主要的存储设备,用于临时存储数据和指令。
它具有随机访问数据的能力,可以根据需要快速读取和写入数据。
RAM的一般结构和读写过程如下。
一般结构:RAM由一个或多个存储单元组成,每个存储单元由一个存储位组成,存储位可以存储一个二进制值(0或1)。
每个存储单元都有一个唯一的地址,用于访问和识别该单元。
存储单元可以按照不同的组织方式进行排列,常见的有随机存取存储器(Random Access Memory)、动态随机访问存储器(Dynamic Random Access Memory)和静态随机访问存储器(Static Random Access Memory)等。
读写过程:1.选择存储单元:首先,需要选择要读取或写入的特定存储单元。
这需要使用指定的地址来选择存储单元。
2.读取操作:当需要从RAM中读取数据时,计算机将根据所指定的地址发送一个读取信号。
这会导致特定存储单元中的数据被读取并被放置在RAM的输出线上。
然后,输出线上的数据可以由计算机的其他部分使用,如中央处理器(CPU)。
3.写入操作:当需要将数据写入RAM时,计算机将根据所指定的地址发送一个写入信号,并同时发送要写入的数据。
这会导致特定存储单元中的数据被更新为新的数据值。
4.刷新操作(仅适用于动态RAM):动态RAM需要定期进行刷新操作,以维持存储单元中的数据值。
这是因为动态RAM中的信息是通过电容器来存储的,电容器会逐渐失去电荷,导致数据丢失。
因此,动态RAM需要周期性地刷新,以重新充电并保持数据的正确性。
5.速度和延迟:RAM具有较快的读写速度,可以在几纳秒的时间内进行操作。
然而,RAM的速度也会受到一些因素的影响,如访问时间、数据传输速度和延迟。
延迟是指从发出指令到开始执行指令所需的时间,而数据传输速度则指数据从RAM传输到其他设备的速率。
总结:RAM的一般结构包括存储单元、地址和数据线等组件,用于临时存储数据和指令。
flash,Rom,RAM,nvram的区别(思科设备)路由器的启动过程简单来说分为三个部分1.硬件检查2.运⾏IOS3.导⼊配置⽂件。
要了解路由器的启动过程⾸先要来了解⼀下路由器的主要存储硬件和它们的作⽤。
ROM是⼀个⽤于维护路由器的硬件它存储着POST程序bootstrap程序以及Mini IOS。
Flash它是⽤来存储路由器完整IOS镜像的硬件。
IOS就相当于思科路由器的没有IOS或者IOS镜像损坏的路由器是⽆法⼯作的。
NVRAM是⽤于存放路由器的启动配置⽂件Startup-config的硬件。
路由器启动前最后⼀次保存的配置都储存在这⾥。
RAM存储路由器启动时由启动配置⽂件拷贝⽽来的运⾏配置⽂件Running-config解压后的IOS以及学习到的路由表Routing-table和包队列。
接下来详细了解⼀下思科路由器的启动过程⼀、路由器加电后⾸先运⾏ROM中的POST程序Power On Self Test对路由器的硬件进⾏检测俗称加电⾃检。
⼆、检测通过后紧接着执⾏ROM中的引导程序bootstrap并根据寄存器值register来决定启动⽅式。
寄存器值的格式为0x21YZ Y列的状态0x210Z从nvram加载配置⽂件0x214Z不从nvram加载配置⽂件Z列的状态0x21Y0从rommon启动提⽰符为路由器启动时按CtrlBreak0x21Y1从mini ios启动提⽰符为Routerboot0x21Y,从flash启动提⽰符为Router我们经常使⽤的两个寄存器值0x2102正常0x2142不读取保存的配置。
三、如果正常启动则按引导程序到Flash中查找IOS镜像。
如果找到IOS镜像则读取后正常启动。
如果没有找到IOS镜像则进⼊即Mini IOS启动。
下可使⽤TFTP上的IOS或使⽤TFTP/X-modem为路由器重新灌⼀个IOS。
如果Mini IOS也启动失败则进⼊rom monitor模式。
高通modem代码中的NV读写NVRAM非易失性随机访问存储器(Non-Volatile Random Access Memory) ,是指断电后仍能保持数据的一种RAM。
在手机中,NVRAM位于flash芯片中。
手机上所谓的NVRAM是一套机制,它的数据部分:默认存在flash的code区,NARAM文件存在文件系统区域(系统盘),电话本数据是以NVRAM文件的形式保存在文件系统区域的(系统盘),SIM卡的电话本就在SIM卡上了,T卡是扩展的flash,都是文件系统区。
(来自于百度百科)这样看来,EFS统一管理着flash芯片,以及扩展flash(sd卡),至于手机的内存,一般是另外的一块单独的RAM,供手机操作系统、应用程序运行时使用,不受EFS管理。
有两种方法设置需要保存的NV值(nv_cmd_type. data_ptr):1.在nv_items.h中找到nv_item_type这个联合体的源代码,把自己需要的数据结构放到这个联合体中;2.不在nv_item_type联合体中添加任何代码,直接使用强制类型转换,将自己的数据结构强制类型转换为nv_item_type。
说明:nv_cmd_type. data_ptr是一个nv_item_type的指针,在做NV 写操作的时候,我们需要传入一个(nv_item_type*)的参数,然后把这个传进来的(nv_item_type*)的参数赋值给nv_cmd_type. data_ptr,这样nv_cmd函数在发送NV_WRITE_F命令的时候,就将需要保存到NV分区中的数据传送给了nv_task,在nv_task正常响应NV_WRITE_F命令后,我们需要的NV值就被保存到NV分区中去了。
对于NV的读操作,nv_cmd_type. data_ptr的值将会赋值给一个(nv_item_type*)类型的出参,这样在nv_task正常响应NV_READ_F 命令后,出参中就保存了从NV分区中读到的NV值了。
RAM的一般结构和读写过程一、RAM(Random Access Memory,随机存取存储器)的一般结构:RAM是一种计算机中常用的存储器,它由若干个存储单元组成,每个存储单元都有唯一的地址。
存储单元的大小决定了RAM的容量大小。
一般情况下,存储单元都是由一个或多个触发器组成。
常见的RAM有静态RAM (SRAM)和动态RAM(DRAM)两种类型。
静态RAM是一种基于触发器的存储器单元,具有快速的读取和写入速度,但相对较大的电路复杂度和功耗。
它的存储单元由许多触发器组成,每个触发器存储一个比特的数据,每个单元还包括读取和写入电路以及地址译码器等。
静态RAM一般用于需要快速读写和低功耗的场景,如高速缓存。
动态RAM是一种基于电容的存储器单元,具有较高的容量和较低的成本,但读取和写入速度相对较慢。
它的存储单元由电容和场效应晶体管组成,每个存储单元存储一个比特的数据。
由于电容会逐渐失去电荷,所以动态RAM需要定期进行刷新操作来保持存储数据的有效性。
动态RAM一般用于大容量的存储器,如计算机主存。
二、RAM的读写过程:RAM的读写过程可以分为以下几个步骤:1.地址传递:计算机通过总线将要读写的存储单元的地址发送给RAM。
2.译码和选择:RAM的地址译码器接收到地址信号后,将指定存储单元的地址译码为有效的信号,用于选择要操作的存储单元。
3.读写控制:根据读写指令,RAM决定是进行读取数据还是写入数据的操作。
这个过程由控制电路来完成。
4.读取数据:如果是读取操作,RAM会将存储单元中的数据通过数据输出线发送给计算机。
5.写入数据:如果是写入操作,计算机会通过数据输入线将要写入的数据发送给RAM,RAM将数据写入指定存储单元。
需要特别说明的是,静态RAM和动态RAM在读写过程中有些许不同。
静态RAM的读写过程较为简单,可以实现单周期读写。
通过选通指定存储单元,将该单元的数据送到数据输出线上供计算机读取。
写入数据时,计算机将数据通过数据输入线写入指定存储单元。
让我们谈谈NVRAM非易失性存储器,一个对于普通用户来说似乎过于专业和晦涩的词汇,其实离我们越来越近,与我们日常工作和生活越来越密不可分。
如果通俗地解释非易失性存储器,那就是指那些断电后数据仍然能保留的半导体存储器。
对这类存储器,业界统称为非易失性随机访问存储器(NVRAM,Non-Volatile Random Access Memory),看看我们身边处处可见的U盘,数码相机、可拍照手机、PDA、以及其中的存储卡,如CF、SD等等,无一例外地仰仗着NVRAM技术的支持。
随着移动设备、便携式设备和无线设备的迅猛发展,NVRAM也遇到了前所未有的好时机,并迅速走俏市场。
日前,在多种NVRAM中,以闪存(Flash Memory)技术最为引人注目,并占据着NVRAM市场的霸主地位。
尽管现在不同于闪存技术的其他NVRAM技术已经出现,并逐渐被一些厂商重视并看好,但在近几年内,闪存仍将以其强大的优势称霸NVRAM应用市场。
移动市场和无线市场的强大需求为NVRAM带来了市场机会,同时也对NVRAM提出了更高的要求,更快的速度、更大的容量、更高的整合度以及更低的能耗始终是NVRAM的奋斗目标,未来NVRAM跟我们的关系将更加密切。
为了更清楚地了解NVRAM技术和市场发展,我们组织了本期专题,详细地向大家介绍了NVRAM 技术的发展、与DRAM和SRAM不同之处以及NVRAM的未来发展,尤其重点介绍了大家经常用到的闪存技术,本期专题由以下5篇文章组成,点击图标进入:我们为什么要讲NVRAM在计算机硬件领域,必不可少的一个设备就是存储器,信息化的处理离不开对信息的保存,因此各式各样的存储器也就呈现在我们的面前,而半导体存储器就是其一。
在一台电脑中,我们最熟悉的半导体存储器主要用以下三种:•用于存储BIOS信息的EEPROM(Electrically Erasable Programmable Read Only Memory,电可擦写可编程只读存储器),数据在断电后仍可以保存,近几年用于BIOS 存储的Flash RAM(闪存)也是EEPROM的一种。
nvme读写命令格式解析NVMe(Non-Volatile Memory Express)是一种高性能、低延迟的存储协议,用于连接计算机系统和固态存储设备(如SSD)之间的通信。
NVMe定义了一系列命令来进行读写操作。
NVMe读写命令的格式如下:1. 命令头(Command Header):命令头包含了对命令的描述和操作类型等信息。
命令头通常由四个双字节(8字节)组成,包括Opcodes字段表示命令操作类型、Flags字段表示命令标志和命令特性、Command Identifier(CID)字段表示命令的唯一标识符等。
2. 命令特征(Command Features):命令特征用于提供特定命令的配置信息和参数。
命令特征通常由一个或多个双字节(2字节)组成,用于指定读写的地址、长度、传输类型等。
3. 数据传输(Data Transfer):在读写命令中,数据传输字段用于指定读取或写入的数据缓冲区的地址和长度。
数据传输字段通常由一个或多个双字节(4字节)组成。
4. 数据保护(Data Protection):数据保护字段用于指定读取或写入数据时所使用的数据完整性和安全性保护手段。
数据保护字段通常由一个或多个双字节(8字节)组成。
5. 中断向量(Interrupt Vector):中断向量字段用于指定当命令执行完成后触发的中断向量号。
中断向量字段通常由一个或多个双字节(2字节)组成。
6. 写入回调地址(Write Callback Address):写入回调地址字段用于指定写入命令完成后,向主机系统通知命令完成状态的回调函数地址。
写入回调地址字段通常由一个或多个双字节(2字节)组成。
以上是简单介绍NVMe读写命令格式的基本组成部分,实际命令格式可能会因具体的协议版本和设备支持的特性而有所不同。
具体的命令格式和解析方法可以参考NVMe协议规范或设备的技术文档。
nvram读写方法NVRAM即非易失性随机访问存储器,它是断电后仍能保持数据的一种RAM要在NVRAM里面添加、删减或者修改数据项,可以按下面五个步骤:(1)在“nvram_user_defs.h”文件的nvram_LID_cust_enum中定义一个新的LID逻辑数据项(2)在”nvram_user_defs.h”文件里定义两个常量SIZE和TOTAL(3)在“nvram_user_config.c”里定义添加的数据项的默认值(4)在”logical_data_item_table_cust”里添加数据项的属性(5)在“nvram_user_config.c”中改变版本号CODED_DATA_VERSION在程序中访问NVRAM(1)S32 WriteRecord(U16 nFileId,U16 nRecordIdk,void *pBuffer,U16 nBufferSize,S16 pError)该函数的作用是写一个记录到NVRAM中,如果写成功返回记录序号,否则返回-1(2) S32 ReadRecord(U16 nFileId,U16 nRecordId,void *pBuffer,U16 nBufferSize,S16 pError)该函数的主要作用是从NVRAM中读取一个记录,如果读取成功将返回TRUE,否则返回FALSE(3) S32 WriteValue(U8 nId,void *pBuffer,U8 nDataType,S16 *pError)该函数往NVRAM里面写入一个BYTE、SHORT或DOUBLE类型的数据,如果写成功将返回TRUE,否则返回FALSE(4) S32 ReadValue(U8 nId,void *pBuffer,U8 nDataType,S16 *pBuffer)该函数从NVRAM里面读取一个BYTE、SHORT或DOUBLE类型的数据,如果读取成功将返回TRUE,否则返回FALSENVRAM的添加方法以闹钟INLINE菜单为例步骤如下:1.在Nvram_common_defs.h文件中添加LID选项到nvram_lid_commapp_enum枚举中NVRAM_EF_MY_LID,/* Add LID with its compile optoin in the tail comment */NVRAM_EF_LAST_LID_COMMAPP} nvram_lid_commapp_enum;2.在Custom_mmi_default_value.h文件中定义SIZE和TOTAL#define NVRAM_MY_DATA_TOTAL 1#define NVRAM_MY_DATA_SIZE sizeof(nvram_struct)3.Nvram_common_config.c文件在ltable_entry_struct logical_data_item_table_cust[]最后增加相应的结构如下:注意按序号填写在最后{NVRAM_EF_MY_LID,NVRAM_ALM_ALARM_DATA_SIZE ,NVRAM_ALM_ALARM_DATA_TOTAL,NVRAM_EF_ZERO_DEFAULT,NVRAM_ATTR_AVERAGE,NVRAM_CATEGORY_SYSTEM| NVRAM_CATEGORY_FACTORY | NVRAM_CATEGORY_SHADOW_MS | NVRAM_CATEGORY_SH ADOW,"MP58",VER(NVRAM_EF_ALM_ALARM_MY_LID),"Alarm my\0",NVRAM_RESERVED_VALUE}5.在Common_nvram_editor_data_item.h文件中添加版本号#define NVRAM_EF_MY_LID_VERNO 000读写数据函数:WriteRecord(nFileId,nRecordId,pBuffer,nBufferSize,pError)ReadRecord(nFileId,nRecordId,pBuffer,nBufferSize,pError)在NVRAMType.h文件中可以查看typedef enum{NVRAM_READ_FAIL,NVRAM_READ_SUCCESS,NVRAM_ERROR_ACTUAL_READ_GREATER_THAN_REQUESTED_READ,NVRAM_ERROR_ACTUAL_READ_LESS_THAN_REQUESTED_READ,NVRAM_WRITE_SUCCESS,NVRAM_WRITE_FAIL} MMINVRAMERRORSENUM;根据返回的ERROR值可以查看读取是否成功另一种读写方式ReadValue(nId,pBuffer,nDataType,pError)Custom_mmi_default_value.h文件中定义你的NVRAM ID,注意要定义在你所定义数据类型相对应的文件下。
NVMe(Non-Volatile Memory Express)是一种用于连接计算机系统与非易失性存储设备(如固态硬盘)的协议和驱动程序。
下面是一个简化的 NVMe 驱动读写流程的概述:1.应用层请求:应用程序通过操作系统提供的文件系统接口(例如,读取或写入文件)发送读写请求。
2.文件系统转换:操作系统的文件系统层将文件操作转换为逻辑块地址。
这个逻辑块地址是虚拟化的,因为NVMe 设备通常被分区并包含逻辑块地址。
3.I/O 队列:操作系统将转换后的请求传递给 NVMe 驱动的 I/O 队列。
NVMe驱动会维护多个 I/O 队列,以允许并行处理多个请求。
4.命令构建: NVMe 驱动将逻辑块地址和其他相关信息封装为 NVMe 命令。
5.命令队列:将构建的 NVMe 命令加入 NVMe 设备的命令队列。
NVMe 设备支持多个命令队列,每个队列可以并行处理命令。
6.NVMe 控制器: NVMe 控制器接收并处理命令队列中的命令。
它将这些命令转换为 PCIe 事务,以便通过 PCIe 总线发送给 NVMe 存储设备。
7.命令传输: NVMe 存储设备收到 PCIe 事务后,将其解码为 NVMe 命令。
8.读写操作: NVMe 存储设备执行相应的读写操作。
在读取操作中,数据从存储设备传输到内存;在写入操作中,数据从内存传输到存储设备。
9.中断通知:存储设备在完成读写操作后,通过 PCIe 发送中断信号通知NVMe 控制器。
10.数据传输: NVMe 控制器从存储设备读取或写入的数据传输到系统内存。
11.完成通知: NVMe 驱动接收到存储设备的完成通知,并更新相应的数据结构以表示请求已完成。
12.应用层响应: NVMe 驱动将请求的结果传递给操作系统文件系统层,并最终返回给应用程序。
这是一个整体的概述,实际的 NVMe 驱动读写流程可能会更为复杂,涉及到异步处理、中断处理、错误处理等方面的细节。
NVMe 的设计旨在充分利用固态硬盘的性能,通过多队列和并行操作来提高数据传输效率。
linux nvme驱动读写流程Linux NVMe驱动读写流程NVMe(Non-Volatile Memory Express)是一种用于连接非易失性存储设备(如固态硬盘)的高性能接口和协议。
在Linux操作系统中,NVMe驱动负责管理和使用NVMe设备。
本文将介绍Linux NVMe驱动的读写流程。
1. 驱动加载和初始化当系统启动时,Linux内核会检测到NVMe设备并加载相应的驱动。
驱动加载完成后,系统会初始化NVMe设备并为其分配内存空间。
2. 创建命名空间NVMe设备可以划分为多个逻辑分区,称为命名空间。
在NVMe 驱动中,需要使用命名空间来进行读写操作。
驱动会通过命令将NVMe设备中的物理块映射到逻辑命名空间中。
3. 打开设备文件在Linux中,每个NVMe设备都会被映射为一个设备文件。
为了进行读写操作,应用程序需要首先打开相应的设备文件。
通过打开设备文件,应用程序可以与NVMe驱动进行交互。
4. 发送读写命令一旦设备文件打开,应用程序就可以向NVMe驱动发送读写命令。
读命令通常包括要读取的逻辑块地址和读取数据的缓冲区。
写命令则包括要写入的逻辑块地址和写入数据的缓冲区。
5. 驱动处理命令NVMe驱动接收到读写命令后,会根据命令中指定的逻辑块地址,将命令映射到相应的物理块地址。
驱动还会进行错误检测和纠正,以确保数据的完整性和正确性。
6. 执行读写操作一旦命令处理完毕,NVMe驱动会通过PCIe总线将命令发送给NVMe设备。
设备会根据命令进行读取或写入操作,并将结果返回给驱动。
7. 数据传输在读取操作中,NVMe设备会将读取的数据传输到驱动中,并将其存储在驱动中的缓冲区中。
在写入操作中,驱动会将要写入的数据传输给NVMe设备,并由设备将数据写入到相应的物理块中。
8. 完成操作一旦数据传输完成,NVMe驱动会将操作的结果返回给应用程序。
应用程序可以根据操作的结果来判断读写操作是否成功。
9. 关闭设备文件当应用程序完成读写操作后,应该关闭设备文件以释放资源。