CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Assign a int16, and interrupt problem?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hmmpic



Joined: 09 Mar 2010
Posts: 314
Location: Denmark

View user's profile Send private message

Assign a int16, and interrupt problem?
PostPosted: Thu Sep 08, 2011 2:36 pm     Reply with quote

This is not running code only some symbolic.
Will it be a problem when assigning the int16 in main module, because Timer0 int can fire in the middle of a assign the HByte and LByte.
Will it be true to disable Timer0 before assigning to the int16 in the main module?
Int8 will be ok? No int can happened in the middle of a instruction.

Hints...



Code:
int8  ms8;
int16 ms16;

#int_TIMER0
void  Timer_0_int(void) {
 set_timer0(Timer0_Reload);
 if (ms8) ms8--;
 if (ms16) ms16--;
}

void main(){

 while (1) {
 
  if (!ms8) {
   //Do something...
   ms8=100; //ms8 is a int8. Cant this go wrong according to my description
  }

  if (!ms16) {
   //Do something...
   ms16=10000;//ms16 is a int16. Cant this go wrong according to my description
  }
 }
}
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

Re: Assign a int16, and interrupt problem?
PostPosted: Thu Sep 08, 2011 4:25 pm     Reply with quote

hmmpic wrote:
This is not running code only some symbolic.
Will it be a problem when assigning the int16 in main module, because Timer0 int can fire in the middle of a assign the HByte and LByte.
Will it be true to disable Timer0 before assigning to the int16 in the main module?
Int8 will be ok? No int can happened in the middle of a instruction.

Hints...



Code:
int8  ms8;
int16 ms16;

#int_TIMER0
void  Timer_0_int(void) {
 set_timer0(Timer0_Reload);
 if (ms8) ms8--;
 if (ms16) ms16--;
}

void main(){

 while (1) {
 
  if (!ms8) {
   //Do something...
   ms8=100; //ms8 is a int8. Cant this go wrong according to my description
  }

  if (!ms16) {
   //Do something...
   ms16=10000;//ms16 is a int16. Cant this go wrong according to my description
  }
 }
}


It depends on the PIC family. 16 and 32 bit PIC families would not have a problem. For 8 bit PICs you would need to disable the timer interrupt before modifying the 16 bit variable in the main exec loop and re-enable the interrupt after the change.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Sep 09, 2011 1:55 am     Reply with quote

Yes, for the older PIC families, the 8 bitters, any 16 bit (or 32 bit, or float or even 8 bit signed multiplies) operation is not, in the language of computer science, "atomic". An operation is atomic if the processor can run it without being interrupted. That effectively means if something can be done in a single machine instruction its atomic. Two or more instructions can be interrupted. This is because most, if not all processors can only deal with interrupts between instructions. On the 18Fs 8 by 8 bit unsigned multiplies are atomic - a single instruction, 8 by 8 *signed* multiplies require more than one instruction and so are NOT atomic. This is not the case on the 16Fs which don't have hardware multipliers, and the 24s and 30s have 16 bit multipliers so its different for them.

To make a code sequence, however long, atomic you have to disable interrupts before it, and reenable after. This makes what is know as a "critical section", and the code within can be regarded as atomic.

Generally writing anything both inside interrupt routines (isr) and outside in non-interrupt code is not advised. Sometimes you cannot avoid it, such as when implementing IO buffers such as circular buffers. Its always a good idea, and with any production standard firmware mandatory, to use critical sections in buffer handling code called from non-interrupt code. Operations such as reading from a receive buffer filled by interrupt code should always be critical sections, so called "interrupt locking". The result of NOT doing this may generally not be obvious, but you end up loosing characters and getting them out of order occasionally. At worst the buffer pointers can be corrupted resulting in major RAM corruption. Beware that operations such as peeking into the buffer and counting the characters in the buffer must also be atomic AND combos such as count, then read must be treated as single atomic processes. Consider what might happen if you count the characters in a serial input buffer, then an interrupt happens which adds more characters to the buffer, then you try to read... what, exactly will happen? You might get away with it... but then again you might not, especially if the buffer was full.

Critical sections should be kept as short as possible as the relevant interrupts will be delayed, and possibly lost altogether. Also the interrupts that are disabled should be as specific as possible. There no need to turn off all interrupts when the only one that matters is serial receive on one port.

Note that the CCS and Microchip examples do not have this locking. They are not fully developed practical code, just simple examples of the basics. This is the sort of thing that used to be taught in computer science courses, I do not know if it still is, mainly as in a PC dominated, hardware abstracted, common runtime, machine independant world its irrelevant. But for embedded firmware, even in C, its as important as it ever was.

RF Developer
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group