/*
* acx.c
*
* Created: 12/1/2017
*
* Revisions:
* 12/1/2017 – This version for Escape Team projects (Mysterium)
* 4/20/2017 – Added x_stack_overflow function to catch overflow condition (canary is checked in x_yield).
* – Added x_new_with_args to support passing argc, argv parameters to threads on creation.
*
* Author: E. Frank Barry
*
*/
#include
#include
#include
#include
#include
#include
#include “acx.h”
//—————————————————
// Exec State Variables
//—————————————————
uint8_t x_thread_id;
uint8_t x_thread_mask;
uint8_t x_disable_status;
uint8_t x_suspend_status;
uint8_t x_delay_status;
//—————————————————
// Stack Control
//—————————————————
STACK_CONTROL stack[MAX_THREADS];
//—————————————————
// Stack Memory
//—————————————————
uint8_t x_thread_stacks[STACK_MEM_SIZE];
//—————————————————
// Thread Delay Counters
//—————————————————
unsigned int x_thread_delay[MAX_THREADS];
unsigned long x_system_counter = 0;
//—————————————————
// Canary pointers
//—————————————————
volatile uint8_t *pCanary[MAX_THREADS]={
x_thread_stacks + T0_CANARY_OFFS,
x_thread_stacks + T1_CANARY_OFFS,
x_thread_stacks + T2_CANARY_OFFS,
x_thread_stacks + T3_CANARY_OFFS,
x_thread_stacks + T4_CANARY_OFFS,
x_thread_stacks + T5_CANARY_OFFS,
x_thread_stacks + T6_CANARY_OFFS,
x_thread_stacks + T7_CANARY_OFFS
};
//—————————————————
// Local Functions
//—————————————————
void init_System_Timer(void);
//—————————————————
// ACX Functions
//—————————————————
void x_init(void)
{
cli();
// Initialize thread status variables
// Initialize Stack Control
// Put “canary” values at each stack boundary (low end)
// to allow debug detection of stack overflow
// Initialize System Timer
init_System_Timer();
// Copy return address to Thread 0 stack area
//
// NOTE: This works for Atmega2560 having 3-byte return addresses
// Does not work for parts having two byte return addresses
// Update hardware SP
// Enable interrupts
sei();
// return to caller (now thread 0).
}
/*————————————————————————————–
Function: x_new
Description: Creates a new thread by associating a function pointer with a
specified thread ID and stack. The thread may be created in
either an enabled or disabled state as specified by the isEnabled
parameter. A thread may replace itself by another thread (or restart itself) by
specifying its own ID for this function. If ID ofthe calling thread is specified
then this function does not return to the caller but jumps to the kernel scheduler.
In this case the new (replacement) thread will be scheduled according to its
status.
Input: int tid – the ID of the thread to be created/replaced (a number between 0 and 7)
PTHREAD pthread – a pointer to a function (PTHREAD type – see kernel.h)
bool isEnabled – 1=thread initially enabled, 0=thread initially disabled.
Returns: none
—————————————————————————————*/
void x_new(uint8_t tid, PTHREAD pthread, bool isEnabled)
{
}
/*————————————————————————————–
Function: x_new_args
Description: Creates a new thread by associating a function pointer with a
specified thread ID and stack. The thread may be created in
either an enabled or disabled state as specified by the isEnabled
parameter. A thread may replace itself by another thread (or restart itself) by
specifying its own ID for this function. If ID ofthe calling thread is specified
then this function does not return to the caller but jumps to the kernel scheduler.
In this case the new (replacement) thread will be scheduled according to its
status.
Input: int tid – the ID of the thread to be created/replaced (a number between 0 and 7)
PTHREAD_ARGS pthread – a pointer to a function that takes argc, argv parameters
bool isEnabled – 1=thread initially enabled, 0=thread initially disabled.
Returns: none
—————————————————————————————*/
void x_new_args(uint8_t tid, PTHREAD_ARGS pthread, int argc, char **argv, bool isEnabled)
{
}
//————————————————————-
// init_System_Timer
//
// Sets system timer (Timer 0) for system tick interval
// Start with 1 msec tick.
// Assumes a 16MHz CPU clock.
//————————————————————-
void init_System_Timer(void)
{
return;
}
/*————————————————————————————–
Function: x_delay
Description: Delays the calling thread by the specified number of system “ticks”
by loading the thread’s delay value and setting its delay status bit
to ‘1’. The kernel timer decrements the delay values each system tick
tick and clears the delay status bits of any that reach zero.
Input: none
Returns: Does not return, but enters scheduling loop.
—————————————————————————————*/
void x_delay(unsigned int ticks)
{
}
/*————————————————————————————–
Function: x_gtime
Description: Returns current value of the system tick counter.
Access to the system tick counter must be atomic since it involves
reading a multi-byte value that is written by an interrupt handler.
The k_longtime counter is incremented each system tick. The 32-bit
counter will overflow after (2**32) * (tick_period) seconds. For
example, if the tick interval is 1msec, then it will overflow in
about 49 days. Ifthis kind of overflow will affect thread timing,
it is the responsibility of each thread to check the value returned
to make sure that if overflow occurs, the timing of the thread
does not cause a failure.
Input: none
Returns: unsigned long time – a copy of the system tick counter (32 bits)
—————————————————————————————*/
unsigned long x_gtime(){
}
/*————————————————————————————–
Interrupt Service Routine: TIMER0_COMPA_vect
Description: This interrupt is triggered every N msec based on TIMER0 COMPARE MATCH.
The ISR decrements the first NUM_THREADS delay values and resets
(to zero) the k_delay_status bits if each thread whose counter reaches
zero. If a thread is delayed and its counter reaches zero, then it
is made READY and may be scheduled to run.
—————————————————————————————-*/
ISR(TIMER0_COMPA_vect)
{
}
/*————————————————————————————–
Function: x_suspend
Description: Set specified thread’s suspend status bit
Input: tid – thread ID
Returns: none
—————————————————————————————*/
void x_suspend(uint8_t tid)
{
}
/*————————————————————————————–
Function: x_resume
Description: Clears specified thread’s suspend status bit
Input: tid – thread ID
Returns: none
—————————————————————————————*/
void x_resume(uint8_t tid)
{
}
/*————————————————————————————–
Function: x_disable
Description: Set specified thread’s DISABLE status bit
Input: tid – thread ID
Returns: none
—————————————————————————————*/
void x_disable(uint8_t tid)
{
}
/*————————————————————————————–
Function: x_enable
Description: Clears specified thread’s DISABLE status bit
Input: tid – thread ID
Returns: none
—————————————————————————————*/
void x_enable(uint8_t tid)
{
}
/*————————————————————————————–
Function: x_stack_overflow
Description: Entered when canary check indicates that a thread
exceeded its stack allocation. Does not return.
Flashes the on-board LED with SOS pattern.
Input: none
Returns: none
—————————————————————————————*/
void x_stack_overflow(int thread_id)
{
DDRB |= 0x80;
PORTB &= ~(0x80); // on board LED for MEGA 2560
_delay_ms(100);
while(1){
// Blink thread_id+1 times
for(int i = 0; i <= thread_id; i++){
PORTB ^= 0x80;
_delay_ms(50);
PORTB ^= 0x80;
_delay_ms(500);
}
_delay_ms(5000);
}
}