/* RLPOS: RLPotter Operating System Version 0.5 for the 68HC12D60A microcontroller by Ryan Potter ryan@rlpotter.com v0.5.1: - implement task msg box system - use linked list w/ task addresses v0.5 April 16, 2003: - added priority preemption - finished kernel task state switcher - it is now officially a legitimate rate monotonic priority preemptive multitasking Real Time Operating System :) - made kernel.c and semlib.c consistent with the rest of the kernel - included the early framework for a msg box system v0.4 April 13, 2003: 8096 bytes - gerneralized the shell command-line input parser: cmd (up to 32 chars) - added kernel and shell functions v0.3 April 12, 2003: 6155 bytes - added a beginning shell user interface. - added a resource control block and basic semaphore functions. - added basic kernel functions v0.2 April 9, 2003: - able to round-robin with RTI interrupt. - bonified/certified multitasking with 3 tasks. :) v0.1 April 3, 2003: - able to round-robin without interrupts. - not multitasking, really. v0.0 started April 1, 2003; 0 bytes - no idea where to start. - don't want to look at anyone else's work. ;0) Architecture/C assumptions: 1) 'D' register is the accumulator 2) 'X' register points to the top of the current stack 3) 'Y' register is for general use in indexed operations 4) the heap grows upward and mem segments allocated by malloc, realloc, and calloc are linear and contiguous. 5) the stack grows downwards, and there is no boundary checking. Potential problem areas: 1) 'running' section of the kernel get's compiled using extra push and pop instructions 2) run out of ram (global + stack + heap) */ #include <912d60.h> #include #include #include "kernel.h" // FUNCTION PROTOTYPES void RTI_handler(void); void shell(void); void task1(void); void task2(void); void (*task_ptr[])(void) = {&shell, &task1, &task2}; // GLOBAL VARIABLES unsigned char *main_frame_ptr = NULL; // bottom of main() frame unsigned char *main_frame_x_ptr = NULL; // top of main() frame (x-reg ptr) unsigned char *temp_task_frame_ptr = NULL; // temp CCR pointer for RTI extern unsigned int current; // current task id number extern unsigned long int system_tick; // task control block extern struct task_block { unsigned char id; // ID of task enum task_state state; // State unsigned char priority; // Priority unsigned long int period_tick; // for determining if deadline is up unsigned int interrupt_msg_box; // flags for pending interrupts enum message_box message; // misc flags unsigned char message_data[8]; // data for misc_msg_box flags unsigned char *heap_ptr; // heap addr while not current task unsigned int heap_size; // heap size unsigned char *frame_ptr; // CCR pointer }; // resource control block extern struct resource_block { unsigned char id; // ID of resource enum resource_state state; // State (busy, free...) unsigned char user; // Current resource user/owner signed char queue[3]; // Tasks waiting on resource unsigned char queue_pos; // Next free spot in queue }; extern struct task_block task[numtasks]; extern struct resource_block resource[numresources]; main() { // LOCAL VARIABLES int result; unsigned int i, temp_heap_size; unsigned int last_task = 0; unsigned char *temp_heap_ptr, temp, priority_check; unsigned long int deadline; extern int _bss_end, _textmode; extern unsigned int current; extern unsigned long int system_tick; _textmode = 1; // maps '\n' to "CR/LF" for Windows terminals current = 0; // start the shell first // initialize the task structures for (i=0; i= numtasks) next_task = 0; current = next_task;*/ // RT PRIORITY BLOCK: // set the current task id based on priority and deadline // determine if the deadline is up for idle tasks /* deadline, is equal to period plus an initial time (t0) reference (t0 = system_tick). Period = priority + 1. Changing the state from idle to pending occurs here. */ for (i=0; i= deadline) { task[i].state = pending; // change state at deadline //puts("promote"); } } // if (task[i].message) {} } // set current = highest priority pending/running task. priority_check = 255; // lowest possible for (i=0; i