Go to Post FIRST: there is no second. - BandChick [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 17-02-2005, 17:09
Orborde Orborde is offline
Registered User
FRC #1747
Team Role: Mentor
 
Join Date: Apr 2004
Rookie Year: 2003
Location: Indianapolis, IN
Posts: 44
Orborde has a spectacular aura aboutOrborde has a spectacular aura about
Send a message via AIM to Orborde
Global Struct Arrays and Interrupts

I have an array of structs, seen below, that will be accessed by interrupts at some points; namely, the "ticks" variable of the structure will be changed by encoder-caused interrupts. "goal_velocity" is NOT read or modified by the interrupt routine, ever. My question, then, is whether I need to disable interrupts when I want to write to goal_velocity? Can I just declare the array as volatile, as shown below, or does that only act on the pointer? Could I throw in an extra "volatile" or two in the array definition to make goal_velocity safe to fiddle with without disabling interrupts? Or is it imperative that I disable interrupts before reading/writing goal_velocity?

Code:
typedef struct {
        unsigned char * output;          // motor output signal
        int goal_velocity;       // goal (ticks per 26.2msec)

        int ticks;               // ticks since last read
    
        int error_current;       // current error
        int error_last;          // error from last measure
        int error_acc;           // accumulated error for integral portion
        } drivemotor;
Code:
volatile drivemotor motors[NUM_MOTORS] = {
  {&drive1, 0, 0, 0, 0, 0},
  {&drive2, 0, 0, 0, 0, 0},
  {&drive3, 0, 0, 0, 0, 0},
  {&drive4, 0, 0, 0, 0, 0}
};
As if that weren't enough, assuming I can set goal_velocity without disabling interrupts first, I'd like to make them accessible by macro, as seen here:
Code:
#define speed1 motors[0].goal_velocity
#define speed2 motors[1].goal_velocity
etc...
I can't figure out how to declare the array so that it can be initialized easily per the definition above AND be accessible across multiple files so the macros WORK. Where do I declare it, and how?

Until some of you geniuses weigh in, I'll assume that interrupts do NOT need to be disabled, and I'll define an accessor function for the array.

Thanks for your time, folks. I'd really like a reply ASAP, as we want to have a testing version of the code ready tonight.

Last edited by Orborde : 17-02-2005 at 17:13. Reason: Corrected some of the quoted code; I can't tell the difference between } and ) in MPLAB on this silly high-res screen :)
  #2   Spotlight this post!  
Unread 17-02-2005, 17:38
Astronouth7303's Avatar
Astronouth7303 Astronouth7303 is offline
Why did I come back?
AKA: Jamie Bliss
FRC #4967 (That ONE Team)
Team Role: Mentor
 
Join Date: Jan 2004
Rookie Year: 2004
Location: Grand Rapids, MI
Posts: 2,071
Astronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud ofAstronouth7303 has much to be proud of
Re: Global Struct Arrays and Interrupts

That's 5 questions.
Quote:
Originally Posted by Orborde
My question, then, is whether I need to disable interrupts when I want to write to goal_velocity?
Can I just declare the array as volatile, as shown below, or does that only act on the pointer?
Could I throw in an extra "volatile" or two in the array definition to make goal_velocity safe to fiddle with without disabling interrupts?
Or is it imperative that I disable interrupts before reading/writing goal_velocity?
In order: Yes. The former. Not necessary. No.

Volatile only means that the value cannot be "cached" by the processor. The compiler will assume that the value will change every time you use it.

Quote:
Originally Posted by Orborde
Where do I declare it, and how?
Easy. You make a header that contains the macros. In the same header, add the following code:
Code:
extern volatile drivemotor motors[NUM_MOTORS];
Then include that header where ever you reference it.
  #3   Spotlight this post!  
Unread 17-02-2005, 17:51
Unsung FIRST Hero
Matt Leese Matt Leese is offline
Been-In-FIRST-Too-Long
FRC #1438 (The Aztechs)
Team Role: Engineer
 
Join Date: May 2001
Rookie Year: 1998
Location: Long Beach, CA
Posts: 937
Matt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond reputeMatt Leese has a reputation beyond repute
Send a message via AIM to Matt Leese
Re: Global Struct Arrays and Interrupts

It's definitely safer to turn off interrupts when reading or writing from goal_velocity. The reason to turn off interrupts is that it's possible that while accessing the data, an interrupt may trigger and also access the data. It's then possible for incorrect data to be generated.

However, you really only need to disable interrupts if both regular code and an interrupt handler are writing to the memory location. In most cases, if your interrupt is writing the data and the regular code is reading it, you shouldn't need to disable interrupts.

As for setting it volatile, volatile is used when a variable may change in another thread of execution (not aplicable here) or in an interrupt handler. The reason for this is that the compiler could optimize out code to check for a value if the compiler thinks the variable couldn't be changed within that code path; but the variable could change the interrupt. I doubt this is particularly relevant here as you probably aren't sitting in a loop waiting for something to happen in your code. I'm also doubting the optimizing ability of this compiler (although I could be wrong). Either way, you can always be safe by declaring it that way.

Matt
  #4   Spotlight this post!  
Unread 17-02-2005, 18:28
Orborde Orborde is offline
Registered User
FRC #1747
Team Role: Mentor
 
Join Date: Apr 2004
Rookie Year: 2003
Location: Indianapolis, IN
Posts: 44
Orborde has a spectacular aura aboutOrborde has a spectacular aura about
Send a message via AIM to Orborde
Re: Global Struct Arrays and Interrupts

First of all, thanks for taking the time to sort out my twisted English syntax.

Quote:
Originally Posted by Astronouth7303
That's 5 questions.

In order: Yes. The former. Not necessary. No.
Um...you contradicted yourself.
Question 1: My question, then, is whether I need to disable interrupts when I want to write to goal_velocity?
Your Answer: "Yes"
Question 4 (or 5?): Or is it imperative that I disable interrupts before reading/writing goal_velocity?
Your Answer: "No."

Quote:
Volatile only means that the value cannot be "cached" by the processor. The compiler will assume that the value will change every time you use it.
So I assume that this applies to the components of the array pointed to by "motors" and not merely the value of the pointer variable "motors"?







Quote:
Easy. You make a header that contains the macros. In the same header, add the following code:
-blah-
I moved the following to the header file (which is #included in the C file that the code is in...)
Code:
extern volatile drivemotor motors[NUM_MOTORS] = {
  {&drive1, 0, 0, 0, 0, 0},
  {&drive2, 0, 0, 0, 0, 0},
  {&drive3, 0, 0, 0, 0, 0},
  {&drive4, 0, 0, 0, 0, 0}
};
and got this:
Code:
C:\mcc18\pidexp\drivereg.c:140:Fatal [151] -internal- populateExternalReferences() - symbol 'motors' is not an external reference.
The line it refers to is:
Code:
void set_motor(int motor, int goal) {
      motors[motor].goal_velocity = goal; // this line
}
Theoretically this function shouldn't exist, but when it is commented out, I get the same thing on
Code:
Motor_Ints_Enable();
(huh?)
and, when I comment that out, I get it here:
Code:
motor_gains[a].kd * (motors[a].error_current - motors[a].error_last));
and so I have stopped commenting things out like that.
Help?



To clarify the functionality of the original motors struct and array: Only the element "ticks" of the struct is touched at all by the interrupt routine (the interrupt uses "motors[0].ticks++;" or similar). No other variable in the struct is explicitly accessed. As stated, the question was whether I need to shut off interrupts if I want to assign goal_velocity a value.

Thanks again for the help. Maybe if I'm lucky this will work someday...

Last edited by Orborde : 17-02-2005 at 18:32.
  #5   Spotlight this post!  
Unread 18-02-2005, 16:12
Orborde Orborde is offline
Registered User
FRC #1747
Team Role: Mentor
 
Join Date: Apr 2004
Rookie Year: 2003
Location: Indianapolis, IN
Posts: 44
Orborde has a spectacular aura aboutOrborde has a spectacular aura about
Send a message via AIM to Orborde
Re: Global Struct Arrays and Interrupts

I hate to be rude about this, but *bump*....
  #6   Spotlight this post!  
Unread 18-02-2005, 22:34
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,112
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: Global Struct Arrays and Interrupts

The tick variable is an integer, with multiple bytes. It's conceivable that an interrupt could occur after one byte was read but before the other one, so you'd get a corrupted value. Any time you want to use a variable like that, it's a good idea to disable interrupts while you access it.
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 09:26.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi