73 void integrity_check(
void) {
77 if(prio->
prev!=
NULL) { fatal(
"ERR10"); }
81 if(prio->
next->
prev!=prio) { fatal(
"ERR11"); }
86 if(td==
NULL) { fatal(
"ERR13"); }
87 if(td->
priority!=prio) { fatal(
"ERR14"); }
88 if(td->
next->
prev != td) { fatal(
"ERR15"); }
89 if(td->
prev->
next != td) { fatal(
"ERR16"); }
92 }
while(td!=prio->
ctid);
105 #ifndef DOXYGEN_SHOULD_SKIP_THIS
109 .globl _tm_switcher\n\
112 ; r0 saved by system timer handler\n\
114 mov.w r1,@-r7 ; save registers\n\
120 mov.w r7,r0 ; pass sp\n\
122 jsr _tm_scheduler ; call scheduler\n\
124 _tm_switcher_return: \n\
125 mov.w r0,r7 ; set new sp\n\
133 ; r0 will be restored by system timer handler\n\
134 ; r6 will be restored by ROM\n\
136 rts ; return to new task\n\
138 #endif // DOXYGEN_SHOULD_SKIP_THIS
155 if(ctid->
next!=ctid) {
171 priority_head = priority->
next;
195 #endif // CONF_TM_DEBUG
223 priority=priority_head;
242 if(next == priority->
ctid) {
247 priority = priority->
next;
256 priority = priority_head;
271 extern void yield(
void);
272 #ifndef DOXYGEN_SHOULD_SKIP_THIS
278 stc ccr,r0h ; to fake an IRQ, we have to\n\
279 push r0 ; store the registers\n\
280 orc #0x80,ccr ; disable interrupts\n\
282 push r6 ; store r6\n\
284 mov.w #0x04d4,r0 ; store rom return addr\n\
287 push r0 ; store r0 (destroyed by call.)\n\
289 mov.w #_systime_tm_return,r0 ; store systime return addr\n\
292 jmp @_tm_switcher ; call task switcher\n\
294 #endif // DOXYGEN_SHOULD_SKIP_THIS
299 extern int tm_idle_task(
int argc,
char **argv) __attribute__ ((noreturn));
300 #ifndef DOXYGEN_SHOULD_SKIP_THIS
308 #endif // DOXYGEN_SHOULD_SKIP_THIS
314 int tm_man_task(
int argc,
char **argv)
321 #ifndef CONF_LCD_REFRESH
323 #endif // CONF_LCD_REFRESH
329 #ifdef CONF_BATTERY_INDICATOR
333 int tm_battery_task(
int argc,
char **argv) {
348 #endif // CONF_BATTERY_INDICATOR
378 #ifdef CONF_BATTERY_INDICATOR
380 #endif // CONF_BATTERY_INDICATOR
410 tid_t execi(
int (*code_start)(
int,
char**),
int argc,
char **argv,
424 size_t *sp=
malloc(stack_size);
438 if ((
size_t)code_start < (
size_t)&
mm_start)
454 *(--sp)=(
size_t) &
exit;
460 *(--sp)=(
size_t) code_start;
466 *(--sp)=(
size_t) argc;
470 *(--sp)=(
size_t) argv;
483 for( pchain = priority_head;
485 ppchain = pchain, pchain = pchain->
next
487 if(pchain==
NULL || pchain->priority!=priority) {
493 newpchain->
next=pchain;
495 pchain->
prev =newpchain;
496 newpchain->
prev=ppchain;
498 ppchain->
next=newpchain;
500 priority_head=newpchain;
511 td->
next=pchain->ctid;
531 void exit(
int code) {
578 unsigned int msleep(
unsigned int msec)
580 #if defined(CONF_TIME) && defined(CONF_TM)
593 unsigned int sleep(
unsigned int sec)
595 return msleep(1000*sec)/1000;
615 pchain = priority_head;
616 while (pchain !=
NULL) {
619 if ((td->
tflags & flags) != 0) {
625 }
while (td != pchain->
ctid);
626 pchain = pchain->
next;
667 pchain=priority_head;
668 while(pchain!=
NULL && prio<pchain->priority)
671 while(pchain!=
NULL) {
674 if((td!=ctid) && ((td->
tflags & flags) == 0)) {
681 }
while(td!=pchain->
ctid);
#define IDLE_STACK_SIZE
should suffice for IRQ service
void rom_ocia_return()
return address in ROM OCIA handler
struct _pchain_t * next
lower priority chain
wakeup_t wakeup_data
user data for wakeup fn
size_t * tm_scheduler(size_t *old_sp)
the process scheduler
tstate_t tstate
task state
int get_battery_mv()
get current battery voltage
void free(void *ptr)
return the allocated memory to memory management.
void enable_irqs()
enable interrupt processing
Interface: kernel level critical sections.
Interface: console input / output.
#define dlcd_show(a)
set a segment directly in the LCD buffer
#define T_SLEEPING
sleeping. wants to run.
volatile unsigned int nb_tasks
number of tasks
priority chain data structure
#define BATTERY_LOW_THRESHOLD_MV
void mm_reaper()
free all blocks allocated by the current process
Internal Interface: H8/300 bit operations.
unsigned char priority_t
task priority type
#define LEAVE_KERNEL_CRITICAL_SECTION()
volatile unsigned int nb_system_tasks
#define NULL
null pointer value
wakeup_t(* wakeup)(wakeup_t)
event wakeup function
#define dlcd_hide(a)
clear a segment directly in the LCD buffer
#define ENTER_KERNEL_CRITICAL_SECTION()
time_t get_system_up_time(void)
retrieve the current system time
Internal Interface: battery handling.
#define BATTERY_NORMAL_THRESHOLD_MV
void shutdown_tasks(tflags_t flags)
signed int tid_t
task id type
#define TM_DEFAULT_SLICE
default multitasking timeslice
Internal Interface: task management.
#define T_WAITING
waiting for an event
Interface: reduced UNIX standard library.
void killall(priority_t p)
#define PRIO_HIGHEST
The highest possible task priority.
void systime_set_switcher(void *switcher)
set task switcher vector
Internal Interface: memory management.
size_t * stack_base
lower stack boundary
priority_t priority
numeric priority level
void lcd_show(lcd_segment segment)
show LCD segment
tdata_t * ctid
ptr to current process data
tdata_t td_single
single process process data
tflags_t tflags
task flags
void disable_irqs()
disable interrupt processing
void delay(unsigned ms)
uncalibrated delay loop
unsigned long wakeup_t
wakeup data area type
struct _pchain_t * prev
higher priority chain
#define T_KERNEL
task flags
struct _tdata_t * prev
previous task in queue
tid_t execi(int(*code_start)(int, char **), int argc, char **argv, priority_t priority, size_t stack_size)
volatile unsigned char tm_timeslice
task time slice
void shutdown_task(tid_t tid)
#define T_ZOMBIE
terminated, cleanup pending
#define INITIALIZE_KERNEL_CRITICAL_SECTION()
struct _tdata_t * parent
parent task
void * malloc(size_t size)
allocate and return pointer to uninitialized memory
volatile unsigned char tflags_t
task flags type
int tm_idle_task(int, char **)
the idle task
__asm__("\n\
.text\n\
.globl _atomic_inc\n\
_atomic_inc:\n\
stc ccr, r1h ; save flags\n\
orc #0x80, ccr ; disable all but NMI\n\
mov.b @r0, r1l\n\
inc r1l\n\
mov.b r1l, @r0\n\
ldc r1h, ccr ; restore flags\n\
rts\n\
")
unsigned long time_t
time type
#define MSECS_TO_TICKS(a)
conv. mSec's to TICKs
void lcd_refresh(void)
refresh the entire LCD display
void tm_init(void)
init task management
void * systime_tm_return
return address for the task switcher
size_t mm_start
end of kernel code + data
unsigned size_t
data type for memory sizes
void exit(int code) __attribute__((noreturn))
unsigned int sleep(unsigned int sec)
delay execution allowing other tasks to run
struct _tdata_t * ctid
current task in chain
void rom_dummy_handler()
address of an RTS instruction
#define SP_RETURN_OFFSET
return address offset on stack in words.
#define T_SHUTDOWN
shutdown requested
struct _tdata_t * next
next task in queue
Interface: reduced standard C library.
void tm_switcher(void)
the task switcher IRQ handler
void tm_start(void)
start task management
void yield(void)
current task yields the rest of timeslice
Internal Interface: LCD control and constants.
unsigned int msleep(unsigned int msec)
Internal LNP Interface: RCX redirected IRQ vectors.
size_t * sp_save
saved stack pointer
wakeup_t wait_event(wakeup_t(*wakeup)(wakeup_t), wakeup_t data)
Internal Interface: system time functions.
#define shutdown_requested()
test to see if task has been asked to shutdown
void systime_set_timeslice(unsigned char slice)
set multitasking timeslice in ms
pchain_t * priority
priority chain