|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||
|
|||
|
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}
};
Code:
#define speed1 motors[0].goal_velocity #define speed2 motors[1].goal_velocity etc... 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
|
|||||
|
|||||
|
Re: Global Struct Arrays and Interrupts
That's 5 questions.
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. Quote:
Code:
extern volatile drivemotor motors[NUM_MOTORS]; |
|
#3
|
|||
|
|||
|
Re: Global Struct Arrays and Interrupts
First of all, thanks for taking the time to sort out my twisted English syntax.
Quote:
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:
Quote:
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}
};
Code:
C:\mcc18\pidexp\drivereg.c:140:Fatal [151] -internal- populateExternalReferences() - symbol 'motors' is not an external reference. Code:
void set_motor(int motor, int goal) {
motors[motor].goal_velocity = goal; // this line
}
Code:
Motor_Ints_Enable(); and, when I comment that out, I get it here: Code:
motor_gains[a].kd * (motors[a].error_current - motors[a].error_last)); 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. |
|
#4
|
|||
|
|||
|
Re: Global Struct Arrays and Interrupts
I hate to be rude about this, but *bump*....
|
|
#5
|
|||||
|
|||||
|
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.
|
|
#6
|
|||||
|
|||||
|
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 |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|