Measuring the time to copy from flash to RAM

In the IPL and Startup stages, code is copied from flash into RAM and then executed. How long this takes depends on the speed of the CPU and the speed of the flash chip. To measure the duration of the copy operation, you can use the following code:

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>
                                        
#define MEGABYTE (1024*1024)
#define BLOCK_SIZE 16384
#define LOOP_RUNS 10
                                        
char *ram_destination;
char *ram_block;
char *flash_block;
unsigned long flash_addr;
uint64_t cycles_per_sec;
                                        
double CopyTest(const char *msg, char *source, char *dest)
{
    uint64_t accum = 0, start, stop;
    double t;
    int i;
                                        
    for (i=0; i<LOOP_RUNS; i++)
    {
        start = ClockCycles();
        memcpy(dest, source, BLOCK_SIZE);
        stop = ClockCycles();
        accum += (stop - start);
    }
    accum /= LOOP_RUNS;
                                            
    t = accum*(MEGABYTE/BLOCK_SIZE); 	// t = cycles per MB
    t = t / cycles_per_sec;		// t = seconds per 1MB
                                            
     printf("\nTo copy %s to RAM takes:\n",msg);
     printf("   %llu clock cycles for %u bytes\n", accum, BLOCK_SIZE);
     printf("   %f milliseconds per 1MB bytes\n", t*1000);
     printf("   %f microseconds per 1KB bytes\n", t*1000);
     return t;
}
                                            
int main(int argc, char *argv[]) 
{
    double flashtime, ramtime;
                                            
    if (argc<1) {
    printf("%s requires address of flash (any 16K block will do)\n", argv[0]);
    return EXIT_FAILURE;
    }
                                            
    flash_addr = strtoul(argv[1], 0, 16);
    printf("Using flash physical address at %lx\n", flash_addr);
                                            
    ram_block = malloc(BLOCK_SIZE);
    ram_destination = malloc(BLOCK_SIZE);
    flash_block = mmap(0, BLOCK_SIZE, PROT_READ,MAP_PHYS|MAP_SHARED, NOFD,flash_addr);
    if (flash_block == MAP_FAILED) {
        printf("Unable to map block at %lx\n", flash_addr);
    }
    cycles_per_sec = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
    flashtime = CopyTest("flash", flash_block, ram_destination);
    ramtime = CopyTest("RAM", ram_block, ram_destination);
    printf("\nFlash is %f times slower than RAM\n", flashtime/ramtime);
    return EXIT_SUCCESS;
}

To get reasonably accurate results, you should run the preceding code either at a high priority (using the on –p command) or when little else is running in the system.

A key factor that affects flash copy time is the bus interface to the flash. Fast CPUs can lose their advantage to their slower competitors if the system has a slow bus architecture or too many wait states.