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 CCS Technical Support

Preemptive multitasking

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



Joined: 30 Dec 2003
Posts: 9

View user's profile Send private message

Preemptive multitasking
PostPosted: Tue Jul 11, 2006 12:26 pm     Reply with quote

If this program is ran the instruction movff tcb_temp.strstkptr,stkptr
causes a reset condition. Can anyone help in determining what causes this. Any help would be greatly appreciated.
Code:
#include <18F2610>
#zero_ram
#device adc=10 icd=true high_ints=true
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOSTVREN                   //Stack full/underflow will cause reset
#FUSES DEBUG                  //No Debug mode for ICD
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#define Serial_RX_PIN       PIN_C7
#define Serial_TX_PIN       PIN_C6

#use delay(clock=22130000)
#use rs232(baud=57600, xmit=Serial_TX_PIN, rcv=Serial_RX_PIN, errors)
#byte stkptr=0xffc
#byte prodh=0xff4
#byte prodl=0xff3
#byte fsr0h=0xfea
#byte fsr0l=0xfe9
#byte w=0xfe8
#byte fsr1h=0xfe2
#byte fsr1l=0xfe1
#byte bsr=0xfe0
#byte fsr2h=0xfda
#byte fsr2l=0xfd9
#byte status=0xfd8
#byte   tmr0h=0xfd7
#byte   tmr0l=0xfd6
#byte   TOSU=0xfff
#byte       TOSH=0xffe
#byte       TOSL=0xffd
#byte        PIR2 = 0xFA1
#byte PIE1 = 0xF9D
#byte PIR1 = 0xF9E
#BYTE RCSTA = 0xFAB
#BYTE TXSTA = 0xFAC
#BYTE TXREG = 0xFAD
#BYTE RCREG = 0xFAE
#BYTE INTCON = 0xFF2
#BYTE t0con = 0xfd5
#define RX9  6
#define TX9D 0
#define TXEN 5
#define TX9  6
#define TX1IF   4
#define TRMT 1
#define CREN 4
#define SPEN 7
#define TMR0IE 5
#define GIE 7
#define tmr0if 2

#include "C:\CCS Projects\another rtos\rtos.h"
#define   Max_Task   2
#define   Setup      0
#define   Run      1

struct tcb{
   int8 strprodh;
   int8 strprodl;
   int8 strfsr0h;
   int8 strfsr0l;
   int8 strwreg;
   int8 strfsr1h;
   int8 strfsr1l;
   int8 strbsr;
   int8 strfsr2h;
   int8 strfsr2l;
   int8 strstatus;
   int8 strstkptr;
   int8 stackl;
   int8 stackh;
};


struct tcb Task_TCB[2];
struct tcb tcb_temp;


int8   task_table[4];
int8   current_task;
long   timers[5];
int8    i0;

//////////////////////////////////////////////////////////////////////////////
//
#INT_TIMER0 fast
void timer0_interrupt()
{
   static int8 i,j;
#asm
   bcf   t0con,7
   movwf   tcb_temp.strwreg
   movff status,tcb_temp.strstatus
   movff prodh,tcb_temp.strprodh
   movff prodl,tcb_temp.strprodl
   movff fsr0h,tcb_temp.strfsr0h
   movff fsr0l,tcb_temp.strfsr0l
   movff fsr1h,tcb_temp.strfsr1h
   movff fsr1l,tcb_temp.strfsr1l
   movff bsr,tcb_temp.strbsr
   movff fsr2h,tcb_temp.strfsr2h
   movff fsr2l,tcb_temp.strfsr2l
   movff   stkptr,tcb_temp.strstkptr
#endasm

   memcpy(&Task_TCB[current_task],&tcb_temp,14);
   current_task++;
   if (current_task >=Max_Task)
      current_task=0;
   memcpy(&tcb_temp,&Task_TCB[current_task],14);

#asm
   movff tcb_temp.strstkptr,stkptr
   movff tcb_temp.strfsr2l,fsr2l
   movff tcb_temp.strfsr2h,fsr2h
   movff tcb_temp.strbsr,bsr
   movff tcb_temp.strfsr1l,fsr1l
   movff tcb_temp.strfsr1h,fsr1h
   movff tcb_temp.strfsr0l,fsr0l
   movff tcb_temp.strfsr0h,fsr0h
   movff tcb_temp.strprodl,prodl
   movff tcb_temp.strprodh,prodh
   movff   tcb_temp.strwreg,w
   movff tcb_temp.strstatus,status
   bsf   t0con,7
   bcf   intcon,tmr0if
   retfie 0
#endasm
}
void Task0(byte Task_Control)
{
   if (Task_Control > 0)
   {
      enable_interrupts(INT_TIMER0);      // Timer 0
      enable_interrupts(GLOBAL);
      Task0_lbl:

      do
      {
         if (timers[2]==0){
              timers[2]=8000;
            printf("done it again" );
           Output_TOGGLE(pin_b3);
         }

      }
      while(1);
   }
   else
   {
      Task_TCB[0].stackl = make8(label_address(Task0_lbl),0);
      Task_TCB[0].stackh = make8(label_address(Task0_lbl),1);
   }
}

//////////////////////////////////////////////////////////////////////////////
//
void Task1(byte Task_Control)
{
   if (Task_Control > 0)
   {
      Task1_lbl:

      do
      {

        if (timers[0]==0){
              timers[0]=17857;
              Output_toggle(pin_b4);
        }
      }
      while(1);
   }
   else
   {
      Task_TCB[1].stackl = make8(label_address(Task1_lbl),0);
      Task_TCB[1].stackh = make8(label_address(Task1_lbl),1);
   }
}


void Task_Init()
{
   Task0(Setup);
   Task1(Setup);


                                    // waiting for a keypressed
}
//////////////////////////////////////////////////////////////////////////////
//
void main ()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_8_bit);
   set_tris_b(0xE7);
   output_low(pin_b4);
   output_low(pin_b3);
   Task_Init();
   task_table[0]=1;
   task_table[1]=16;
   current_task=0;
#asm
   movff task_table, STKPTR
   movff   task_table,Task_TCB[0].strstkptr
   movlw Task_TCB[0].stackl
   movwf TOSL
   movlw Task_TCB[0].stackh
   movwf TOSH
   clrf    TOSU
    movff task_table+1,STKPTR
   movff   task_table+1,Task_TCB[1].strstkptr
   movlw Task_TCB[1].stackl
   movwf TOSL
   movlw Task_TCB[1].stackh
   movwf TOSH
   clrf TOSU
   movff task_table, STKPTR
   bsf INTCON, TMR0IE  //Enable timer 0 interrupt
   bsf INTCON, GIE        //Enable global interrupts
#endasm
}


DaveThib



Joined: 17 Oct 2004
Posts: 15
Location: New Hampshire USA

View user's profile Send private message

Retfie
PostPosted: Wed Jul 12, 2006 3:24 pm     Reply with quote

I think your problem may be the RETFIE you have in the inline assembly code. You code will call cause a return from the interrupt then when the end of the ISR is reached, which is the next line, the CCS compiler will generate a RETFIE instruction which will return to the start of your code or something like that. So you basically are returning twice from your interrupt.
So get rid of the RETFIE and give that a shot.
Ted Ems



Joined: 30 Dec 2003
Posts: 9

View user's profile Send private message

preemptive multitasking
PostPosted: Wed Jul 12, 2006 7:21 pm     Reply with quote

Dave
The retfie inserted by the ccs compiler is actually a fast interrupt return. This uses those shadow registers for the fast stack and replaces the w and bsr registers. The return must return the next stacks w and bsr not what is on the fast return stack, hence the retfie. I did fix the problem.
You cannot use a movff instruction with the stkptr register. I believe this is mentioned somewhere in microchips data sheets but i had forgotten.
Anyway now i have other problems, see later posts.

Thanks for the input!
asmallri



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

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

PostPosted: Wed Jul 12, 2006 8:06 pm     Reply with quote

I solved this problem differently. I wrote my handler as a standard function (coded in assembler only) and specified an origin address. I redirected the interrupt handler vectors that CCS uses with the build instruction to point to some dummy location. I then placed a goto instructions at the real vector locations to the origin of the appropriate handlers. I had to do the low level interupt priority enabling etc.

This way your handler can use whichever return from interrupt mechanism is appropriate.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
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