I discovered that my minimum timer interval allowed by my processor is 300us. I output time by keeping track of ClockCycles(), saving the values to a buffer array, and printing out to an output file after its done. I noticed that no matter what I set my SERVO_INT variable to, for the first ~15ms the difference in my timed pulses are around 300us. Then after ~15ms the interval becomes the value of SERVO_INT (like it should be).
When I take out the code that sends a message to my hardware server, I noticed that timed pulses occur at the correct SERVO_INT interval right from time=0. I have concluded that sending messages to my server causes odd behaviour in my timed interrupt. Why is this occurring? And how can I avoid it, besides from creating a delay in my system?
Thank you.
(Sorry, it’s been awhile since I’ve been able to work on this problem.)
#define SERVO_INT 800 //Servo interrupt 800us
// Real-Time Control loop
int controlLoop(void)
{
int i;
int rcvid=0;
ClientMessageT msg;
MessageT timMsg;
uint64_t cps, stClock;
float fTime;
float fBuffer[2000];
//Get the starting time in Clock Cycles
stClock=ClockCycles();
cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
//Process Control Loop
for (i=0;i<=2000;i++)
{
//Receive messages from Timer
rcvid=MsgReceive(timChid,&timMsg,sizeof(MessageT),NULL);
if (rcvid==0)
{
//Send data to Hardware Server for DAC Output
msg.iMsgType = MT_SEND_DAC_OUTPUT;
msg.fMsgData = 20;
if (MsgSend(coid, &msg, sizeof(ClientMessageT),&msg,sizeof(ClientMessageT))==1)
{
printf(“Error during MsgSend\n”);
perror(NULL);
return(-1);
}
//Output data to file
fTime = ((float) (ClockCycles()-stClock)/cps);
fBuffer[i]=fTime;
}
}
//Print buffer out to a file
for (i=0;i<=iQueueCtr;i++)
{
fprintf(fptr,"%f \n",fBuffer[i][0]);
}
return (0);
}
/*
- setupPulseAndTimer
-
- This routine is responsible for setting up a pulse so it sends a message
- with code MT_TIMER. It then sets up a periodic timer that fires once per sec
-
*/
int SingleMotor::setupPulseAndTimer(void)
{
timer_t timerid; // timer ID for timer
struct sigevent event; // event to deliver
struct itimerspec timer; // the timer data struct
struct _clockperiod clkper; // to control the clock period
// set up the kind of event that we want -- a pulse
SIGEV_PULSE_INIT(&event, timCoid, SIGEV_PULSE_PRIO_INHERIT,CODE_TIMER,10);
// create the timer, binding it to the event
if (timer_create(CLOCK_REALTIME, &event, &timerid)==-1)
{
printf("Can't timer_create, errno %d\n", errno);
perror(NULL);
return(-1);
}
// setup the timer (1ns delay, SERVO_INT reload)
timer.it_value.tv_sec = 0;
timer.it_value.tv_nsec = 1;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_nsec = ((int)SERVO_INT)*1000;
// and start it!
timer_settime (timerid,0,&timer,NULL);
//Set the Clock Period to 100us
clkper.nsec = 100000;
clkper.fract = 0;
ClockPeriod(CLOCK_REALTIME,&clkper,NULL,0);
return 0;
}