File "os.h"
Full Path: /home/analogde/www/68hc11/os.h
File size: 7.42 KB
MIME-type: text/x-c
Charset: utf-8
/*
* os.h - os defines
*
* $Id: os.h,v 1.17 2002/08/03 17:52:57 tomdean Exp $
*/
#ifndef _OS_H_INCLUDED
#define _OS_H_INCLUDED
/*
********************************************************
* structures
*/
/*
* if DEBUG is defined, use error1 and error3 rather than lcd_row_x */
/* #define DEBUG 1 */
/* #define SHOW_GPS_COUNT */
#define SHOW_GPS_DATA 1
/* number of tasks */
#define NUM_TASK 8
/* trace */
typedef struct trace_t {
unsigned char task;
unsigned char cmd;
unsigned char cmd_arg;
unsigned char state[NUM_TASK+1];
unsigned short stack[NUM_TASK+1];
} trace_t;
extern trace_t *next_trace;
/* task state */
typedef enum {
halt,
wait_timer,
wait_msg,
run,
ready
} state_t;
/* system calls */
typedef enum {
sys_wait_timer,
sys_stop,
sys_start,
sys_send,
sys_recv,
sys_recv_wait,
sys_queue,
sys_dequeue,
sys_done
} operation_t;
/* context */
typedef struct context_t {
unsigned short sp;
state_t state;
} context_t;
/* interrupt vector */
typedef struct vector_t {
unsigned char opcode;
unsigned short task;
} vector_t;
#define MSG_BUF_SIZE 82
/*
* task message queue
* A GPS message may have 81 characters in it!
*/
#define MSG_BUF_SIZE 82
typedef struct msg_t {
unsigned char task; /* from task */
unsigned char empty; /* are we done with it? */
struct msg_t *next; /* linked list */
/* XXX fix me what is the longest gps message? */
unsigned char buf[MSG_BUF_SIZE]; /* msg body */
} msg_t;
extern msg_t *msg_queue[];
#ifndef NULL
#define NULL 0
#endif
/*
* system call
* status
* success
* failure unknown reason or lazy coding on my part
* unsupported operation
* illegal task number
* destination queue full
*/
typedef enum {
success,
gen_failure,
unsupported_op,
ill_task_num,
dest_que_full
} sys_call_stat_t;
/* and, the structure */
typedef struct sys_call_t {
unsigned char operation;
unsigned char task_num;
unsigned short timer;
sys_call_stat_t status;
msg_t *msg_ptr;
} sys_call_t;
/*
* system call structures, one for each task
* the index is task number, which is 1..8
*/
extern sys_call_t sys_call[];
/*
* use these defines to access the system functions in swi()
* you can manipulate the structure and do an swi() directly,
* but, it is easier to make a mistake. Don't blame me if strange
* things start to happen...
*/
#define SYS_OP sys_call[cur_task].operation
#define SYS_TIMER sys_call[cur_task].timer
#define SYS_TASK sys_call[cur_task].task_num
#define SYS_MSG sys_call[cur_task].msg_ptr
#define SYS_WAIT_TIMER(n) SYS_OP=sys_wait_timer; SYS_TIMER=n; swi()
#define SYS_STOP(t) SYS_OP=sys_stop; SYS_TASK=t; swi()
#define SYS_START(t) SYS_OP=sys_start; SYS_TASK=t; swi()
#define SYS_SEND(t, m) SYS_OP=sys_send; SYS_TASK=t; SYS_MSG=m; swi()
#define SYS_RECV(m) SYS_OP=sys_recv; swi(); m = SYS_MSG
#define SYS_RECV_WAIT(m) SYS_OP=sys_recv_wait; swi(); m = SYS_MSG
#define SYS_QUEUE(t, m) SYS_OP=sys_send; SYS_TASK=t; SYS_MSG=m; swi()
#define SYS_DEQUEUE(m) SYS_OP=sys_dequeue; swi(); m = SYS_MSG
#define SYS_DONE() SYS_OP=sys_done; swi()
/*
* definitions for tasks
*/
#define TASK1 1
#define TASK2 2
#define ADC_TASK 3
#define GPS_TASK 4
#define TASK5 5
#define CLI_TASK 6
#define TASK7 7
#define DIS_TASK 8
/*
* system clock definitions
*/
typedef struct m6811_clock_t {
unsigned char ticks;
unsigned char seconds;
unsigned char minutes;
unsigned char hours;
unsigned char days;
unsigned char months;
unsigned short years;
} m6811_clock_t;
extern m6811_clock_t m6811_clock;
extern unsigned long tick_count;
/*
* interrupt vector locations. Note: this changed after 7/23/2002.
*/
#define sci_sect_vector (vector_t *)0x7FC4
#define spi_sect_vector (vector_t *)0x7FC7
#define pai_sect_vector (vector_t *)0x7FCA
#define pao_sect_vector (vector_t *)0x7FCD
#define tof_sect_vector (vector_t *)0x7FD0
#define toc5_sect_vector (vector_t *)0x7FD3
#define toc4_sect_vector (vector_t *)0x7FD6
#define toc3_sect_vector (vector_t *)0x7FD9
#define toc2_sect_vector (vector_t *)0x7FDC
#define toc1_sect_vector (vector_t *)0x7FDF
#define tic3_sect_vector (vector_t *)0x7FE2
#define tic2_sect_vector (vector_t *)0x7FE5
#define tic1_sect_vector (vector_t *)0x7FE8
#define rti_sect_vector (vector_t *)0x7FEB
#define irq_sect_vector (vector_t *)0x7FEE
#define xirq_sect_vector (vector_t *)0x7FF1
#define swi_sect_vector (vector_t *)0x7FF4
#define illop_sect_vector (vector_t *)0x7FF7
#define cop_sect_vector (vector_t *)0x7FFA
#define clkfail_sect_vector (vector_t *)0x7FFD
/* m68hc11 instructions */
#define RTI 0x3b
#define JMP 0x7e
/*
* task stack size.
* XXX fix me - change this to have a stack definition for each task
* to allow tuning the stack size for task requirements
*/
#define STACK_SIZE 80
/*
* rti() decrements tocks, and, when zero, does a context switch to
* the next ready task in a round-robin fashion.
* Normally, there are 4 ticks per tock. This may be changed
* by setting TICKS_PER_TOCK
* looks like the display task may need ~ 20 msec
*/
#define TICKS_PER_TOCK 6
extern unsigned char tocks;
/*
* debug outputs on porta
*/
#define DEBUG_ON(n) _io_ports[M6811_PORTA] |= n;
#define DEBUG_OFF(n) _io_ports[M6811_PORTA] &= ~n;
/*
********************************************************
* prototypes
*/
typedef void(*task_t)(void);
void add_handler(vector_t *, task_t);
void clear_handler(vector_t *, task_t);
void task_init(unsigned char, task_t, unsigned char *);
/* swi functions */
void put_message(unsigned char, msg_t *);
void get_message();
/* sci functions */
void sci_init();
void sci_send(unsigned char *);
/* display functions */
void display();
void display_init();
void display_clear();
/* gps functions */
void gps();
void gps_init();
void show_gps_count();
/* short hand */
#define TRAP(x) void x() __attribute__((trap))
#define INTERRUPT(x) void x() __attribute__((interrupt))
/*
* prototypes for trap and interrupt routines
* Using this format allows the routine to be defined
* as 'void xxx()' in the source file
*/
TRAP(swi);
INTERRUPT(sci);
INTERRUPT(rti);
/* short hand */
#define TASK(x) void task##x()
#define STACK(x) extern unsigned char stack##x[]
/*
* define the tasks and the respective stack
*/
TASK(1); STACK(1);
TASK(2); STACK(2);
/* task 3 */
void adc();
extern unsigned char adc_stack[];
/* task 4 */
void gps();
extern unsigned char gps_stack[];
TASK(5); STACK(5);
/* task 6 */
void cli();
extern unsigned char cli_stack[];
TASK(7); STACK(7);
/* task 8 */
void display();
extern unsigned char display_stack[];
/* number of the running task */
extern unsigned char cur_task;
/* context pointers and definitions related to context switch */
extern context_t *context[];
#define PSH_SOFT_REG(x) asm("ldx %0"::"m"( x )); asm("pshx")
#define POP_SOFT_REG(x) asm("pulx"); asm("stx %0":"=m"( x ))
#define SET_SP(x) asm("lds %0" ::"m" ( x ))
#define SAV_SP(x) asm("sts %0" ::"m" ( x ))
#define POP_FRAME_Y asm("puly")
#define PSH_FRAME_Y asm("pshy")
/* timers - the index is task_num, which is 1..8 */
extern unsigned short timer[];
/*
* message queue, one for each task
* the index is task number, which is 1..8
*/
extern msg_t *msg[];
/*
* sci buffer and control
*/
#define NUM_SCI 8
extern msg_t sci_buf[];
extern msg_t *cur_sci_buf;
/*
* convert a word bin to hex-ascii in buffer ptr
*/
void hex_to_ascii_4(unsigned short, unsigned char *);
void hex_to_ascii_2(unsigned char, unsigned char *);
#endif