3 Replies Latest reply on May 4, 2017 6:39 AM by tuma84

    hrtimer.h und/oder timer interrupt

    tuma84

      Hallo liebe community,

       

      für mein Projekt auf der Intel Edison Plattform benötige ich einen Timer/Timer-interrupt, welches alle 0,1ms (10kHz) ausgelöst wird. Soweit ich das sehe, ist der hrtimer in der aktuellen Poky-Distro nicht verfügbar, oder habe ich etwas übersehen? Mein Ziel ist, ein Signal mit 10 KHz über einen exteren Sensor (SPI) abzutasten und die Werte zu speichern. Besteht irgendeine Möglichkeit, das Problem auf Linuxebene zu lösen. Ich Arbeite mit Eclipse und C/C++ (kein Arduino)

       

      Vielen Dank!

        • 1. Re: hrtimer.h und/oder timer interrupt
          Intel Corporation
          This message was posted on behalf of Intel Corporation

          Hello tuma84,

          Thanks for reaching out!

          As you mentioned, Edison's standard image doesn't have hrtimer installed, therefore it is not possible to create a timer with this library by default. However, I created this small script that might help you. The script creates a loop that, I believe, will get you as close to 100us as a non-RTOS OS will get you. 

          #include <stdio.h>
          #include <sys/time.h>

          int main (int argc, char** argv) {
              struct timeval tvalBefore;
              struct timeval tvalAfter;

              long time_elapsed = 0;

              gettimeofday (&tvalBefore, NULL);
              long time_b_sec = tvalBefore.tv_sec;
              long time_b_usec = tvalBefore.tv_usec;

              while (time_elapsed < 100)
              {
               gettimeofday (&tvalAfter, NULL);
               long time_a_sec = tvalAfter.tv_sec;
               long time_a_usec = tvalAfter.tv_usec;
               time_elapsed = ((time_a_sec - time_b_sec) * 1000000L + time_a_usec) - time_b_usec;
              }
              printf("Time in microseconds: %ld microseconds\n", time_elapsed);
              return 0;
          }

          I hope this information helps you, and if you have any doubts, please don't hesitate to ask.
          Pedro M.

          • 2. Re: hrtimer.h und/oder timer interrupt
            SpiderKenny

            Pedro's answer is great and it runs in a tight loop.

            Here are a couple of helper-functions that I use, to create timers which send a signal (similar to an interrupt) to the app at specified intervals. You can specify the interval in seconds or nano-seconds.

             

            // When any timer fires it will call here.

            // The ID of the timer is stored in the si_value.sival_ptr member.

            static void handler(int sig, siginfo_t *si, void *uc)

            {

              UNUSED(uc); // The user-context is almost universally never used.

              UNUSED(sig); // We could check SIG against TIMER_SIG but why bother since it's the only signal we registered for?

             

             

              static uint64_t seconds = 0;

            // off_t filesize;

              uint32_t param;

             

             

              // Get the timer ID.

              param = (uint32_t)si->si_value.sival_ptr;

             

              switch (param) {

              case ONE_SECOND_TIMER:

              seconds++;

              //discovery_tick();

             

              if((seconds % 120)==0)

              {

              if(mcp->opts.logfd)

              {

              // Tell world how many lines we have logged.

              sprintf(g_buf, "Logged %d Lines",mcp->opts.loglines);

              mc->sendMqttIDMessge(g_buf, (char*)"canlog");

             

             

              }

              }

             

              break;

              case TWENY_MILLISECOND_TIMER:

              mcp->tick(); // Call the Microchip-Can-Controller tick.

              break;

              default:

              break;

              }

             

            }

             

             

            // Schedule and start a timer. Specify a uniuqe ID and time in seconds and nano-seconds.

            void startTimer(uint32_t id, long sec, long nsec)

            {

              struct sigaction sa;

              struct itimerspec ts;

              struct sigevent sev;

              timer_t tid;

             

              // Configure the signal action.

              sa.sa_flags = SA_SIGINFO;

              sa.sa_sigaction = handler; // When the timer fires, it will call handler(...);

              sigemptyset(&sa.sa_mask); // No masks.

             

              // Establish a handler for our custom signal TIMER_SIG

              if(sigaction(TIMER_SIG, &sa, NULL)==-1)

              {

              std::cerr << "Error in sigaction\n";

              return;

              }

             

             

              // Configure the signal event structure

              sev.sigev_notify = SIGEV_SIGNAL; // We wish to be notified using a SIGNAL

              sev.sigev_signo = TIMER_SIG; // Use our custom signal number: TIMER_SIG

              sev.sigev_value.sival_ptr = (void*)id;

             

             

             

              // Configure the time-spec

              ts.it_value.tv_sec = sec;

              ts.it_value.tv_nsec = nsec;

              ts.it_interval.tv_sec = sec;

              ts.it_interval.tv_nsec = nsec;

             

             

             

              // Create the timer

              if(timer_create(CLOCK_REALTIME, &sev, &tid) == -1)

              {

              std::cerr << "Error in timer_create\n";

              return;

              }

             

              // Start the timer.

              if(timer_settime(tid,0,&ts, NULL)==-1)

              {

              std::cerr << "Error in settime\n";

              }

             

             

            }

            I hope this helps too!

            1 of 1 people found this helpful
            • 3. Re: hrtimer.h und/oder timer interrupt
              tuma84

              Hi SpiderKenny,

               

              thanks a lot! That is exactly what I was looking for. It's working so far. I will do some further tests but it's already more accurate than my thread-based solution. I also thought about putting an external clock on one input pin and using the edison's interrupt. Of course I don't want to change my PCB-layout again