/***************************************************************************/ /* Copyright (c) 2024 Microsoft Corporation */ /* Copyright (c) 2026 Eclipse ThreadX contributors */ /* */ /* This program and the accompanying materials are made available under */ /* the terms of the MIT License which is available at */ /* https://opensource.org/licenses/MIT. */ /* */ /* SPDX-License-Identifier: MIT */ /***************************************************************************/ // Some portions generated by Codex (GPT-5). /* Basic NOR flash tests... */ #include #include "lx_api.h" #define DEMO_STACK_SIZE 4096 /* Define the ThreadX object control blocks... */ #ifndef LX_STANDALONE_ENABLE TX_THREAD thread_0; #endif UCHAR thread_0_stack[DEMO_STACK_SIZE]; /* Define LevelX structures. */ LX_NOR_FLASH nor_sim_flash; ULONG buffer[128]; ULONG readbuffer[128]; UCHAR nor_cache_memory[2048+16+8]; UCHAR nor_cache_memory2[8192]; UCHAR nor_cache_memory_invalid[256]; #ifndef LX_NOR_DISABLE_EXTENDED_CACHE UCHAR nor_zero_base_cache_memory[512]; ULONG nor_zero_base_memory[LX_NOR_SECTOR_SIZE * 2]; ULONG nor_zero_base_driver_read_count; #endif /* Define LevelX NOR flash simulator prototoypes. */ UINT _lx_nor_flash_simulator_initialize(LX_NOR_FLASH *nor_flash); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE static UINT zero_base_nor_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words); static UINT zero_base_nor_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words); static UINT zero_base_nor_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count); static UINT zero_base_nor_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block); #else static UINT zero_base_nor_read(ULONG *flash_address, ULONG *destination, ULONG words); static UINT zero_base_nor_write(ULONG *flash_address, ULONG *source, ULONG words); static UINT zero_base_nor_block_erase(ULONG block, ULONG erase_count); static UINT zero_base_nor_block_erased_verify(ULONG block); #endif static UINT zero_base_nor_initialize(LX_NOR_FLASH *nor_flash); #endif /* Define thread prototypes. */ void thread_0_entry(ULONG thread_input); /* Define main entry point. */ int main() { /* Enter the ThreadX kernel. */ #ifndef LX_STANDALONE_ENABLE tx_kernel_enter(); #else thread_0_entry(0); #endif } /* Define what the initial system looks like. */ #ifndef LX_STANDALONE_ENABLE void tx_application_define(void *first_unused_memory) { /* Create the main thread. */ tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, thread_0_stack, DEMO_STACK_SIZE, 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); } #endif #ifndef LX_NOR_DISABLE_EXTENDED_CACHE static UINT zero_base_nor_initialize(LX_NOR_FLASH *nor_flash) { UINT status; /* Setup the base address as a logical zero offset. */ nor_flash -> lx_nor_flash_base_address = LX_NULL; /* Setup geometry of the test flash. */ nor_flash -> lx_nor_flash_total_blocks = 1; nor_flash -> lx_nor_flash_words_per_block = LX_NOR_SECTOR_SIZE * 2; /* Setup function pointers for the NOR flash services. */ nor_flash -> lx_nor_flash_driver_read = zero_base_nor_read; nor_flash -> lx_nor_flash_driver_write = zero_base_nor_write; nor_flash -> lx_nor_flash_driver_block_erase = zero_base_nor_block_erase; nor_flash -> lx_nor_flash_driver_block_erased_verify = zero_base_nor_block_erased_verify; /* Setup local buffer for NOR flash operation. */ nor_flash -> lx_nor_flash_sector_buffer = buffer; /* Erase the test flash. */ #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE status = zero_base_nor_block_erase(nor_flash, 0, 0); #else status = zero_base_nor_block_erase(0, 0); #endif /* Return completion status. */ return(status); } #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE static UINT zero_base_nor_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words) #else static UINT zero_base_nor_read(ULONG *flash_address, ULONG *destination, ULONG words) #endif { ULONG offset; #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE LX_PARAMETER_NOT_USED(nor_flash); #endif /* MISRA C:2012 Rule 11.4 deviation: this test driver intentionally treats NOR flash addresses as logical offsets, including zero. */ offset = ((ULONG)flash_address) / sizeof(ULONG); if ((offset + words) > (LX_NOR_SECTOR_SIZE * 2)) { return(LX_ERROR); } nor_zero_base_driver_read_count++; while (words--) { *destination++ = nor_zero_base_memory[offset++]; } return(LX_SUCCESS); } #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE static UINT zero_base_nor_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words) #else static UINT zero_base_nor_write(ULONG *flash_address, ULONG *source, ULONG words) #endif { ULONG offset; #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE LX_PARAMETER_NOT_USED(nor_flash); #endif /* MISRA C:2012 Rule 11.4 deviation: this test driver intentionally treats NOR flash addresses as logical offsets, including zero. */ offset = ((ULONG)flash_address) / sizeof(ULONG); if ((offset + words) > (LX_NOR_SECTOR_SIZE * 2)) { return(LX_ERROR); } while (words--) { nor_zero_base_memory[offset++] = *source++; } return(LX_SUCCESS); } #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE static UINT zero_base_nor_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count) #else static UINT zero_base_nor_block_erase(ULONG block, ULONG erase_count) #endif { ULONG offset; ULONG words; #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE LX_PARAMETER_NOT_USED(nor_flash); #endif LX_PARAMETER_NOT_USED(erase_count); if (block != 0) { return(LX_ERROR); } offset = 0; words = LX_NOR_SECTOR_SIZE * 2; while (words--) { nor_zero_base_memory[offset++] = LX_ALL_ONES; } return(LX_SUCCESS); } #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE static UINT zero_base_nor_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block) #else static UINT zero_base_nor_block_erased_verify(ULONG block) #endif { ULONG offset; ULONG words; #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE LX_PARAMETER_NOT_USED(nor_flash); #endif if (block != 0) { return(LX_ERROR); } offset = 0; words = LX_NOR_SECTOR_SIZE * 2; while (words--) { if (nor_zero_base_memory[offset++] != LX_ALL_ONES) { return(LX_ERROR); } } return(LX_SUCCESS); } #endif /* Define the test threads. */ void thread_0_entry(ULONG thread_input) { ULONG i, j, sector; #ifndef LX_NOR_DISABLE_EXTENDED_CACHE ULONG read_count; ULONG *last_sector_address; #endif UINT status; ULONG *word_ptr; /* Initialize LevelX. */ _lx_nor_flash_initialize(); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE /* Test 0: Extended cache with a zero NOR flash base address. */ printf("Test 0: Extended cache with zero base address...."); LX_MEMSET(&nor_sim_flash, 0, sizeof(nor_sim_flash)); status = zero_base_nor_initialize(&nor_sim_flash); nor_zero_base_memory[0] = 0x12345678; /* MISRA C:2012 Rule 11.6 deviation: this test driver intentionally treats NOR flash addresses as logical offset tokens. */ last_sector_address = (ULONG *)(LX_NOR_SECTOR_SIZE * sizeof(ULONG)); nor_zero_base_driver_read_count = 0; if (status == LX_SUCCESS) { status = lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_zero_base_cache_memory, sizeof(nor_zero_base_cache_memory)); } if (status == LX_SUCCESS) { status = _lx_nor_flash_driver_read(&nor_sim_flash, LX_NULL, readbuffer, 1); } if ((status != LX_SUCCESS) || (readbuffer[0] != 0x12345678) || (nor_zero_base_driver_read_count != 1)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = _lx_nor_flash_driver_read(&nor_sim_flash, LX_NULL, readbuffer, 1); if ((status != LX_SUCCESS) || (readbuffer[0] != 0x12345678) || (nor_zero_base_driver_read_count != 1)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } buffer[0] = 0x87654321; status = _lx_nor_flash_driver_write(&nor_sim_flash, LX_NULL, buffer, 1); if ((status != LX_SUCCESS) || (nor_zero_base_memory[0] != 0x87654321)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = _lx_nor_flash_driver_read(&nor_sim_flash, LX_NULL, readbuffer, 1); if ((status != LX_SUCCESS) || (readbuffer[0] != 0x87654321) || (nor_zero_base_driver_read_count != 1)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } read_count = nor_zero_base_driver_read_count; status = _lx_nor_flash_driver_block_erase(&nor_sim_flash, 0, 0); if (status == LX_SUCCESS) { status = _lx_nor_flash_driver_read(&nor_sim_flash, LX_NULL, readbuffer, 1); } if ((status != LX_SUCCESS) || (readbuffer[0] != LX_ALL_ONES) || (nor_zero_base_driver_read_count != (read_count + 1))) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } nor_zero_base_memory[LX_NOR_SECTOR_SIZE] = 0xABCDEF01; status = _lx_nor_flash_driver_read(&nor_sim_flash, last_sector_address, readbuffer, 1); if ((status != LX_SUCCESS) || (readbuffer[0] != 0xABCDEF01) || (nor_zero_base_driver_read_count != (read_count + 2))) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = _lx_nor_flash_driver_read(&nor_sim_flash, last_sector_address, readbuffer, 1); if ((status != LX_SUCCESS) || (readbuffer[0] != 0xABCDEF01) || (nor_zero_base_driver_read_count != (read_count + 2))) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } read_count = nor_zero_base_driver_read_count; status = _lx_nor_flash_driver_block_erase(&nor_sim_flash, 0, 0); if (status == LX_SUCCESS) { status = _lx_nor_flash_driver_read(&nor_sim_flash, last_sector_address, readbuffer, 1); } if ((status != LX_SUCCESS) || (readbuffer[0] != LX_ALL_ONES) || (nor_zero_base_driver_read_count != (read_count + 1))) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } printf("SUCCESS!\n"); #endif /* Test 1: Simple write 100 sectors and read 100 sectors. */ printf("Test 1: Simple write-read 100 sectors..........."); lx_nor_flash_format(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize, NULL); lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif #ifdef LX_NOR_ENABLE_MAPPING_BITMAP if (nor_sim_flash.lx_nor_flash_extended_cache_mapping_bitmap_max_logical_sector != 128) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } #endif #ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE if (nor_sim_flash.lx_nor_flash_extended_cache_obsolete_count_max_block != 8) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } #endif /* Write 100 sectors.... */ for (i = 0; i < 100; i++) { for (j = 0; j < 128; j++) buffer[j] = i; status = lx_nor_flash_sector_write(&nor_sim_flash, i, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } /* Read back 100 sectors... */ for (i = 0; i < 100; i++) { status = lx_nor_flash_sector_read(&nor_sim_flash, i, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } for (j = 0; j < 128; j++) { if (buffer[j] != i) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } } #ifdef LX_NOR_ENABLE_MAPPING_BITMAP for (i = 0; i < 100; i++) { if (nor_sim_flash.lx_nor_flash_extended_cache_mapping_bitmap[i>>5] & (ULONG)(1<<(i & 31)) == 0) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } #endif #ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE for (i = 0; i < 8; i++) { if(nor_sim_flash.lx_nor_flash_extended_cache_obsolete_count[i] != 0) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } #endif /* Release 100 sectors... */ for (i = 0; i < 100; i++) { status = lx_nor_flash_sector_release(&nor_sim_flash, i); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } #ifdef LX_NOR_ENABLE_MAPPING_BITMAP for (i = 0; i < 100; i++) { if (nor_sim_flash.lx_nor_flash_extended_cache_mapping_bitmap[i>>5] & (ULONG)(1<<(i & 31)) != 0) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } #endif #ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE for (i = 0; i < 6; i++) { if(nor_sim_flash.lx_nor_flash_extended_cache_obsolete_count[i] != 15) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } if (nor_sim_flash.lx_nor_flash_extended_cache_obsolete_count[6] != 10 || nor_sim_flash.lx_nor_flash_extended_cache_obsolete_count[7] != 0) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } #endif _lx_nor_flash_close(&nor_sim_flash); printf("SUCCESS!\n"); /* Test 2: Write same sector 120 times. */ printf("Test 2: Write same sector 120 times............."); /* Reinitialize... */ lx_nor_flash_initialize(); lx_nor_flash_format(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize, NULL); lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif for (j = 0; j < 128; j++) buffer[j] = 0xFFFFFFFF; /* Write same sector 120 sectors.... */ for (i = 0; i < 120; i++) { for (j = 0; j < 128; j++) buffer[j] = i; status = lx_nor_flash_sector_write(&nor_sim_flash, 7, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 7, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } for (j = 0; j < 128; j++) { if (buffer[j] != readbuffer[j]) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } /* Write other sectors just to have additional sectors to manage. */ if (i == 1) lx_nor_flash_sector_write(&nor_sim_flash, 1, buffer); if (i == 16) lx_nor_flash_sector_write(&nor_sim_flash, 16, buffer); if (i == 32) lx_nor_flash_sector_write(&nor_sim_flash, 32, buffer); if (i == 48) lx_nor_flash_sector_write(&nor_sim_flash, 48, buffer); if (i == 64) lx_nor_flash_sector_write(&nor_sim_flash, 64, buffer); if (i == 80) lx_nor_flash_sector_write(&nor_sim_flash, 80, buffer); if (i == 96) lx_nor_flash_sector_write(&nor_sim_flash, 96, buffer); if (i == 112) lx_nor_flash_sector_write(&nor_sim_flash, 112, buffer); } status = lx_nor_flash_defragment(&nor_sim_flash); status = lx_nor_flash_sector_read(&nor_sim_flash, 7, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 119) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 1, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 1) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 16, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 16) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 32, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 32) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 48, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 48) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 64, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 64) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 80, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 80) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 96, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 96) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 112, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 112) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_defragment(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } /* Point at the simulated NOR flash memory. */ word_ptr = nor_sim_flash.lx_nor_flash_base_address; status = lx_nor_flash_close(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } printf("SUCCESS!\n"); /* Test 3: Corrupt block 0, simulate a power interruption during erase of block 0, after the erase, but before the free bit map and erase count is setup. */ printf("Test 3: Block erase-initialize interrupted......"); word_ptr[0] = 0xFFFFFFFF; word_ptr[3] = 0xFFFFFFFF; /* Open the flash and see if we recover properly. */ status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE status += lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif if ((status != LX_SUCCESS) || (nor_sim_flash.lx_nor_flash_free_physical_sectors != 111) || (nor_sim_flash.lx_nor_flash_mapped_physical_sectors != 9)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_close(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } /* Corrupt block 0, simulate a power interruption during erase of block 0, after the erase, and after the free bit map setup, but before erase count is setup. */ word_ptr[0] = 0xFFFFFFFF; /* Open the flash and see if we recover properly. */ status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE status += lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif if ((status != LX_SUCCESS) || (nor_sim_flash.lx_nor_flash_free_physical_sectors != 111) || (nor_sim_flash.lx_nor_flash_mapped_physical_sectors != 9)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_close(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } printf("SUCCESS!\n"); /* Test 4: simulate a power interruption after a new block is allocated but before anything else can be done. */ printf("Test 4: Power interrupted new block allocation.."); word_ptr[3] = word_ptr[3] & ~((ULONG) 1); /* Open the flash and see if we recover properly. */ status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE status += lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif if ((status != LX_SUCCESS) || (nor_sim_flash.lx_nor_flash_free_physical_sectors != 110) || (nor_sim_flash.lx_nor_flash_mapped_physical_sectors != 9)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_close(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } /* Simulate a power interruption after a new block is allocated but before anything else can be done. */ word_ptr[(16*128)+3] = 0x7C00; /* Open the flash and see if we recover properly. */ status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE status += lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif if ((status != LX_SUCCESS) || (nor_sim_flash.lx_nor_flash_free_physical_sectors != 109) || (nor_sim_flash.lx_nor_flash_mapped_physical_sectors != 9)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_close(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } /* Simulate a power interruption after a new sector is allocated, after data had been copied, and the superceeded bit is clear, but before the new entry can be setup. */ word_ptr[3] = 0x7FFC; word_ptr[(16*128)+6] = word_ptr[(16*128)+6] & ~((ULONG) 0x40000000); /* Open the flash and see if we recover properly. */ status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE status += lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif if ((status != LX_SUCCESS) || (nor_sim_flash.lx_nor_flash_free_physical_sectors != 108) || (nor_sim_flash.lx_nor_flash_mapped_physical_sectors != 9)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } lx_nor_flash_close(&nor_sim_flash); /* Simulate a power interruption after a new sector is allocated, after data had been copied, and the superceeded bit is clear, the new entry is setup, but the old entry has not been invalidated. */ word_ptr[3] = 0x7FF8; word_ptr[6] = 0xC0000070; for (i = 0; i < 128; i++) { word_ptr[(3*128)+i] = 0x70; } /* Open the flash and see if we recover properly. */ status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE status += lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif if ((status != LX_SUCCESS) || (nor_sim_flash.lx_nor_flash_free_physical_sectors != 107) || (nor_sim_flash.lx_nor_flash_mapped_physical_sectors != 9)) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 7, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 119) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 1, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 1) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 16, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 16) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 32, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 32) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 48, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 48) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 64, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 64) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 80, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 80) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 96, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 96) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 112, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 112) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_defragment(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_defragment(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 7, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 119) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 1, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 1) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 16, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 16) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 32, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 32) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 48, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 48) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 64, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 64) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 80, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 80) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 96, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 96) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 112, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 112) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } /* Read in reverse order to see if caching helps! */ status = lx_nor_flash_sector_read(&nor_sim_flash, 112, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 112) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 96, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 96) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 80, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 80) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 64, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 64) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 48, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 48) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 32, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 32) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 16, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 16) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 1, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 1) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_read(&nor_sim_flash, 7, readbuffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } if (readbuffer[0] != 119) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_release(&nor_sim_flash, 7); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_sector_release(&nor_sim_flash, 8); if (status != LX_SECTOR_NOT_FOUND) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_defragment(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_close(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } printf("SUCCESS!\n"); printf("Test 5: Randow write/read sector................"); /*format the simulated NOR flash. */ /* Open the flash. */ status = lx_nor_flash_format(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize, NULL); status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE status += lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory, sizeof(nor_cache_memory)); #endif if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } /* Write 100 sectors.... */ for (i = 0; i < 100; i++) { for (j = 0; j < 128; j++) buffer[j] = i; status = lx_nor_flash_sector_write(&nor_sim_flash, i, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } /* Read back 100 sectors... */ for (i = 0; i < 100; i++) { status = lx_nor_flash_sector_read(&nor_sim_flash, i, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } for (j = 0; j < 128; j++) { if (buffer[j] != i) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } } /* Now, perform 1000 sector writes to randomly selected sectors, each time reading first to make sure the previous contents are valid. */ for (i = 0; i < 1000; i++) { /* Pickup random sector. */ sector = (rand() % 100); /* Read that sector. */ status = lx_nor_flash_sector_read(&nor_sim_flash, sector, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } for (j = 0; j < 128; j++) { if ((buffer[j] & 0x0000FFFF) != sector) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } /* Include the itteraction in the buffer to generate a new write. */ for (j = 0; j < 128; j++) { buffer[j] = (buffer[j] & 0x0000FFFF) | (i << 16); } status = lx_nor_flash_sector_write(&nor_sim_flash, sector, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } status = lx_nor_flash_close(&nor_sim_flash); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } printf("SUCCESS!\n"); printf("Test 6: Check lx_nor_flash_extended_cache_entries size................"); /* Format the simulated NOR flash. */ status = lx_nor_flash_format(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize, NULL); /* Open the flash. */ status = lx_nor_flash_open(&nor_sim_flash, "sim nor flash", _lx_nor_flash_simulator_initialize); #ifndef LX_NOR_DISABLE_EXTENDED_CACHE if (status == LX_SUCCESS) { status = lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory_invalid, sizeof(nor_cache_memory_invalid)); if (status != LX_ERROR) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } status = lx_nor_flash_extended_cache_enable(&nor_sim_flash, nor_cache_memory2, sizeof(nor_cache_memory2)); } #endif if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } /* Write 100 sectors.... */ for (i = 0; i < 100; i++) { for (j = 0; j < 128; j++) buffer[j] = i; status = lx_nor_flash_sector_write(&nor_sim_flash, i, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } /* Read back 100 sectors... */ for (i = 0; i < 100; i++) { status = lx_nor_flash_sector_read(&nor_sim_flash, i, buffer); if (status != LX_SUCCESS) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } for (j = 0; j < 128; j++) { if (buffer[j] != i) { printf("FAILED!\n"); #ifdef BATCH_TEST exit(1); #endif while(1) { } } } } #ifdef BATCH_TEST exit(0); #endif /* All done! */ while(1) { } }