This is somewhat related to my other question about arrys and pointers but for aseparate situation now. And this time I really do want 1 operation copying, but the arrays are guaranteed the same lengthand just need swapping over.
I'll have two sets of arrays which I want to be able to use in both main body code and within an ISR.
I have one array for which I want to populate it with values from wthin the ISR (writing only), and then use them in the main code (reading only).
I'll have another where I want to populate it in the main code (writing only) and use it (for reading only) in the ISR.
But typically an ISR could trigger whilst copying is ongoing, so the ISR could find itself processing an array which the main code had only got halfway through putting the correct values in to, or the main code could find that when trying to take a non-volatile copy of the other array which the ISR modifies that it copies half of what that array used to say, but then the ISR runs and the rest of the array which the maind code fills up afterwards instead reflects new data compared to the first half of the array.
I understand that one can put cli() and SREG=OldSREG code around the copying, but this means that the interrupt is disabled for the whole time it takes to copy the arrays. i don't want this, I want the time for which the interrupt canot trigger to be as short as possible.
The slow way would be:
uint8_t ArrayA_main[5]={0,1,2,3,4};
uint8_t ArrayA_ISR[5]={0,1,2,3,4};
//array sets A and B don't have the same data or do the same things, they are
//separate in every way and not guranteed to be the same lengths
uint8_t ArrayB_main[5]={0,1,2};
uint8_t ArrayB_ISR[5]={0,1,2};
//other variables and setup stuff
ISR (PCINT0_vect ){
uint8_t variable=digitalRead(z);
//use ArrayA_ISR (reading only)...
uint8_t whatever=ArrayA_ISR[x];
digitalWrite(n,ArrayA_ISR[y]);
//fill ArrayB_ISR (writing only)...
ArrayB_ISR[thing]=variable;
}
void setup (void){
PCMSKX |= bit (PCINTX); // pin
PCIFR |= bit (PCIFX); // clear any outstanding interrupts
PCICR |= bit (PCIEX); // enable pin change interrupts for D8 to D13
}
void loop (void){
//do stuff which fills ArrayA_Main(writing only)
ArrayA_Main[i]=(uint8_t)measurement;
//read from ArrayB_Main(reading only)
uint8_t something=ArrayB_Main[k];
uint8_t OldSREG=SREG;
cli();//disable interrupts
for(uint8_t a; a<sizeof(ArrayA_Main);a++){
ArrayA_ISR[a]=ArrayA_Main[a];
}
for(uint8_t b; b<sizeof(ArrayB_ISR);b++){
ArrayB_Main[b]=ArrayB_ISR[b];
}
SREG=OldSREG;//re-enable them
}
But this means that interrupts are disabled for quite a long time, for the duration of two whole for loopings, a problem if the arrays are long as any interrupt event occuring then will have t wait potentially a rather long time before it can run. I want something where I can preserve the integrity of the arrays, not end up either in the interrupt or themain body where half of the array is from a previous main body or interrupt loop and half is from the latest iteration, and do so with only a few clock cycles of time during which interrupts must be disabled, so that any interrupt arriving during this time will be able to start running almost as fast as if there wasn't a section of the main body where interrupts are disabled.
I understand there is a way with two pointers which swap references to each other (one set of two pointers for the ArrayA situation and another set of two for the ArrayB situation) and give only a disabling interrupts period of two or three instructions while the array pointers get swapped via an extra temporary variable. I'm sure I've heard of this being done, but don't seem to be able to find the right keywords online, most of what searches bring up for terms about arrays swapping and pointers contain for loops doing almost exactly what I show in the slow example for item by item swapping, except with pointers doing it rather than value copies.
Can someone please show me an example for how to quickly swap the arrays between those used by the ISR and those used in the loop code. Needing to get a whole array intact in to or out of an ISR without the long delay involved in for loops or memcpy must be a common problem, and this is a direct swapping scenario not an arbitrary copying between multiple possible places.
Thank you