This article is mainly about the introduction of NOR flash, and focuses on the identification of NOR flash and its working principle.
NOR flash working principleNor Flash has an interface like memory. It can be read like memory but cannot be written like memory. Nor Flash needs to issue specific commands for writing and erasing. When it comes to Nor Flash, it usually involves the CFI ([Common Flash Interface) interface. Normally Nor Flash supports sending commands to read basic information such as manufacturer ID and device ID, but not all Nor Flash
Flash supports sending commands to obtain information such as the size of the chip itself, the number of sectors, and the size of the erased block. In order to make Nor Flash compatible in the future, the CFI interface is introduced, and the information related to the chip is written into the chip, and this information can be obtained through the CFI command.
The Linux kernel has good support for various types of Nor Flash, but its organization is complex, which is not conducive to analysis. Here we use the Nor Flash code in u-boot for analysis. The code is located at: u-boot-2010.06/board/samsung/smdk2410/flash.c.
Generally, there are two ways to identify a Nor Flash in the kernel: one is jedec detection, which is to define an array in the kernel in advance. The array contains some parameters of each chip of different manufacturers. When detecting, the ID and array of the flash are The IDs inside are compared one by one, and if the same is found, the parameters of the array are used. The other is cfi detection, which is to directly send various commands to read the information of the chip, such as ID, capacity, etc. The advantage of jedec detection is that it is simple, but the disadvantage is that if there are many types of flash to be supported by the kernel, this array will be huge. . . The /samsung/smdk2410/flash.c file uses the first method, but there are some differences. The kernel uses
When jedec detects a chip, it first obtains the ID of the flash by sending a command, and then compares it with the array, but even the ID in flash.c is configured by itself through a macro.
unsigned long flash_init (void)
{
for (i = 0; i《CONFIG_SYS_MAX_FLASH_BANKS; i++)
{
ulong flashbase = 0;
//Set flash_id, this flag saves manufacturer ID and device ID
flash_infoï¼»iï¼½.flash_id =
#if defined(CONFIG_AMD_LV400)
(AMD_MANUFACT & FLASH_VENDMASK) | (AMD_ID_LV400B & FLASH_TYPEMASK);
#elif defined(CONFIG_AMD_LV800)
(AMD_MANUFACT & FLASH_VENDMASK) | (AMD_ID_LV800B & FLASH_TYPEMASK);
#else
#error “Unknown flash configuredâ€
#endif
//Set the flash size and number of sectors
flash_infoï¼»iï¼½.size = FLASH_BANK_SIZE;
flash_infoï¼»iï¼½.sector_count = CONFIG_SYS_MAX_FLASH_SECT;
//For each sector of flash, the first address of the sector needs to be saved
for (j = 0; j "flash_infoï¼»i].sector_count; j++)
{
. . .. . .
flash_infoï¼»iï¼½.startï¼»jï¼½ = flashbase + (j-3) * MAIN_SECT_SIZE;
}
size += flash_infoï¼»iï¼½.size; //Total size of all flash off-chip
}
//Set the write protection for the sectors in the code area, here is just a setting of the software
flash_protect (FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE,
CONFIG_SYS_FLASH_BASE + monitor_flash_len-1,
&flash_info [0]);
//If the environment variables are stored in nor, these sectors need to be write-protected
flash_protect (FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
CONFIG_ENV_ADDR + CONFIG_ENV_SIZE-1, &flash_info [0]);
return size; //return flash size
}
The flash_init() function is mainly to do some flash initialization, such as setting the flash ID, size, number of sectors, etc. to construct the flash_info_t structure, but from the above code, it can be seen that there is nothing to do with the hardware in the initialization function. Regarding initialization, all values ​​are assigned externally, which means that we can assign any value we want to these member variables, even if these values ​​are not
The real parameters of flash, although these values ​​do not affect the calling of this function, they are closely related to the following functions.
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
//See if there is a write-protected sector, if there is a direct return error
prot = 0;
for (sect = s_first; sect "= s_last; ++sect)
{
if (info-"protect[sect])
prot++;
}
if (prot)
return ERR_PROTECTED;
//Turn off interrupts, etc. to prevent the erasing process from being interrupted
cflag = icache_status ();
icache_disable ();
iflag = disable_interrupts ();
/* Start erase on unprotected sectors */
for (sect = s_first; sect "= s_last &&! ctrlc (); sect++)
{
printf ("Erasing sector %2d. .. ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
if (info-"protect[sect] == ​​0) //The judgment here is a bit redundant
{/* not protected */
//Take the first address of the sector
vu_short *addr = (vu_short *) (info-"startï¼»sectï¼½);
//Send unlock and erase sector commands
MEM_FLASH_ADDR1 = CMD_UNLOCK1; //Write 0xAA to address 0x555《》1
MEM_FLASH_ADDR2 = CMD_UNLOCK2; //Write 0x55 to address 0x2AA《》1
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;//Write 0x80 to address 0x555《》1
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
*addr = CMD_ERASE_CONFIRM; //Write 0x30 to address 0x555《《1
/* wait until flash is ready */
chip = 0;
do
{
result = *addr; //Read the value in the first address of the sector
/* check timeout */
if (get_timer_masked () "CONFIG_SYS_FLASH_ERASE_TOUT)
{
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
chip = TMO;
break;
}
//BIT_ERASE_DONE = 0x80, that is, to determine whether DQ7 is 1
if (!chip && (result & 0xFFFF) & BIT_ERASE_DONE)
chip = READY;
//BIT_PROGRAM_ERROR = 0x20, that is, to determine whether DQ5 is 1
if (!chip && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
chip = ERR;
} while (!chip);
MEM_FLASH_ADDR1 = CMD_READ_ARRAY; //Write 0xF0 to address 0x555《》1
. . .. . .
printf ("ok.n");
}
else
{/* it was protected */
printf ("protected!n");
}
}
. . .. . .
/* allow flash to settle-wait 10 ms */
udelay_masked (10000);
return rc;
}
How to automatically identify NOR flashWhen Norflash starts:
The 4K internal SRAM is mapped to 0x40000000-0x40001000
When Nandflash starts:
The 4K internal SRAM is mapped to 0x40000000, and also mapped to 0x00000000-0x00001000
So, we can judge whether the data at 0x0000003c is equal to the data at 0x4000003c to determine which startup method is. This address is chosen because the value at this address is fixed at 0xdeadbeef
3c = 60 = 4*15
.globl _start_start: b start_code ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _not_used ldr pc,. data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiq .balignl 16, 0xdeadbeef
The code in start.S is as follows
/***************** CHECK_BOOT_FLASH ******************************* ***********/ ldr r1, = ((4《》28)|(3《》4)|(3《《2)) /* address of Internal SRAM 0x4000003C*/ mov r0, #0 /* r0 = 0 */ str r0, [r1] mov r1, #0x3c /* address of men 0x0000003C*/ ldr r0, [r1] cmp r0, #0 bne relocate /* recovery */ ldr r0, = (0xdeadbeef) ldr r1, = ((4《》28)|(3《》4)|(3《《2)) str r0, [r1]/************** *** CHECK_BOOT_FLASH ******************************************/
The process in Uboot: first clear the data at 0x4000003C at startup, and then read the data at 0x0000003C. If it is 0, it means that this address is mapped at 0x4000003C and 0x0000003C at the same time, which means nandflash starts, which is not equal Then the norflash starts.
But the last point is very important: if Nand flash is started, the cleared data must be restored. The reason is: after nand boot, the 4K program in the internal SRAM will be checked whether it is consistent with the previous 4K program copied from Nand to SDRAM. If it is inconsistent, it will enter an endless loop.
How does nor flash read and write data(1) Nor Flash working mode
Nor Flash is in the data reading state (Reading Array Data) after power on. In this state, normal reading can be performed. This is the same as reading SDRAM/SRAM/ROM. (If it is different, how to read the startup code from Nor Flash after the chip is powered on.~)
Generally, the chip information such as the device ID number must be read before operating the Flash. The main purpose of this is to judge whether the program written by yourself supports the device. Nor Flash supports 2 ways to obtain ID number. One is that the method used by the programmer requires high voltage (11.5V-12.5V). Another method is the so-called in-system method, which is done in the system through the command register of Nor Flash. In this article, only the in-system method is described. At this time, you need to switch to Autoselect Command, which is done by sending a command. The command type is shown in the figure below. note:
After entering the Autoselect Command mode, you need to send a reset command to return to the Reading Array Data state.
After completing the information acquisition, the data is generally erased. Nor Flash supports Sector Erase division and Chip Erase. These two modes have corresponding command sequences. After the erase command is completed, it will automatically return to the Reading Array Data state. You can query the status of programming before returning.
After erasing is completed, it is necessary to write the chip, that is, to program. This needs to enter the programming (Program) state. After completing the programming command, it will automatically return to the Reading Array Data state. You can query the status of programming before returning. Note: It must be erased before programming. Because programming can only rewrite '1' to '0', all data can be erased and written to '1' by erasing.
(2) Nor Flash hardware connection
1. Pin 47 is BYTE#: When it is high, the data output is in 16bit mode (the address line is A19:A0 at this time). Low level is 8bit mode. (At this time, the address line is A19:A1) In the above figure, Pin47 plus VCC selects the 16bit mode and the effective address line is A19:A0.
2. For 16bit mode, 16bit alignment is required, so LADDR1 of S3C2440A must be connected to A0. It should be noted that the address 0x555 on the NorFlash chip corresponds to the address of S3C2440A as baseaddr+0x555*2; the baseaddr is related to the address mapped by NorFlash. Normally NorFlash is placed in Bank0. So baseaddr=0, but baseaddr= the new address mapped to address 0 after mmu is turned on. The reason for 0x555*2 is that LADDR1 is connected to A0. That is, 0x555 represents the 0x555th word (16bit) in the chip.
3. Pin 15 is RYBY# output pin. Used to output Ready and Busy signals. You can leave it out when you actually use it. You can use the command to query the NorFlash status instead.
(3) Nor Flash mode programming
1. Read ID
2. Sector Erase
Each cycle of the sector erase command sequence is a write cycle.
3. Program
4. Write operation status (WRITE OPERATION STATUS)
Nor Flash provides several data bits to determine the status of a write operation. They are: DQ2, DQ3, DQ5, DQ6, DQ7, and RY/BY#. As shown in the figure above. Among them, DQ7, RY/BY# pins, and DQ6 each provide a method to determine whether a program or erase operation has been completed or is in progress. Only one of them needs to be used in actual programming.
DQ7: Data# Polling bit, the state change of DQ7 during programming.
The DQ7 of the data read from the address being programmed during the programming process is the complement of the data to be written. For example, the written data is 0x0000, and the input DQ7 is '0', then the data read during programming is '1'; when the programming is completed, the read data changes back to the input data, which is '0'. During the erasing process, DQ7 outputs '0'; after erasing is completed, the output is '1'; note that the read address must be the ground within the erasing range RY/BY#: high level means'ready', low power Ping means'busy'.
DQ6: Toggle Bit 1 (Toggle Bit 1).
During programming and erasing, reading any address will cause DQ6 to rotate (change between 0 and 1). . When the operation is complete, DQ6 stops conversion.
DQ2: Toggle Bit 2 (Toggle Bit 2). When a certain sector is selected to be erased, reading the effective address (all addresses are within the range of the erased sector) will cause DQ2 to rotate.
Note: DQ2 can only judge whether a specific sector is selected for erasing. But it cannot be distinguished whether the block is being erased or is in the erase pause state. In contrast, DQ6 can distinguish whether NorFlash is in the erasing or erasing state, but it cannot distinguish which one is selected for erasing. Therefore, these 2 bits are needed to determine the sector and mode status information.
DQ5: Exceeded Timing Limits. When the program or erase operation exceeds a specific internal pulse count, DQ5=1; this indicates that the operation has failed. When programming, changing '0' to '1' will cause DQ5=1, because only erasing can change '0' to '1'. When an error occurs, it is necessary to execute a reset command (see Figure 1-1) to return to the state of reading data.
DQ3: (Sector Erase Timer) Sector Erase Timer, which only works during sector erase command. When the erase command actually starts to work, DQ3=1, the commands input at this time (except the erase pause command) are ignored. DQ3=0, it is possible to add additional sectors for multi-sector erasure
ConclusionThis is the end of the related introduction about NOR flash. Please correct me if there are any deficiencies.
Related reading recommendations: Detailed explanation of the difference between NAND flash and NOR flash
Related reading recommendations: a detailed analysis of the difference between NorFlash and NandFlash
Portable Battery ,Portable Power Bank,Portable Battery Pack,Portable Power Pack
Zhejiang Casnovo Materials Co., Ltd. , https://www.casnovonewenergy.com