WinCE下应用程序直接读_写_擦除flash设备的方法
单片机flash的擦写过程
单片机flash的擦写过程
单片机flash的擦写过程是指对存储在flash芯片中的数据进行擦除和写入的过程。
在进行擦写操作之前,需要先对flash进行擦除操作,将需要写入的数据覆盖在已经擦除的区域中。
擦写操作的过程可以分为以下几个步骤:
1. 擦除操作:在进行写入操作之前,需要对flash进行擦除操作。
擦除操作会将需要擦除的区域中的所有数据清空,以便写入新的数据。
2. 写入操作:在擦除操作完成之后,可以进行写入操作。
写入操作将需要写入的数据存储在flash芯片的相应区域中。
写入操作时需要对flash进行写入保护,以免误操作导致数据的丢失。
3. 校验操作:在写入操作完成之后,需要进行校验操作,以确保写入的数据和原始数据一致。
校验操作可以使用CRC等校验算法进行验证。
4. 读取操作:在校验操作完成之后,可以进行读取操作,以验证写入的数据是否被正确保存在flash中。
读取操作可以使用读取指令进行。
总之,单片机flash的擦写过程是一个非常重要的操作,需要注意各个环节的细节,以确保数据的正确性和可靠性。
- 1 -。
分享STM32FLASH擦除以及防止误擦除程序代码、写入
分享STM32 FLASH 擦除(以及防止误擦除程序代码)、写入编译环境:我用的是(Keil)MDK4.7.2stm32库版本:我用的是3.5.0一、本文不对FLASH的基础知识做详细的介绍,不懂得地方请查阅有关资料。
对STM32 内部FLASH进行编程操作,需要遵循以下流程:FLASH解锁清除相关标志位擦除FLASH(先擦除后写入的原因是为了工业上制作方便,即物理实现方便)写入FLASH锁定FLASH实例:#define FLASH_PAGE_SIZE ((uint16_t)0x400) //如果一页为1K大小#define WRITE_START_ADDR ((uint32_t)0x08008000)//写入的起始地址#define WRITE_END_ADDR((uint32_t)0x0800C000)//结束地址uint32_t EraseCounter = 0x00, Address = 0x00;//擦除计数,写入地址uint32_t Data = 0x3210ABCD;//要写入的数据uint32_t NbrOfPage = 0x00;//记录要擦除的页数volatile FLASH_Status FLASHStatus =FLASH_COMPLETE;/*FLASH擦除完成标志*/void main(){/*解锁FLASH*/FLASH_Unlock();/*计算需要擦除FLASH页的个数 */NbrOfPage = (WRITE_END_ADDR - WRITE_START_ADDR) / FLASH_PAGE_SIZE;/* 清除所有挂起标志位 */FLASH_ClearFlag(FLASH_FLAG_EOP |FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);/* 擦除FLASH 页*/for(EraseCounter = 0; (EraseCounter 只要()里面的数是flash第xx页中对应的任何一个地址!就是擦除xx页全部内容!防止误擦除有用程序代码的方法方法一:首先要计算程序代码有多少,把FLASH存取地址设置在程序代码以外的地方,这样就不会破坏用户程序。
wince中的flash分区和checksum点滴[会要]
WinCE中的Flash分区和CheckSum点滴星期三, 十一月 8th, 2006CheckSum是一种用于检查数据文件有没有发生变化的方法,对于一些重要的数据文件为了检查传输过程过程中有没有数据的损坏或丢失,常常会用到CheckSum算法。
WinCE中经常用到CheckSum的地方就是对即将烧写进Flash中的image文件进行校验,和烧写完对写入的数据进行完整性检查,一般这里的image有OSimage和UT的bin文件两种。
CheckSum的原理是把一个文件以二进制的方式打开,将里面所有的字节的值一个一个的累加起来,一直到最后一个字节,最后得到一个累加值,它就是我们要的CheckSum的结果。
从CheckSum的这个特性可知数据值为0的字节是不会影响到最终的结果,这种特性我认为也是CheckSum的一个弱点,不能像MD5,SHA1等摘要算法一样基本上能反映出哪怕一个bit 的改动,但是这个特性也给WinCE运行期间计算保存在FLASH上的image数据文件的完整性带来了方便。
为了从Flash中得到正确的CheckSum值必须先了解image在Flash中的烧写方式,这包括了解image文件内部是怎么组织的,Flash的分区和块的分配是如何进行的。
先以Sumsung的FLASH为例来分析一下Flash的分区大体原则:WinCE的Flash分区大体分为Nand BootLoader(NBL)区,Binfs区和文件区,NBL区存放BootLoader和烧写Image的工具程序,Binfs分区存放MBR、image的XIPKERNEL.bin、Chain.bin和NK.bin等OS的数据。
文件区一般格式化为FAT分区让WinCE上层的磁盘和分区管理程序管理。
Flash的分区是由UT在烧入image的时候决定的,包括每个分区的起止块地址,分区的大小和类型等,Detail如下:1)NBL区一般占10个块(128K/块)的大小,分区虽小但是却是最重要的部分,保存着UT的三大模块:NBL1(bootloader),NBL2(IPL,Init Program Loader)和NBL3(Upgrade Tools),其中NBL1和NBL2共同保存在FlASH的第一个block中,FLASH芯片在生产的时候厂商都会特别保障这些block的可靠性,特别是保存了最开始bootloader代码和IPL的第一块。
flash读写擦除的main函数
flash读写擦除的main函数下面是一个使用Flash读写擦除的主要函数的示例,用于在嵌入式系统中操作Flash存储器。
该函数使用简体中文编写。
Flash存储器是一种可编程的非易失性存储器,常用于嵌入式系统中存储程序代码、配置数据和其他非易失性数据。
原始的Flash存储器是按块组织的,并且每个块只能进行整体擦除,然后才能进行读取和写入操作。
这意味着在对Flash存储器进行写操作之前,必须首先将需要保留的数据读取出来,然后再进行擦除和写入操作。
下面的代码展示了如何在嵌入式系统中实现Flash读写擦除的主要函数。
```c#include <stdint.h>// Flash存储器基地址#define FLASH_BASE_ADDRESS 0x80000000// Flash存储器块的大小#define FLASH_BLOCK_SIZE 4096// Flash存储器的扇区数量#define FLASH_SECTOR_COUNT 16// Flash存储器的页大小#define FLASH_PAGE_SIZE 256//从Flash存储器中读取数据void flash_read(uint32_t address, uint8_t *data, uint32_t size) {uint32_t flash_address = FLASH_BASE_ADDRESS + address;for (uint32_t i = 0; i < size; i++) {*data++ = *((uint8_t*)flash_address++);}}//向Flash存储器中写入数据void flash_write(uint32_t address, const uint8_t *data, uint32_t size) {uint32_t flash_address = FLASH_BASE_ADDRESS + address; //将需要保留的数据读取出来uint8_t temp_data[size];flash_read(address, temp_data, size);//擦除该块Flash存储器flash_erase_block(address);//将保留的数据写入原始位置for (uint32_t i = 0; i < size; i++) {*((uint8_t*)flash_address++) = temp_data[i];}//将新数据写入Flash存储器for (uint32_t i = 0; i < size; i++) {*((uint8_t*)flash_address++) = *data++;}}//擦除Flash存储器中的一个块void flash_erase_block(uint32_t address) {uint32_t flash_address = FLASH_BASE_ADDRESS + address;//模拟擦除操作,将该块Flash存储器中的每个字节设置为0xFF for (uint32_t i = 0; i < FLASH_BLOCK_SIZE; i++) {*((uint8_t*)flash_address++) = 0xFF;}}int main() {//从Flash存储器中读取数据uint8_t data[FLASH_PAGE_SIZE];flash_read(0, data, FLASH_PAGE_SIZE);//向Flash存储器中写入数据uint8_t new_data[FLASH_PAGE_SIZE];for (uint32_t i = 0; i < FLASH_PAGE_SIZE; i++) {new_data[i] = i;}flash_write(0, new_data, FLASH_PAGE_SIZE);return 0;}```上述代码中的`flash_read`函数用于从Flash存储器中读取数据。
教你从Windows10彻底删除Flash的两种技巧
教你从Windows10彻底删除Flash的两种技巧Flash终于⾛向⽣命的终结!过去⼏年,业界⼀直在不断提醒⽤户,Flash将会在2021年彻底淘汰,呼吁⼤家卸载Flash。
现在Flash的终点已经到来,Flash的开发商Adobe⾃⾝也强烈建议⽤户马上卸载Flash。
微软也表⽰,将会在未来的更新中,将Flash从系统中删除。
那么问题来了,如果现在就想要彻底从Windows 10中卸载Flash,要怎么做?Windows 10中⽆法⾃⾏卸载系统⾃带的Flash,只能在浏览器禁⽤在Windows 10中,Flash是系统⾃带的,我们⽆法直接通过应⽤管理来找到Flash,所以也没法从系统设置或者控制⾯板中卸载它。
Flash的路径为“C:\Windows\System32\Macromed\Flash”,通过直接删除相应的⽂件来清理掉Flash,也太过简单粗暴,可能会引发其他问题,并不推荐⼤家这么做。
Flash存在于Windows 10的系统⽬录中Edge浏览器提供了禁⽤Flash的功能,但这并不意味着Flash已经从Windows 10中卸载掉。
如果你对Flash存在洁癖,那就⼀起来看看如何彻底在Windows 10中删除Flash吧。
⽅法⼀:通过Windows KB4577586补丁卸载这是微软官⽅提供的补丁,唯⼀作⽤就在于从系统中彻底删除Flash。
⽬前KB4577586仍未通过Windows Update向⽤户推送,但我们可以⼿动下载安装它。
注意,KB4577586补丁的下载页⾯中,列表提供了对应不同系统的版本,⽽且列表有两页。
如果你⽬前使⽤最新的Windows 10 20H2系统,那么可以在第⼆页中找到⽤于x86/x64/ARM64(取决⽤的是64位、32位或者是ARM版本系统)的“Windows 10 Version 2004”的版本,这个版本的补丁适⽤于Windows 10 1903之后的系统。
“擦”控制程序
“块擦除”控制程序//程序功能:控制FLASH“擦”操作/*程序流程:第一,读取FLASH第一块已经存好的的无效块信息,判断第一块是否有效,若无效,块地址加1,继续判断下一块是否有效,若有效,进行第二个环节。
第二,对有效块进行“擦”操作。
首先,由FPGA发60h进行擦命令建立,由于FLASH擦除是以块为单位的,所以接下来只需再发给FLASH三个行地址。
然后,再发擦除确认命令D0h,等待一定的时间让FLASH擦除该块,最后,检测由FLASH反馈给FPGA的I/O0是否为0,若I/O0=0,则擦除成功,若I/O0=1,则擦除失败。
第三,对FLASH的所有块都进行如上操作,直到擦除完最后一块有效块为止。
module erase_cesu(clk,rst,start,cle,ce1,ce2,we,ale,re,wp,data_in,data_out,invalid_info,state,erase_flash_link,erase_flag,erase_addr,erase_ram_read_en);input clk,rst,start;input invalid_info; //无效块信息input [7:0]data_in; // FlASH反馈给FPGA的数据,用于检测// I/O0的值,来说明“擦”是否成功output cle,ce1,we,ale,re,wp;output erase_flag,erase_flash_link;output [7:0]data_out; //FPGA给FLASH的数据或地址output [4:0] state;output [33:0]erase_addr; //[33:31]擦片选地址;//[30:18]擦块地址;//[17:12]擦页地址;//[11:0]擦每一页2048个字节的地址output erase_ram_read_en;reg cle,ce,we,ale,re,wp,erase_flag;reg erase_flash_link,data_from_flash;reg [7:0]data_out;reg [4:0] state;reg [16:0]wait_cycle;reg [33:0]erase_addr;reg erase_ram_read_en;assign ce1 = (erase_addr[33:31]==3'd0)? ce : 1;//ce=0,擦FLASH第一小片assign ce2 = (erase_addr[33:31]==3'd1)? ce : 1;//ce=1,擦FLASH第二小片parameter step1 = 5'd0,step2 = 5'd1,step3 = 5'd2,step4 = 5'd3,step5 = 5'd4,step6 = 5'd5,step7 = 5'd6,step8 = 5'd7,step9 = 5'd8,step10 = 5'd9,step11 = 5'd10,step12 = 5'd11,step13 = 5'd12,step14 = 5'd13,step15 = 5'd14,step16 = 5'd15,step17 = 5'd16,step18 = 5'd17,step19 = 5'd18,step20 = 5'd19,step21 = 5'd20,step22 = 5'd21,step23 = 5'd22,step24 = 5'd23,step25 = 5'd24,step26 = 5'd25,step28 = 5'd27,step29 = 5'd28,step30 = 5'd29,step31 = 5'd30,step32 = 5'd31;always@(posedge clk)beginif(!rst)beginstate<=0;cle<=1'b0;ce<=1'b1;we<=1'b1;ale<=1'b0;re<=1'b1;erase_flash_link<=1'b0;wait_cycle<=0;wp<=1'b1;erase_addr[33:31]<=0;erase_addr[30:18]<=0;erase_addr[17: 0]<=0;endelse if(start==0)beginstate<=0;cle<=1'b0;ce<=1'b1;we<=1'b1;re<=1'b1;elsecase(state)step1:begince<=1'b0;erase_ram_read_en<=0;state<=step2;endstep2:begince<=1'b0;erase_ram_read_en<=1;//读取效块信息state<=step3;endstep3:beginerase_ram_read_en<=0;state<=step4;endstep4:begince<=1'b0;erase_ram_read_en<=0;state<=step5;endstep5:beginerase_ram_read_en<=0;state<=step6;endstep6:begince<=1'b0;erase_ram_read_en<=0;state<=step7;endstep7:beginerase_ram_read_en<=0;state<=step8;endstep8://begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;erase_flag<=1'b0;erase_flash_link<=1'b0;wp<=1'b0;if(invalid_info==1) //判断该块是否为有效块beginstate<=step9;erase_addr<=erase_addr;endelsebeginerase_addr[33:18]<=erase_addr[33:18]+1;if(erase_addr[33:18]==16'd16383)beginstate<=step32;erase_flag<=1'b1;endelsebeginerase_flag<=1'b0;state<=step1;endendendstep9:begincle<=1'b1;ce<=1'b0;we<=1'b0;ale<=1'b0;re<=1'b1;wp<=1'b1;erase_flag<=1'b0;erase_flash_link<=1'b0;data_out<=8'h60;//擦建立命令wait_cycle<=0;state<=step10;endstep10:begincle<=1'b1;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;erase_flag<=1'b0;erase_flash_link<=1'b0;state<=step11;endstep11:begincle<=1'b0;ce<=1'b0;we<=1'b0;ale<=1'b1;re<=1'b1;wp<=1'b1;erase_flash_link<=1'b0;data_out[7:0]<=erase_addr[19:12];//行地址低8位state<=step12;endstep12:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b1;re<=1'b1;erase_flash_link<=1'b0;state<=step13;endstep13:begincle<=1'b0;ce<=1'b0;we<=1'b0;ale<=1'b1;re<=1'b1;erase_flash_link<=1'b0;data_out[7:0]<=erase_addr[27:20];//行地址次8位state<=step14;endstep14:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b1;re<=1'b1;erase_flash_link<=1'b0;state<=step15;endstep15:begincle<=1'b0;ce<=1'b0;we<=1'b0;ale<=1'b1;re<=1'b1;data_out[7:3]<=5'd0;data_out[2:0]<=erase_addr[30:28];//行地址高3位erase_flash_link<=1'b0;state<=step16;endstep16:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b1;re<=1'b1;erase_flash_link<=1'b0;state<=step17;endstep17:begincle<=1'b1;ce<=1'b0;we<=1'b0;ale<=1'b0;re<=1'b1;erase_flash_link<=1'b0;data_out[7:0]<=8'hd0;//擦确认命令state<=step18;endstep18:begincle<=1'b1;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;wp<=1'b1;erase_flash_link<=1'b0;state<=step19;endstep19:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;erase_flash_link<=1'b0;data_out[7:0]<=8'h0;state<=step20;endstep20:beginstate<=step21;endstep21:beginstate<=step22;endstep22:beginstate<=step23;endstep23:beginwait_cycle<=wait_cycle+1;if(wait_cycle==100000)//擦等待时间beginstate<=step24;wait_cycle<=0;endelsebeginstate<=step23;endendstep24:begincle<=1'b1;ce<=1'b0;we<=1'b0;ale<=1'b0;re<=1'b1;data_out[7:0]<=8'h70;//判断“擦”是否成功的命令state<=step25;endstep25:begincle<=1'b1;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;state<=step26;endstep26:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;erase_flash_link<=1'b1;data_out[7:0]<=8'h0;state<=step27;endstep27:beginstate<=step28;endstep28:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b0;data_from_flash<=data_in[0];//读I/O0的值,//若I/O0=0,擦成功//若I/O0=1,擦失败state<=step29;endstep29:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;wp<=1'b1;state<=step30;endstep30:beginif(data_from_flash==1'b1)state<=step31;elsebeginif(erase_addr[33:18]==16'd16383)begin //[33:31]=1;state<=step32; //[30:18] =8192erase_flag<=1'b1;//整片FLSAH全擦完的标志endelsebeginerase_flag<=1'b0;state<=step31;endendendstep31:beginerase_addr[33:18]<=erase_addr[33:18]+1;erase_addr[17: 0]<=0;erase_flag<=1'b0;state<=step1;endstep32:begincle<=1'b0;ce<=1'b0;we<=1'b1;ale<=1'b0;re<=1'b1;erase_flash_link<=1'b0;erase_flag<=erase_flag;wait_cycle<=0;wp<=1'b1;state<=step32;enddefault:state<=step1;endcaseendendmodule/**************“擦”控制程序结束****************/。
NAND flash读写擦除操作
NAND flash读写擦除操作本文主要介绍SAMSUNG公司的S3C2410处理器和K9F1208NAND flash的读写擦除操作。
一、K9F1208NAND flash芯片介绍S3C2410处理器集成了8位NAND flash控制器。
因NAND flash K9F1208、K9F1G08的数据页大小分别为512B、2KB,在寻址方式上有一定的差异,所以程序代码并不通用。
K9F1208的器件存储容量为64M字节和2048K字节的spare存储区,8位I/O 端口采用地址、数据和命令复用的方法。
该器件的引脚图如下所示该器件的引脚功能描述如下表所示引脚名称英文描述描述I/O0~I/O7Data input/outputs数据输入输出CLE Command latch enable命令锁存使能ALE Address latch enable地址锁存使能CE#Chip enable片选RE#Read enable读使能WE#Write enable写使能WP#Write protect写保护R/B#Ready/Busy output准备好/忙碌输出VCC Power(+2.7V~3.6V)电源(+2.7V~3.6V)VSS Ground地N.C No connection空引脚NAND flash的数据是以bit的方式保存在memory cell。
一般一个cell中只能存储一个bit。
这些cell以8个或者16个为单位,连成bit line,形成所谓的byte(X8)/word(X16),这就是NAND device的位宽。
这些line组成page,page再组织形成一个block。
K9F1208的相关数据如下:1block=32page;1page=528byte=512byte(main area)+16byte(spare area)总容量为=4096(block)*32(page/block)*512(byte/page)=64MBNAND flash以页为单位读写数据,而以块为单位擦除数据。
Flash存储器的在线擦写方法
除了有512个保留字节不能使用之外,还有两个字节的安全锁定字节以保护FLASH。读锁定字节的每一为控制一个大小为8K的存储区域,对应关系如图3所示。写/擦除锁定字节也一样,每一位控制一个8K的存储区域。
图3
5. 用MOVX 指令向待擦除扇区内的任何一个地址写入一个数据字节。
6. 清除PSEE 以禁止FLASH 扇区擦除。
7. 用MOVX 指令向刚擦除的扇区中所希望的地址写入数据字节。重复该步直到所有字
节பைடு நூலகம்已写入(目标扇区内)。
8. 清除PSWE 以禁止FLASH 写,使MOVX 操作指向XRAM 数据空间。
在对FLASH存储器进行写操作前,必须将其进行擦除。由于FLASH写操作是用MOVX指令实现的,所以用于写或擦除的FLASH指针必须是xdata类型
本文内容根据一下资料整理:
1.《C8051F020/1/2/3混合信号ISP FLASH维控制器数据手册》 潘琢金译
EA=1; //重新允许中断
}
void main(void)
{ WDTCN=0xde;
WDTCN=0xad;
//Add initialization code here
P1MDOUT=0xff;
ReadState();
#include<c8051f020.h>
unsigned char test; //保存输出状态
//在FLASH中保存输出状态
/*For reading*/
unsigned char code test_c _at_ 0xCF20;
/*For writing*/
unsigned char xdata test_x _at_ 0xCF20;
NANDflash读写擦除操作
NANDflash读写擦除操作NAND flash读写擦除操作本⽂主要介绍SAMSUNG公司的S3C2410处理器和K9F1208NAND flash的读写擦除操作。
⼀、K9F1208NAND flash芯⽚介绍S3C2410处理器集成了8位NAND flash控制器。
因NAND flash K9F1208、K9F1G08的数据页⼤⼩分别为512B、2KB,在寻址⽅式上有⼀定的差异,所以程序代码并不通⽤。
K9F1208的器件存储容量为64M字节和2048K字节的spare存储区,8位I/O 端⼝采⽤地址、数据和命令复⽤的⽅法。
该器件的引脚图如下所⽰该器件的引脚功能描述如下表所⽰引脚名称英⽂描述描述I/O0~I/O7Data input/outputs数据输⼊输出CLE Command latch enable命令锁存使能ALE Address latch enable地址锁存使能CE#Chip enable⽚选RE#Read enable读使能WE#Write enable写使能WP#Write protect写保护R/B#Ready/Busy output准备好/忙碌输出VCC Power(+2.7V~3.6V)电源(+2.7V~3.6V)VSS Ground地N.C No connection空引脚NAND flash的数据是以bit的⽅式保存在memory cell。
⼀般⼀个cell中只能存储⼀个bit。
这些cell以8个或者16个为单位,连成bit line,形成所谓的byte(X8)/word(X16),这就是NAND device的位宽。
这些line组成page,page再组织形成⼀个block。
K9F1208的相关数据如下:1block=32page;1page=528byte=512byte(main area)+16byte(spare area)总容量为=4096(block)*32(page/block)*512(byte/page)=64MBNAND flash以页为单位读写数据,⽽以块为单位擦除数据。
MCU的Flash操作(擦除﹑写入和读出) 实验报告
武 夷 学 院实验报告数学与计算机系实验一 MCU的Flash操作(擦除﹑写入和读出)一、实验目的1、掌握IDE3000软件的使用2、掌握汇编语言基本程序设计二、实验环境1、MT-IDE通用开发套件2、MT-IDE集成开发环境三、实验内容1、建立和打开工程文件2、MCU的Flash操作(擦除、写入和读出)四、实验步骤及结果1、建立和打开工程文件(1)新建工程。
单击文件菜单中的“新建”命令,在“新建”对话框的“新建工程”页中选择工程的路径、工程文件名、工程类型,然后选择MCU型号,工程向导为自动在工程属性中填入该器件的内存设置。
工程属性可选择C工程或者汇编工程。
以上设置好以后点击确定,工程建立成功,如图2-1所示。
工程向导将为用户产生部分该器件的引导代码和程序框架。
(2)新建文件。
单击文件菜单中的“新建”命令,在“新建”对话框的“新建文件”页中选择新建文件的路径、文件名、文件类型,然后选择是否添加到当前工程,以上设置好以后点击确定,新建文件成功,如图2-2所示。
(3)打开工程。
如果用户需要打开已有的工程,可以通过菜单中的“打开工程”命令实现,选择*.prj 文件打开即可。
打开工程时,MT-IDE 集成开发环境会默认选择main.c文件打开,主菜单上会显示Flash操作和调试子菜单,同时工具栏上的可用按钮被激活,2-3所示。
图2-2 新建文件界面(4) 源文件编辑和编译双击目录树上的源文件名,该文件就会被打开,可以进行修改编辑。
编辑器支持语法高亮显示。
源代码编辑完成后,需要通过“编译”生成相应的S19机器码文件。
例如,如果工程文件为abc.prj(工程名为abc),则编译后会在同一文件夹内生成abc.s19文件。
(1)编译设置。
点击编译菜单的编译设置,会出现如图2-4的设置对话框。
在这里可以选择芯片型号,修改器件内存和Flash 区的地址,以及编译器所需头文件的路径。
全局变量设置用来设置程序中全局变量的地址使用单字节还是双字节。
在WinCE下,应用程序直接读写擦除flash设备的方法
WinCEWinCE1WinCEWinCE1在网上的很多论坛中都看到有人提问:应用程序如何直接读写Flash的扇区,或者是类似的问题。
总之,就是希望应用程序能够直接访问Flash设备,直接读写扇区的数据,或者作其他的操作。
这几天没事,就尝试着做了一下,把我的方法介绍给大家。
先做个简单的介绍。
WinCE支持Flash设备,一般指Nandflash或者是NORFlash,采用的架构一般是FAL+FMD架构,我们实现FMD相关的接口函数,Flash的驱动就算完成了。
当WinCE启动以后,我们能够看到Flash设备的磁盘。
我们可以操作磁盘上面的文件,但是不能直接操作flash设备,对Flash设备的操作无非就是:读,写,擦除,读ID。
现在开始介绍实现的方法。
我们如果想在应用程序中直接调用FMD中的FMD_ReadSector(..),FMD_WriteSector(..),FMD_EraseBlock(..)是不太现实的。
这里再补充一下,这三个函数分别是Flash的读扇区,写扇区,擦除块的函数。
好像有点罗嗦了。
但是我们可以在应用程序中调用到FMD_OEMIoControl(..)函数,这个是可以做到的。
所以我们需要改一下Flash设备的驱动程序,也就是改Flash设备驱动中的FMD_OEMIoControl(..)这个函数。
我的改动如下:BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned){PFMDInterface pInterface = (PFMDInterface)pOutBuf;RETAILMSG(1, (TEXT("FMD_OEMIoControl: control code is 0x%x\r\n"), dwIoControlCode));switch(dwIoControlCode){case IOCTL_FMD_GET_INTERFACE:if (!pOutBuf || nOutBufSize < sizeof(FMDInterface)){DEBUGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));return(FALSE);}pInterface->cbSize = sizeof(FMDInterface);pInterface->pInit = FMD_Init;pInterface->pDeInit = FMD_Deinit;pInterface->pGetInfo = FMD_GetInfo;pInterface->pGetInfoEx = NULL; //FMD_GetInfoEx;pInterface->pGetBlockStatus = FMD_GetBlockStatus;pInterface->pSetBlockStatus = FMD_SetBlockStatus;pInterface->pReadSector = FMD_ReadSector;pInterface->pWriteSector = FMD_WriteSector;pInterface->pEraseBlock = FMD_EraseBlock;pInterface->pPowerUp = FMD_PowerUp;pInterface->pPowerDown = FMD_PowerDown;pInterface->pGetPhysSectorAddr = NULL;pInterface->pOEMIoControl = FMD_OEMIoControl;break;case 0xff123456:FMD_ReadSector(..); //调用读Sector函数break;case 0xff654321:FMD_WriteSector(..); //调用写Sector函数break;case 0xff123457:FMD_EraseBlock(..); //调用擦除Block函数break;default:DEBUGMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));return(FALSE);}return(TRUE);}在FMD_OEMIoControl(..)函数里面增加了3个case,这3个case里面调用了读/写/擦除函数。
分享stm32 flash 擦除(以及防止误擦除程序代码)写入
分享STM32 FLASH 擦除(以及防止误擦除程序代码)、写入编译环境:我用的是(Keil)MDK4.7.2stm32库版本:我用的是3.5.0一、本文不对FLASH的基础知识做详细的介绍,不懂得地方请查阅有关资料。
对STM32 内部FLASH进行编程操作,需要遵循以下流程:FLASH解锁清除相关标志位擦除FLASH(先擦除后写入的原因是为了工业上制作方便,即物理实现方便)写入FLASH锁定FLASH实例:#define FLASH_PAGE_SIZE ((uint16_t)0x400) //如果一页为1K大小#define WRITE_START_ADDR((uint32_t)0x08008000)//写入的起始地址#define WRITE_END_ADDR((uint32_t)0x0800C000)//结束地址uint32_t EraseCounter = 0x00, Address = 0x00;//擦除计数,写入地址uint32_t Data = 0x3210ABCD;//要写入的数据uint32_t NbrOfPage = 0x00;//记录要擦除的页数volatile FLASH_Status FLASHStatus =FLASH_COMPLETE;/*FLASH擦除完成标志*/void main(){/*解锁FLASH*/FLASH_Unlock();/*计算需要擦除FLASH页的个数*/NbrOfPage = (WRITE_END_ADDR -WRITE_START_ADDR) / FLASH_PAGE_SIZE;/* 清除所有挂起标志位*/FLASH_ClearFlag(FLASH_FLAG_EOP |FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); /* 擦除FLASH 页*/for(EraseCounter = 0; (EraseCounter < NbrOfPage)&& (FLASHStatus == FLASH_COMPLETE); EraseCounter++){FLASHStatus =FLASH_ErasePage(WRITE_START_ADDR +(FLASH_PAGE_SIZE * EraseCounter));}/* 写入FLASH */Address = WRITE_START_ADDR;while((Address < WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE)){FLASHStatus = FLASH_ProgramWord(Address, Data);Address = Address + 4;}/* 锁定FLASH */FLASH_Lock();}二、FLASH 擦除(以及防止误擦除程序代码)1、擦除函数FLASH_Status FLASH_ErasePage(u32 Page_Address)只要()里面的数是flash第xx页中对应的任何一个地址!就是擦除xx页全部内容!防止误擦除有用程序代码的方法方法一:首先要计算程序代码有多少,把FLASH存取地址设置在程序代码以外的地方,这样就不会破坏用户程序。
flash擦除原理
flash擦除原理
Flash擦除原理是指将Flash中的数据擦除或删除的一种技术。
Flash擦除原理的实现是基于半导体存储器的物理操作,通过擦除电荷填充,可以将单个Flash存储单元的状态
从“1”转换为“0”。
Flash内存是一种非易失性存储器,通常用于存储代码和数据。
Flash存储器是基于电荷填充的存储技术,可以以非常紧凑的方式存储大量数据。
当由于某些原因需要更改
Flash存储器中的数据时,需要先将存储单元擦除,再将新数据写入。
Flash内存中的每个存储单元都由一对闪存晶体管组成,一个晶体管用于控制存储单
元的读取操作,另一个晶体管用于控制存储单元的擦除和写入。
晶体管中的电子(或称为
电子行程)被用于存储数据,每个存储单元可以存储一个或多个行程。
在擦除Flash存储
器之前,存储单元中的电子必须被清除。
Flash存储器中的每个存储单元通过通道(或Word Line)来访问。
当擦除某个存储单元时,Flash存储器的控制电路将通道的电压提高到足够高的电压,这需要数百倍于通常
的工作电压。
这样就可以使存储单元中的电子冲出晶体管,并返回到闪存晶体管上,从而
将存储单元中存储的数据清空。
擦除Flash存储器的速度比写入速度慢得多。
因此,Flash擦除操作通常是静态操作,并且是在应用程序中已知的计划时间内进行的。
因为擦除操作需要大量时间和资源,所以
在应用程序中必须精心管理Flash存储器的使用,以避免频繁擦除操作,从而减少Flash
存储器的使用寿命。
STM32:Flash擦除与读写操作(HAL库)
STM32:Flash擦除与读写操作(HAL库)应⽤平台:STM32F030F4P6ST官⽅库:STM32Cube_FW_F0_V1.9.0背景知识绝⼤多数的单⽚机和微控制器(ARM,x86),地址空间都是以字节为单位的,也就是说⼀个地址是⼀个字节。
Flash存储器有个特点,就是只能写0,不能写1。
所以如果原来的地址有数据了,意味着有⼀些位为0,这些位就相当于⽆效了。
所以必须写之前确保他们都为1,只有擦除才可以。
另外每次擦除都必须擦除⼀个4K⼤⼩的扇区,这是flash的特性所决定的。
对Flash操作前必需打开内部振荡器。
STM32F030F4P6的Flash存储简介STM32F030F4P6硬件配置: FLASH (16KB) RAM (4KB)(包含4个扇区,1个扇区包含4个页,每页有1Kbyte空间)⽤户可以对Flash进⾏program 和 erase 操作。
Main Flash memory programmingThe main Flash memory can be programmed 16 bits at a time.Flash memory eraseThe Flash memory can be erased page by page or completely (Mass Erase).Flash memory addresses Size(byte)Name Description0x0800 0000 - 0x0800 03FF 1 Kbyte Page 0Sector 00x0800 0400 - 0x0800 07FF 1 Kbyte Page 1Sector 00x0800 0800 - 0x0800 0BFF 1 Kbyte Page 2Sector 00x0800 0C00 - 0x0800 0FFF 1 Kbyte Page 3Sector 00x0800 1000 - 0x0800 13FF 1 Kbyte Page 4Sector 10x0800 1400 - 0x0800 17FF 1 Kbyte Page 5Sector 10x0800 1800 - 0x0800 1BFF 1 Kbyte Page 6Sector 10x0800 1C00 - 0x0800 1FFF 1 Kbyte Page 7Sector 10x0800 2000 - 0x0800 23FF 1 Kbyte Page 8Sector 20x0800 2400 - 0x0800 27FF 1 Kbyte Page 9Sector 20x0800 2800 - 0x0800 2BFF 1 Kbyte Page 10Sector 20x0800 2C00 - 0x0800 2FFF 1 Kbyte Page 11Sector 20x0800 3000 - 0x0800 33FF 1 Kbyte Page 12Sector 30x0800 3400 - 0x0800 37FF 1 Kbyte Page 13Sector 30x0800 3800 - 0x0800 3BFF 1 Kbyte Page 14Sector 3Flash memory addresses Size(byte)Name Description0x0800 3C00 - 0x0800 3FFF 1 Kbyte Page 15Sector 3 STM32F030F4P6的Flash读写参考代码(HAL库)/* Base address of the Flash sectors */#define ADDR_FLASH_PAGE_0 ((uint32_t)0x08000000) /* Base @ of Page 0, 1 Kbyte */#define ADDR_FLASH_PAGE_1 ((uint32_t)0x08000400) /* Base @ of Page 1, 1 Kbyte */#define ADDR_FLASH_PAGE_2 ((uint32_t)0x08000800) /* Base @ of Page 2, 1 Kbyte */#define ADDR_FLASH_PAGE_3 ((uint32_t)0x08000C00) /* Base @ of Page 3, 1 Kbyte */#define ADDR_FLASH_PAGE_4 ((uint32_t)0x08001000) /* Base @ of Page 4, 1 Kbyte */#define ADDR_FLASH_PAGE_5 ((uint32_t)0x08001400) /* Base @ of Page 5, 1 Kbyte */#define ADDR_FLASH_PAGE_6 ((uint32_t)0x08001800) /* Base @ of Page 6, 1 Kbyte */#define ADDR_FLASH_PAGE_7 ((uint32_t)0x08001C00) /* Base @ of Page 7, 1 Kbyte */#define ADDR_FLASH_PAGE_8 ((uint32_t)0x08002000) /* Base @ of Page 8, 1 Kbyte */#define ADDR_FLASH_PAGE_9 ((uint32_t)0x08002400) /* Base @ of Page 9, 1 Kbyte */#define ADDR_FLASH_PAGE_10 ((uint32_t)0x08002800) /* Base @ of Page 10, 1 Kbyte */#define ADDR_FLASH_PAGE_11 ((uint32_t)0x08002C00) /* Base @ of Page 11, 1 Kbyte */#define ADDR_FLASH_PAGE_12 ((uint32_t)0x08003000) /* Base @ of Page 12, 1 Kbyte */#define ADDR_FLASH_PAGE_13 ((uint32_t)0x08003400) /* Base @ of Page 13, 1 Kbyte */#define ADDR_FLASH_PAGE_14 ((uint32_t)0x08003800) /* Base @ of Page 14, 1 Kbyte */#define ADDR_FLASH_PAGE_15 ((uint32_t)0x08003C00) /* Base @ of Page 15, 1 Kbyte *//* Private define ------------------------------------------------------------*/#define FLASH_USER_START_ADDR ADDR_FLASH_PAGE_15 /* Start @ of user Flash area */#define FLASH_USER_END_ADDR ADDR_FLASH_PAGE_15 + FLASH_PAGE_SIZE /* End @ of user Flash area */#define DATA_32 ((uint32_t)0x12345678)/*Variable used for Erase procedure*/static FLASH_EraseInitTypeDef EraseInitStruct;uint32_t Address = 0;/*** @brief Main program* @param None* @retval None*/int main(void){/* STM32F0xx HAL library initialization:- Configure the Flash prefetch- Systick timer is configured by default as source of time base, but usercan eventually implement his proper time base source (a general purposetimer for example or other time source), keeping in mind that Time baseduration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined andhandled in milliseconds basis.- Low Level Initialization*/HAL_Init();/* Configure the system clock to48 MHz */SystemClock_Config();/* Unlock the Flash to enable the flash control register access *************/HAL_FLASH_Unlock();/* Erase the user Flash area(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********//* Fill EraseInit structure*/EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK){/*Error occurred while page erase.User can add here some code to deal with this error.PageError will contain the faulty page and then to know the code error on this page,user can call function 'HAL_FLASH_GetError()'*//* Infinite loop */while (1){/* User doing something here */}}/* Program the user Flash area word by word(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/Address = FLASH_USER_START_ADDR;while (Address < FLASH_USER_END_ADDR){if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) == HAL_OK){Address = Address + 4;}else{/* Error occurred while writing data in Flash memory.User can add here some code to deal with this error */while (1){/* User doing something here */}}}/* Lock the Flash to disable the flash control register access (recommendedto protect the FLASH memory against possible unwanted operation) *********/HAL_FLASH_Lock();/* Check if the programmed data is OKMemoryProgramStatus = 0: data programmed correctlyMemoryProgramStatus != 0: number of words not programmed correctly ******/Address = FLASH_USER_START_ADDR;MemoryProgramStatus = 0x0;while (Address < FLASH_USER_END_ADDR){data32 = *(__IO uint32_t *)Address;if (data32 != DATA_32){MemoryProgramStatus++;}Address = Address + 4;}/*Check if there is an issue to program data*/if (MemoryProgramStatus == 0){/* User doing something here */}elseelse{while (1){/* User doing something here */ }}/* Infinite loop */while (1){}}。
Linux下flash操作读、写、擦除步骤
Linux下flash操作读、写、擦除步骤
1、背景介绍
在板上,ZYNQ PL部分通过EMC连接一片NOR FLASH,地址空间如下:
可以看到NOR FLASH的起始地址为0x80000000,这是物理地址,可以把数据存放在以该地址起始的一段区域。
需要注意的是,在对NOR FLASH进行读写数据时,需要参考对应的datasheet,例如这里选用的NOR FLASH读、写、擦除步骤如下:
通过上面的表格就知道进行相应操作每一步该做什么,可以转换为SDK中裸奔程序的C 代码。
2、Linux下flash操作之前提到过zynq中Linux用户应用程序可以通过/dev/mem访问到物理地址,xil_in32和xil_out32等裸奔程序中常见的函数可以通过这一机制移植到linux 下。
于是,对flash的操作其实就是基于xil_in和xil_out对物理地址进行读写。
这里只需要实现三个函数,erase,write_sector以及read_sector.代码如下:
//xil_io.h
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PAGE_SIZE ((size_t)getpagesize())。
单片机读写flash防错算法
单片机是指整个系统只包含一个微处理器(CPU)、存储器(ROM、RAM)、I/O设备(串口、并口、中断设备等),与其他外围集成电路(IC)如定时器、ADC、LCD驱动芯片等外设器件共同构成。
单片机应用广泛,功耗低、体积小、性能稳定可靠,在嵌入式系统领域有着广泛的应用。
Flash是一种非易失存储器,具有读写速度快、寿命长、抗震动、防潮湿、防刮擦等优点,广泛应用于各种嵌入式设备中。
在单片机系统中,Flash常用于存储程序、数据等信息。
在单片机读写Flash时,由于环境、设备等因素的影响,可能会发生读写错误,为了保证数据的正确性和完整性,需要对Flash读写进行错误检测和纠正。
本文将介绍单片机读写Flash时的防错算法。
1. 错误检测在单片机读取Flash数据时,由于电路、线路等原因,可能会发生数据错误。
为了检测这些错误,可以通过校验和、CRC校验、哈希校验等算法对读取的数据进行检测。
校验和是将数据进行累加或取反求和,然后将结果与一个已知值进行比较,如果相等则数据正确;CRC校验是通过生成多项式对数据进行计算,得到一个校验值,然后将该校验值与发送方发送的校验值进行比较,一致则数据正确;哈希校验是通过对数据进行哈希算法计算得到一个哈希值,然后将该哈希值与预先存储的哈希值进行比较,一致则数据正确。
通过这些算法可以对读取的Flash数据进行错误检测。
2. 错误纠正除了进行错误检测外,还可以对读取的Flash数据进行错误纠正。
最常用的错误纠正算法是BCH算法和RS算法。
BCH算法是一种纠删码算法,通过对数据进行编码和解码,可以对数据进行错误纠正和恢复。
RS算法是一种重要的纠删码算法,具有编码简单、性能优秀等特点,广泛应用于数据存储和通信领域。
通过使用这些算法,可以对读取的Flash数据进行错误纠正,保证数据的正确性和完整性。
3. 算法实现以上介绍了单片机读写Flash防错算法的原理和方法,接下来将介绍如何在单片机系统中实现这些算法。
flash擦写方式
flash擦写方式一、概述Flash擦写是指将Flash存储器中的数据全部或部分清除并重新写入新的数据的过程。
Flash存储器是一种非易失性存储器,因此在擦写过程中需要特别小心以避免数据丢失或损坏。
二、Flash存储器的结构Flash存储器通常由多个块组成,每个块又由多个扇区组成。
每个扇区包含一个或多个页面,每个页面包含若干字节的数据。
三、Flash擦写方式1. 扇区擦除方式扇区擦除是最常见的Flash擦写方式。
它通过将整个扇区中所有页面的数据清除来实现。
这种方式可以确保所有数据都被清除,但也会导致擦写时间较长。
2. 页面擦除方式页面擦除是一种相对较快的Flash擦写方式。
它只会清除指定页面中的数据,而不影响其他页面。
但是,这种方式可能会导致某些未使用的空间被占用,从而降低了可用空间。
3. 块擦除方式块擦除是一种比较特殊的Flash擦写方式。
它通过将整个块中所有扇区的数据清除来实现。
这种方式可以确保所有数据都被清除,并且擦写时间相对较短。
但是,它也会导致块内所有数据丢失。
四、Flash擦写流程1. 擦除Flash擦写的第一步是擦除。
在这个阶段,需要将要写入的扇区或页面中的所有数据清除掉,以确保不会出现任何残留数据干扰新数据的写入。
2. 编程编程是指将新数据写入Flash存储器中。
在这个阶段,需要将新数据逐个字节地写入到指定的扇区或页面中。
3. 验证验证是指检查已经编程的数据是否正确地存储在Flash存储器中。
在这个阶段,需要读取刚刚编程的数据并与原始数据进行比较,以确保两者完全一致。
五、注意事项1. 擦写次数限制Flash存储器有一个重要的特点:每次擦写都会减少其寿命。
因此,在进行Flash擦写时应该尽量减少不必要的操作,避免过多地使用同一个扇区或页面。
2. 操作顺序在进行Flash擦写时应该按照正确的顺序执行各个步骤:首先是擦除、然后是编程、最后是验证。
如果顺序出错,可能会导致数据丢失或损坏。
WINCE6.0下的nandflash驱动
WINCE6.0下的nandflash驱动(基于K9F1G08U0B)********************************LoongEmbedded********************************作者:LoongEmbedded时间:2010.11.26类别:WINCE驱动开发********************************LoongEmbedded******************************** 1.nandflash驱动架构概述图1Windows CE下的FLASH驱动分为两层,分别为FMD层和FAL层(flash abstraction layer),FMD (Flash Media Driver)属于底层,直接操作Flash硬件,比如读、写和擦除等,不同的Flash 硬件则FMD_XXX接口实现函数各不相同,上层则是FAL (Flash Abstraction Layer)层,该层是由微软实现并提供的,是一个与硬件无关的层,可用于FAL层实现扇区的动态分配和坏块管理等。
FAL层向应用层(如API)提供DSK接口。
例如CreateFile中调用的设备即是调用该FAL层提供的接口。
FMD层暴露FMD_XXX让FAL层调用。
在PB中的阐述如下:The flash media driver (FMD) is a device driver that performs the actual input and output of data to a flash memory device. An FMD contains all of the device-specific code necessary for read, write, and erase commands to the flash memory device. You can link the FMD with the flash abstraction layer (FAL) to create a block driver that a file system such as FAT can use. You can also link the FMD with a boot loader so that the boot loader can flash a run-time image.2.FAL和FMD对应的实现代码部分首先我们知道是由FAL+FMD smflash.dll的,下面看看FAL和FMD分别对应哪些代码:2.1 FAL层FAL: \WINCE600\PRIVATE\WINCEOS\DRIVERS\MSFLASH,这个文件夹下的代码编译出fal.lib也就是说FAL层是以fal.lib供链接的,fal.lib的导出文件内容如下:LIBRARY MSFLASHEXPORTSDSK_InitDSK_DeinitDSK_OpenDSK_CloseDSK_ReadDSK_WriteDSK_SeekDSK_IOControlDSK_PowerDownDSK_PowerUp从上面的导出函数可知FAL层向应用层(如API)提供DSK接口2.2 FMD层smflash_lib.lib:\WINCE600\PLATFORM\DMA2443\Src\Common\Smartmedia\fmd,这个文件下的代码生成smflash_lib.lib,而\WINCE600\PLATFORM\DMA2443\Src\Common\Smartmedia\Dll 文件夹将生成smflash.dll,下面是其sources的内容:TARGETNAME=smflashTARGETTYPE=DYNLINKRELEASETYPE=PLATFORMWINCEOEM=1DEFFILE=smflash.defTARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib \SOURCELIBS=$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\fal.lib \$(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\smflash_lib.lib可以知道smflash.dll需要链接fal.lib和smflash_lib.lib这个两个库,而fal.lib就是FAL层提供的链接库,smflash_lib.lib是FMD层提供的链接库。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
•WinCE下应用程序直接读/写/擦除flash设备的方法•在网上的很多论坛中都看到有人提问:应用程序如何直接读写Flash的扇区,或者是类似的问题。
总之,就是希望应用程序能够直接访问Flash设备,直接读写扇区的数据,或者作其他的操作。
这几天没事,就尝试着做了一下,把我的方法介绍给大家。
在网上的很多论坛中都看到有人提问:应用程序如何直接读写Flash的扇区,或者是类似的问题。
总之,就是希望应用程序能够直接访问Flash设备,直接读写扇区的数据,或者作其他的操作。
这几天没事,就尝试着做了一下,把我的方法介绍给大家。
先做个简单的介绍。
WinCE支持Flash设备,一般指Nandflash或者是NORFlash,采用的架构一般是FAL+FMD架构,我们实现FMD相关的接口函数,Flash的驱动就算完成了。
当WinCE启动以后,我们能够看到Flash设备的磁盘。
我们可以操作磁盘上面的文件,但是不能直接操作flash设备,对Flash设备的操作无非就是:读,写,擦除,读ID。
现在开始介绍实现的方法。
我们如果想在应用程序中直接调用FMD中的FMD_ReadSector(..),FMD_WriteSector(..),FMD_EraseBlock(..)是不太现实的。
这里再补充一下,这三个函数分别是Flash的读扇区,写扇区,擦除块的函数。
好像有点罗嗦了。
但是我们可以在应用程序中调用到FMD_OEMIoControl(..)函数,这个是可以做到的。
所以我们需要改一下Flash设备的驱动程序,也就是改Flash设备驱动中的FMD_OEMIoControl(..)这个函数。
我的改动如下:BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned){PFMDInterface pInterface = (PFMDInterface)pOutBuf;RETAILMSG(1, (TEXT("FMD_OEMIoControl: control code is 0x%x\r\n"), dwIoControlCode));switch(dwIoControlCode){case IOCTL_FMD_GET_INTERFACE:if (!pOutBuf || nOutBufSize < sizeof(FMDInterface)){DEBUGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE badparameter(s).\r\n")));return(FALSE);}pInterface->cbSize = sizeof(FMDInterface);pInterface->pInit = FMD_Init;pInterface->pDeInit = FMD_Deinit;pInterface->pGetInfo = FMD_GetInfo;pInterface->pGetInfoEx = NULL; //FMD_GetInfoEx;pInterface->pGetBlockStatus = FMD_GetBlockStatus;pInterface->pSetBlockStatus = FMD_SetBlockStatus;pInterface->pReadSector = FMD_ReadSector;pInterface->pWriteSector = FMD_WriteSector;pInterface->pEraseBlock = FMD_EraseBlock;pInterface->pPowerUp = FMD_PowerUp;pInterface->pPowerDown = FMD_PowerDown;pInterface->pGetPhysSectorAddr = NULL;pInterface->pOEMIoControl = FMD_OEMIoControl;break;case 0xff123456:FMD_ReadSector(..); //调用读Sector函数break;case 0xff654321:FMD_WriteSector(..); //调用写Sector函数break;case 0xff123457:FMD_EraseBlock(..); //调用擦除Block函数break;default:DEBUGMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));return(FALSE);}return(TRUE);}在FMD_OEMIoControl(..)函数里面增加了3个case,这3个case里面调用了读/写/擦除函数。
至于Case的值,我是随便定义的。
这样Flash设备的驱动部分就改完了。
在改完Flash驱动以后,我下面会提供两种方法,每一种方法都和Flash设备的注册表配置有关:1. 以Nandflash为例,当然对于NORFlash来说大同小异,注册表配置如下:[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NANDFlash]"Dll"="ep94xxnandflash.dll""Prefix"="DSK""Order"=dword:4;"Ioctl"=dword:4"Profile"="NSFlash""IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"; Override names in default profile[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash]"Name"="Ep94xx NAND Flash""Folder"="NANDFlash""PartitionDriver"="MSPart.dll""AutoMount"=dword:1"AutoPart"=dword:1"AutoFormat"=dword:1[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash\FATFS] "EnableCache"=dword:1"CacheSize"=dword:1000"MountBootable"=dword:1"Flags"=dword:00000024"CheckForFormat"=dword:1然后编写应用程序,主要就是通过CreateFile来打开DSK1:设备,然后通过DeviceIoControl(..)函数来调用FMD_OEMIoControl(..)函数,来达到直接读/写/擦除Flash设备的目的。
应用程序代码如下:HANDLE hFirm;hFirm = CreateFile(TEXT("DSK1:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);if(hFirm == INVALID_HANDLE_VALUE){printf("Open Flash Device Failed");return 0;}iRet = DeviceIoControl(hFirm, 0xff123456, para1, para2, para3, para4, para5, para6); //Read Flash SectoriRet = DeviceIoControl(hFirm, 0xff654321, para1, para2, para3, para4, para5, para6); //Write Flash SectoriRet = DeviceIoControl(hFirm, 0xff123457, para1, para2, para3, para4, para5, para6); //Erase Flash Blockprintf("DeviceIoControl OK\r\n");while(1);通过上面的应用程序,就能够调用到Flash设备驱动中的FMD_OEMIoControl(..)函数,这样根据不同的case就可以调用读/写/擦除函数了。
2. 以Nandflash为例,当然对于NORFlash来说大同小异,注册表配置如下:[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NANDFlash]"Dll"="ep94xxnandflash.dll""Prefix"="DSK""Order"=dword:4;"Ioctl"=dword:4"Profile"="NSFlash""IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"; Override names in default profile[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash]"Name"="Ep94xx NAND Flash""Folder"="NANDFlash""PartitionDriver"="MSPart.dll""AutoMount"=dword:1"AutoPart"=dword:1"AutoFormat"=dword:1[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash\FATFS] "EnableCache"=dword:1"CacheSize"=dword:1000"MountBootable"=dword:1"Flags"=dword:00000024"CheckForFormat"=dword:1[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\NSFlash] "DriverPath"="Drivers\\BuiltIn\\NANDFlash""LoadFlags"=dword:0"BootPhase"=dword:1然后编写应用程序,主要就是通过OpenStore来打开NSFlash,然后通过DeviceIoControl(..)函数来调用FMD_OEMIoControl(..)函数,来达到直接读/写/擦除Flash设备的目的。