|
|
View previous topic :: View next topic |
Author |
Message |
Ted Ems
Joined: 30 Dec 2003 Posts: 9
|
Preemptive multitasking |
Posted: Tue Jul 11, 2006 12:26 pm |
|
|
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
|
Retfie |
Posted: Wed Jul 12, 2006 3:24 pm |
|
|
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
|
preemptive multitasking |
Posted: Wed Jul 12, 2006 7:21 pm |
|
|
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
|
|
Posted: Wed Jul 12, 2006 8:06 pm |
|
|
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!! |
|
|
|
|
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
|