My first scheduler..... ugggh

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

My first scheduler..... ugggh

592 Views
techsound
Contributor I

Hey all.  I've been a casual programmer for a couple of years and have done alright but I'm taking a class on embedded microprocessors and we're learning about real time systems. We're learning about schedulers and it is so confusing. If you all know of a couple of good tutorials please let me know.

 

I'm trying to write a scheduler which will set up two threads. Each thread will require 500 ms to complete. My code will compile but I get an illegal breakpoint or Trigger A occured error message. 

 

#include <hidef.h>      /* common defines and macros */
#include <MC9S12C128.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12c128"
 
void Task1(void){
  //DO SOMETHING
}

void Task2(void){  //non real time
   //DO SOMETHING
}

struct TCB{
  unsigned char *StackPt;    //Stack Pointer
  unsigned char MoreStack[91];//100 bytes if stack
  unsigned char InitialReg[7];//initial CCR,B,A,X,Y
  void (*InitialPC)(void);
};

typedef struct TCB TCBType;
TCBType *RunPt;

#define TheTask1 &sys[0] //real time
#define TheTask2 &sys[1] //non real time

TCBType sys[2]={
{ TheTask1.InitialReg[0],{ 0},{0x40,0,0,0,0,0,0},Task1},
{ TheTask2.InitialReg[0],{ 0},{0x40,0,0,0,0,0,0},Task2}
};

struct Node{
  struct Node *Next;
  TCBType *ThreadPt;
  unsigned short TimeSlice;
};

typedef struct Node NodeType;

NodeType *NodePt;
NodeType Schedule[2]={ 
{ &Schedule[1], TheTask1, 500},
{ &Schedule[0], TheTask2, 500}
};

void OS_Sleep(void){ //all this does is run non real time task
asm swi 
}

interrupt 4 void swiISR(void){
 
  asm ldx RunPt   //cooperative multitasking
  asm sts 0,X     //thread goes to sleep when it's done
  RunPt = TheTask2;  //none real time thread
  asm ldx RunPt
  asm lds 0,x
}

interrupt 11 void threadSwitchISR(void){
asm ldx RunPt
asm sts 0,x
NodePt = NodePt->Next;
RunPt = NodePt->ThreadPt;
TC3 = TC3+NodePt->TimeSlice;
TFLG1 = 0x08;
asm ldx RunPt
asm lds 0,x
}

 


void main(void) {

NodePt = &Schedule[0];
RunPt = NodePt->ThreadPt;
TIOS |= 0x08;
TSCR1 = 0x80;
TSCR2 = 0x02;
TIE |= 0x08;
TC3 = TCNT+NodePt->TimeSlice;
TFLG1 = 0x08;
 
asm ldx RunPt;
asm lds 0,x;
asm rti

}

Labels (1)
0 Kudos
3 Replies

432 Views
kef
Specialist I

In your implementation all task routines have to never exit. You need to add for(;:smileywink:{} loops there. Some schedulers allow tasks to end when done.

0 Kudos

432 Views
techsound
Contributor I

Thanks kef.  I updated the tasks to run forever with for(;:smileywink:

 

I still get a Trigger A occured in the command window of the debugger. Any ideas?

0 Kudos

432 Views
kef
Specialist I

Are you using banked memory model? You scheduler is not compatible with this model, since task switching should include save/restore of PPAGE register, which doesn't seem to take place. But it should work even with banked model, while code is small and all tasks are placed in the same PPAGE.

But if it was banked memory model, then I wonder how didn't you receive linkers fixup overflow messages, because I don't see #pragma CODE_SEG NON_BANKED around your service routines.

So try small memory model.

 

What debugger connection are you using? BDM or maybe serial monitor? If second, and if interrupts are enabled by serial monitor already at entry to main(), then try rearranging you main() lines from

 

TIE |= 0x08;
TC3 = TCNT+NodePt->TimeSlice;
TFLG1 = 0x08;

 

to

 

TC3 = TCNT+NodePt->TimeSlice;
TFLG1 = 0x08;
TIE |= 0x08;

And you are not using S12X, but S12C128, right? Because it is not compatible with S12X.

0 Kudos