This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM1808 high resolution timestamps

Other Parts Discussed in Thread: AM1808

I am working on a project about time measurement on Lego Mindstorms Ev3. Lego used the AM1808 Chip.

On the Mindstorms is running a modified Linux OS  (Ev3dev).

I want to measure some C code instructions and need time stamp before and after some instruction with minimal overhead.

I need a C code instruction or inline assembly  to take the timestamp.

  • Moving this to the AM1X forum.
  • Hi Dirk,

    Long back, I have tried the  below sample code to measure the time  and it worked.

    Steps:

    1. copy the below code into a test.c file

    2. Build the code using the ARM tool chain ( I used Linaro )

       $ sudo /home/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/bin/arm-linux-gnueabihf-gcc -o test.o test.c -lrt

    3. copy this test.o into your target rootfilesystem's home directory.

    4. Boot linux on target board ( I used K2H EVM )

    5. Go to the home directory and run the test.o

    ( In the place of sleep() function you can insert your function )

    #include <stdio.h>      /* for printf */
    
    #include <stdint.h>     /* for uint64 definition */
    
    #include <stdlib.h>     /* for exit() definition */
    
    #include <time.h>       /* for clock_gettime */
    
    #define BILLION 1000000000L
    
    int localpid(void) {
    
           static int a[9] = { 0 };
    
           return a[0];
    
    }
    
    main(int argc, char **argv)
    
    {
    
           uint64_t diff;
    
           struct timespec start, end;
    
           int i;
    
           /* measure monotonic time */
    
           clock_gettime(CLOCK_MONOTONIC, &start); /* mark start time */
    
           sleep(1);       /* do stuff */
    
           clock_gettime(CLOCK_MONOTONIC, &end);   /* mark the end time */
    
           diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
    
           printf("elapsed time = %llu nanoseconds\n", (long long unsigned int) diff);
    
           /* now re-do this and measure CPU time */
    
           /* the time spent sleeping will not count (but there is a bit of overhead */
    
           clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);        /* mark start time */
    
           sleep(1);       /* do your own stuff / code here*/
    
           clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);          /* mark the end time */
    
           diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
    
           printf("elapsed process CPU time = %llu nanoseconds\n", (long long unsigned int) diff);
    
           exit(0);
    
    }

  • Hello,
    I tried this method and the problem is the clock_gettime is expensive and a jitter of 3 ms is unusable for a couple instructions on a 300MHz machine.
    I read about a Cycle Counter Register on infocenter.arm.com/.../index.jsp
    The Example is pretty simple just execute MRC p15, 0, <Rd>, c15, c12, 1 ; Read Cycle Counter Register.
    Linux protect the register but I found a way to unlock the reg. for user-space via module.
    /* Enable user-mode access to counters. */
    asm volatile("mcr p15, 0, %0, c9, c14, 0" :: "r"(1));
    /* Program PMU and enable all counters */
    asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(PERF_DEF_OPTS));
    asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(0x8000000f));

    I also try to Read it in a module.
    But the programs will not execute.
    On the console it return immediately without any massages.

    I also tested the perf event utility but it crashed on initialisation.



    Mfg,
    Dirk
  • Hi Dirk,

    Whether atleast that my suggested method works for you?