11 Replies Latest reply on Aug 7, 2015 5:13 AM by JernejH

    Creating a timer function in C on Galileo gen 2

    JernejH

      Hello everyone,

       

      does anyone have an experience creating a timer function in C code for Galileo. I am trying to port some C kode made for mikrokontroler, but I am totally stuck with this function:

       

      void DotMatrixScanTimerInit(unsigned long ulSrcFreq, unsigned long ulScanFerq)
      {
          unsigned long ulMatchVal = (ulSrcFreq * DM_SCAN_FREQ) / (DM_SCANDIV_VALUE * (DM_SCANPSR_VALUE + 1) * 1000);
      
      
          //
          // Set the timer clock
          //
          //xSysCtlPeripheralClockSourceSet(DM_SCAN_CLKSRC, DM_SCANDIV_VALUE);
      
      
          xSysCtlPeripheralEnable2(DM_SCAN_TIMER);
      
      
          //
          // Clear the status first
          //
          TimerIntClear(DM_SCAN_TIMER, xTIMER_INT_MATCH);
          while(xTimerStatusGet(DM_SCAN_TIMER, DM_SCAN_CHANNEL, xTIMER_INT_MATCH));
      
      
          // 
          // Config as periodic mode
          //        
          xTimerInitConfig(DM_SCAN_TIMER, DM_SCAN_CHANNEL, xTIMER_MODE_PERIODIC, ulScanFerq);
          xTimerPrescaleSet(DM_SCAN_TIMER, DM_SCAN_CHANNEL, DM_SCANPSR_VALUE);
          xTimerMatchSet(DM_SCAN_TIMER, DM_SCAN_CHANNEL, ulMatchVal);
          xTimerIntEnable(DM_SCAN_TIMER, DM_SCAN_CHANNEL, xTIMER_INT_MATCH);
          xTimerIntCallbackInit(DM_SCAN_TIMER, DotMatrixScan);
          xIntEnable(xSysCtlPeripheraIntNumGet(DM_SCAN_TIMER));
      
      
          //
          // Start the timer
          //
          xTimerStart(DM_SCAN_TIMER, DM_SCAN_CHANNEL);
      }
      
      

       

      I searched this site and github, but I could not find any example which could help me with my problem.

       

      Cheers, Jernej

        • 1. Re: Creating a timer function in C on Galileo gen 2
          Intel_Alvarado

          Hi,

           

          Are you searching for something similar to a sleep function? Sleep will basically put the program to rest for a certain amount of time sleep

           

          What specifically are you trying to do, there are several timer examples but your code seems somewhat incomplete. There are also periodic timers such asc++ - Portable periodic/one-shot timer implementation - Code Review Stack Exchange that might give some insight on the timers function.

           

          Sergio

          • 2. Re: Creating a timer function in C on Galileo gen 2
            JernejH

            Hi Sergio,

             

            I am trying to connect Intel Edison and Colors Shield. So far I can only change colors on the shield, but I am unable to show characters. I need a timer to drive A dot matrix. I found C code on github, written for shield and now I am trying to port it to Edison.

             

            I will need timer function which will be responsible for set and reset of Galileo GPIOs.

             

            Many thanks for help, Jernej

            • 3. Re: Creating a timer function in C on Galileo gen 2
              JernejH

              Hello everyone,

               

              I think I over complicated my question. Does anyone know how to make on Galileo a function in C which will be executed 100 times in second? Which timer interrupts to use, is there way to set priority?

               

              The code I pasted is used to set up timers in microcontroller, does Galileo have something similar?

               

              Cheers, Jernej

              • 4. Re: Creating a timer function in C on Galileo gen 2
                Intel_Alvarado

                Hi,

                 

                Take a look at Anyone try theTimerOne example?  ISRBLINK ? . The thread has lots of information on timers and interrupts for the Galileo. It even has some example sketches that you might use as a reference to build your code.

                 

                Sergio

                1 of 1 people found this helpful
                • 5. Re: Creating a timer function in C on Galileo gen 2
                  JernejH

                  Hi everyone,

                   

                  this is the code which should exactly the same as the one I posted in the  first post.

                   

                  extern void
                  DotMatrixScanTimerInit(unsigned long Period)
                  {
                    struct itimerval it_val; /* for setting itimer */
                  
                  
                    /* Upon SIGALRM, call  DotMatrixScan(). DotMatrixScan() is a function which is called every timer interrupt
                    * Set interval timer.  We want frequency in ms,
                    * but the setitimer call needs seconds and useconds. */
                  
                    if (signal(SIGALRM, (void (*)(int))  DotMatrixScan) == SIG_ERR) {
                       perror("Unable to catch SIGALRM");
                    }
                    it_val.it_value.tv_sec =  Period/1000;
                    it_val.it_value.tv_usec = (Period*1000) % 10000;
                    it_val.it_interval = it_val.it_value;
                    if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
                      printf("error calling setitimer()"); 
                    }          
                  
                  }
                  
                  }
                  

                   

                   

                   

                  The problem I am having is, that it is not executing 100 times a second but only around 10 times. Does anyone have an idea how if I can give timer function priority? Or is this the best I can get out of Galileo?

                   

                  Cheers

                  • 6. Re: Creating a timer function in C on Galileo gen 2
                    Intel_Alvarado

                    Hi,

                     

                    And are you able to get other timer values when you run this code, if you change to 5 times per second for example? You can try to increase the timer value to see what would be the highest value can be reached.

                     

                    Sergio

                    • 7. Re: Creating a timer function in C on Galileo gen 2
                      JernejH

                      Hi Sergio,

                       

                      I tried experimenting with timer. But for some reason, it only works when I choose period as 1. I have no idea why is that. I attached entire code, but it is messy as I mix it up from few resources and everything is in one file.

                       

                      This video shows what my problem is all about:

                       

                       

                      Cheers, Jernej

                      • 8. Re: Creating a timer function in C on Galileo gen 2
                        xthunderheartx

                        I use the following scheme to good effect. Times pretty good down to 100 usecs or so.  I just call startTimer and then go about my work, checking the flag periodically and taking appropriate action if/when it gets set.  If I finish before expiration I just call stopTimer and carry on.  Some variation on the theme might work for you.

                         

                        // Control structure for timer
                        
                        struct TmrCtrlBlk
                        {
                          bool *flag;
                          timer_t *tmrID;
                        }
                        

                         

                         

                        //
                        // timerHandler: Mark timer expired. Forward signal to be ignored by system
                        //
                        
                        
                        void timerHandler (int timerSignal, siginfo_t *si, void *uc)
                        {
                          struct TmrCtrlBlk *timerCtrlBlkPtr;
                        
                        
                          timerCtrlBlkPtr = si->si_value.sival_ptr;
                          *timerCtrlBlkPtr->flag = true;
                            signal(timerSignal, SIG_IGN);
                          return;
                        
                        
                        }
                        
                        
                        //
                        // startTimer: Start a timer using timer_create()
                        //
                        
                        
                        struct TmrCtrlBlk* startTimer (float userTimeout, bool *userFlagPtr)
                        {
                          timer_t timerID;
                            sigset_t timerSigMask;
                            struct itimerspec  timerSpec;
                          struct sigevent timerSigEvent;
                            struct sigaction timerSigAction;
                            struct TmrCtrlBlk *timerCtrlBlkPtr;
                            unsigned long msecs;
                        
                        
                            // Setup a user defined, one-shot hander.  This handler will be invoked
                            // when the timer expires.  The signals behavior will be reset to it's default
                            // on entry to the handler and subsequent expirations of the timer will be ignored.
                            // That's the theory anyway 
                        
                        
                            timerSigAction.sa_flags = SA_SIGINFO | SA_RESETHAND;
                            timerSigAction.sa_sigaction = timerHandler;
                            sigemptyset(&timerSigAction.sa_mask);
                            if (sigaction(SIGRTMIN, &timerSigAction, NULL) == -1)
                                errExit("sigaction");
                        
                        
                            // Block the timer signal temporarily
                            sigemptyset(&timerSigMask);
                            sigaddset(&timerSigMask, SIGRTMIN);
                            if (sigprocmask(SIG_SETMASK, &timerSigMask, NULL) == -1)
                                errExit("sigprocmask");
                        
                        
                            // Allocate a TmrCntlBlk
                            timerCtrlBlkPtr = (struct TmrCtrlBlk*) malloc (sizeof(struct TmrCtrlBlk));
                        
                        
                            // Create the timer
                            timerSigEvent.sigev_notify = SIGEV_SIGNAL;
                            timerSigEvent.sigev_signo = SIGRTMIN;
                            timerSigEvent.sigev_value.sival_ptr = timerCtrlBlkPtr;
                            if (timer_create(CLOCK_MONOTONIC, &timerSigEvent, &timerID) == -1)
                                errExit("timer_create");
                        
                        
                            // Init out TmrCtrlBlk for this timer
                            timerCtrlBlkPtr->flag = userFlagPtr;
                            timerCtrlBlkPtr->tmrID = timerID; // Not actually used by the hdlr but set it anyway.
                        
                        
                            msecs = userTimeout * 1000; // Convert seconds to milliseconds store as long
                        
                        
                            // Set the timeout value (timer period)
                        
                        
                            timerSpec.it_value.tv_sec = msecs / 1000; // Dump fractional time
                            timerSpec.it_value.tv_nsec = (msecs % 1000) * 1000000; // Recover fractional time as nanoseconds
                            timerSpec.it_interval.tv_sec = timerSpec.it_value.tv_sec;
                            timerSpec.it_interval.tv_nsec = timerSpec.it_value.tv_nsec;
                        
                        
                            *userFlagPtr = false;
                        
                        
                            if (timer_settime(timerID, 0, &timerSpec, NULL) == -1)
                                errExit("timer_settime");
                        
                        
                            // Unlock the signal and away we go.
                            if (sigprocmask(SIG_UNBLOCK, &timerSigMask, NULL) == -1)
                                errExit("sigprocmask");
                        
                        
                            // The timer is now running ...
                          return (timerCtrlBlkPtr);
                        }
                        
                        
                        //
                        // stopTimer: Disarm the timer and release it's TmrCtrlBlk
                        //
                        
                        
                        void stopTimer (struct TmrCtrlBlk *timerCtrlBlkPtr)
                        {
                            struct itimerspec its;
                        
                        
                            // Disable the timer.
                            its.it_value.tv_sec = 0;
                            its.it_value.tv_nsec = 0;
                            its.it_interval.tv_sec = its.it_value.tv_sec;
                            its.it_interval.tv_nsec = its.it_value.tv_nsec;
                        
                        
                            if (timer_settime(timerCtrlBlkPtr->tmrID, 0, &its, NULL) == -1)
                                errExit("timer_settime"); //TODO: Pffft.  I don't think so.
                        
                        
                            // Free the control block
                            free (timerCtrlBlkPtr);
                        }
                        
                        
                        • 9. Re: Creating a timer function in C on Galileo gen 2
                          JernejH

                          Hi xthunderheartx,

                           

                          I am trying to reuse your code, but I am receiving errors:

                           

                          /tmp/ccNjeRV0.o: In function `startTimer':
                          MatrixDisplay.c:(.text+0xebb): undefined reference to `errExit'
                          MatrixDisplay.c:(.text+0xf0f): undefined reference to `errExit'
                          MatrixDisplay.c:(.text+0xf59): undefined reference to `timer_create'
                          MatrixDisplay.c:(.text+0xf6a): undefined reference to `errExit'
                          MatrixDisplay.c:(.text+0x1066): undefined reference to `timer_settime'
                          MatrixDisplay.c:(.text+0x1077): undefined reference to `errExit'
                          MatrixDisplay.c:(.text+0x10a6): undefined reference to `errExit'
                          /tmp/ccNjeRV0.o: In function `stopTimer':
                          MatrixDisplay.c:(.text+0x10f7): undefined reference to `timer_settime'
                          MatrixDisplay.c:(.text+0x1108): undefined reference to `errExit'
                          collect2: error: ld returned 1 exit status
                          

                           

                          Which libraries do you include besides stdbool.h and time.h in your project?

                           

                          Cheers, Jernej

                          • 10. Re: Creating a timer function in C on Galileo gen 2
                            xthunderheartx

                            Here's the missing macro:

                             

                            #define errExit(msg)    do {syslog (LOG_DEBUG, msg); exit(EXIT_FAILURE);} while (0)

                             

                            here are the includes:

                             

                            #include <stdint.h>

                            #include <syslog.h>

                            #include <ctype.h>

                            #include <string.h>

                            #include <stdbool.h>

                            #include <stdlib.h>

                            #include <stdio.h>

                            #include <unistd.h>

                            #include <fcntl.h>

                            #include <termios.h>

                            #include <signal.h>

                            #include <time.h>

                            #include <errno.h>

                            #include <mqueue.h>

                            #include <netinet/in.h>

                            #include <linux/rtc.h>

                            #include <sys/ioctl.h>

                             

                             

                            #include "mraa.h"

                             

                            and let me see I think you need to link librt .. yep.

                            • 11. Re: Creating a timer function in C on Galileo gen 2
                              JernejH

                              Hi xthunderheartx,

                               

                               

                              thanks, now I can compile your code. Do you have any examples, how to properly call your timer function? I have some problems with initialization.

                               

                               

                              Cheers, Jernej