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

Bug in the main interrupt handler and serial communication

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



Joined: 05 May 2010
Posts: 1

View user's profile Send private message

Bug in the main interrupt handler and serial communication
PostPosted: Wed May 05, 2010 9:01 am     Reply with quote

Hi everybody.

I've a project written in CCS C Compiler.

The prior version of this project use two interrupts: timer0/rtcc (for time counting (timeouts)) and rda (receiving data from the serial port).

The prior version is working fine.

The new version of this project use one more interrupt: external interrupt 0 (int_ext) for radio communication.

After this point I've notice some problems.

My suspicions fall on the main interruption handler of the CCS C Compiler.

And when I compiled the project source code, I analyzed the LST file wich contains both source code and the generated assembly code.

The logic of this main interruption handler is the following:

1 - Save the context (save several register values in RAM).

2 - If the external interrupt 0 is not enabled, go to step 4.

3 - If the external interrupt 0 was trigged, go to the external interrupt 0 handler.

4 - If the timer0 interrupt is not enabled, go to step 6.

5 - If the timer0 interrupt was trigged, go to the timer0 interrupt handler.

6 - If the rda interrupt is not enabled, go to step 8.

7 - If the rda interrupt was triggered, go to the rda interrupt handler.

8 - Restore the context (restore the register values from RAM).

9 - Return from this main interrupt handler (RETFIE).

I see no problem in this main interruption handler, but I found a problem after the end of each of user interruption handler.

After each user interruption handler, the CCS C Compiler put assembly code for clear the respective triggered interruption flag (INT0IF, TMR0IF, RCIF), and return to the main interruption handler via GOTO statement.

The problem is the address puted in the GOTO statement.

For example, the first interrupt checked in the main interruption handler is the user external interrupt 0 handler.

After the code of this handler, there's code to clear the INT0IF flag (perfect) and a GOTO statement for the step 8.

The execution of the program should return to the step 4, not the step 8.

The same problem happens in the second user interruption handler (timer0), where there's a GOTO statement to the step 8 and should be to the step 6.

Following this logic, if the three interrupts (int_ext, timer0 and rda) were triggered at same time (hypothetical situation), just the int_ext handler was executed, but not the timer0 and rda handler.

I've solved this problem placing a GOTO statement via #ASM/#ENDASM directives, jumping to the correct step.

After it, I don't need more to disable and reenable some interrupts at some points of the program to try to balance these handlers.

Now I found other problem in the serial module, in other words, I need to reenabled the rda interrupt periodically until receive the right data via serial port.

I didn't find the source of this problem, but the first problem was solved.

Anyone had detected problem with the serial ports using CCS C Compiler 4.088?

If I don't reenable periodically the rda interrupt until receive the data, I will never receive any data via serial port.

Any clue about this situation?

Thanks in advance.
Ttelmah



Joined: 11 Mar 2010
Posts: 19328

View user's profile Send private message

PostPosted: Wed May 05, 2010 9:36 am     Reply with quote

You need to post what chip is involved. There are a number of 'issues' with specific PICs on the behaviour of the UART. This might be your problem.

The behaviour you describe with regard to the interrupts, is not a problem, but normal coding. You have to remember that in most situations, you want to get out of the interrupt handler reasonably quickly, in order to be doing other work in the main. Hence CCS, services just one interrupt at a time. This won't result in the interrupts being missed, but does allow the main code to still advance one instruction at a time. If you want to service all three sequentially, then the normal way would be to take over command of the interrupts completely, by using int_global. Using an assembler jump, is potentially dangerous, because if anything at all changes in future releases of the compiler your code will fail...
The #priority directive, allows you to specify which interrupt will be checked first.

It sounds though as if your main problem is how long int_ext is taking to handle. Are you using a software serial handler inside INT_EXT?. If so, this will mean that the code for this interrupt handler will stay inside the routine for the entire byte time of the character, with only a single 'bit time' available for everything else, if data is arriving continuously. This will be the fundamental problem. This apporach is only really 'OK' for relatively infrequent data. If a lot of data is arriving over the radio, you may perhaps want to consider using the hardware UART for this channel, rather than whatever it is currently doing. Alternatively look at a timer based 'state machine' serial receive routine. I have posted basic code for this in the past.

Best Wishes
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