The T command shows the current wchan and PC for each task in the system.
/* Stack runs from above the allocated __data space to 0xfe, which avoids
* writing to 0xff as that triggers the stack overflow indicator
*/
-#define AO_STACK_START 0x6f
+#define AO_STACK_START 0x62
#define AO_STACK_END 0xfe
#define AO_STACK_SIZE (AO_STACK_END - AO_STACK_START + 1)
__xdata void *wchan; /* current wait channel (NULL if running) */
uint8_t stack_count; /* amount of saved stack */
uint8_t task_id; /* index in the task array */
+ __code char *name; /* task name */
uint8_t stack[AO_STACK_SIZE]; /* saved stack */
};
/* Add a task to the run queue */
void
-ao_add_task(__xdata struct ao_task * task, void (*start)(void));
+ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name);
+
+/* Dump task info to console */
+void
+ao_task_info(void);
/* Start the scheduler. This will not return */
void
"l Dump last flight log\n"
"E <0 off, 1 on> Set command echo mode\n"
"S<data> Send data to serial line\n"
+ "T Show task states\n"
"\n"
"Target debug commands:\n"
"D Enable debug mode\n"
case 'l':
dump_log();
break;
+ case 'T':
+ ao_task_info();
+ break;
case 'S':
send_serial();
break;
void
ao_cmd_init(void)
{
- ao_add_task(&ao_cmd_task, ao_cmd);
+ ao_add_task(&ao_cmd_task, ao_cmd, "cmd");
}
/* Main flight thread. */
__xdata struct ao_adc ao_flight_data; /* last acquired data */
-__data enum flight_state ao_flight_state; /* current flight state */
-__data uint16_t ao_flight_tick; /* time of last data */
-__data int16_t ao_flight_accel; /* filtered acceleration */
-__data int16_t ao_flight_pres; /* filtered pressure */
-__data int16_t ao_ground_pres; /* startup pressure */
-__data int16_t ao_ground_accel; /* startup acceleration */
-__data int16_t ao_min_pres; /* minimum recorded pressure */
-__data uint16_t ao_launch_time; /* time of launch detect */
-__data int16_t ao_main_pres; /* pressure to eject main */
+__pdata enum flight_state ao_flight_state; /* current flight state */
+__pdata uint16_t ao_flight_tick; /* time of last data */
+__pdata int16_t ao_flight_accel; /* filtered acceleration */
+__pdata int16_t ao_flight_pres; /* filtered pressure */
+__pdata int16_t ao_ground_pres; /* startup pressure */
+__pdata int16_t ao_ground_accel; /* startup acceleration */
+__pdata int16_t ao_min_pres; /* minimum recorded pressure */
+__pdata uint16_t ao_launch_time; /* time of launch detect */
+__pdata int16_t ao_main_pres; /* pressure to eject main */
/*
* track min/max data over a long interval to detect
* resting
*/
-__data uint16_t ao_interval_end;
-__data int16_t ao_interval_cur_min_accel;
-__data int16_t ao_interval_cur_max_accel;
-__data int16_t ao_interval_cur_min_pres;
-__data int16_t ao_interval_cur_max_pres;
-__data int16_t ao_interval_min_accel;
-__data int16_t ao_interval_max_accel;
-__data int16_t ao_interval_min_pres;
-__data int16_t ao_interval_max_pres;
+__pdata uint16_t ao_interval_end;
+__pdata int16_t ao_interval_cur_min_accel;
+__pdata int16_t ao_interval_cur_max_accel;
+__pdata int16_t ao_interval_cur_min_pres;
+__pdata int16_t ao_interval_cur_max_pres;
+__pdata int16_t ao_interval_min_accel;
+__pdata int16_t ao_interval_max_accel;
+__pdata int16_t ao_interval_min_pres;
+__pdata int16_t ao_interval_max_pres;
#define AO_INTERVAL_TICKS AO_SEC_TO_TICKS(5)
void
ao_flight(void)
{
- __data static uint8_t nsamples = 0;
+ __pdata static uint8_t nsamples = 0;
for (;;) {
ao_sleep(&ao_adc_ring);
ao_interval_max_pres = 0x7fff;
ao_interval_end = AO_INTERVAL_TICKS;
- ao_add_task(&flight_task, ao_flight);
+ ao_add_task(&flight_task, ao_flight, "flight");
}
#include "ao.h"
-__data uint32_t ao_log_current_pos;
-__data uint32_t ao_log_start_pos;
-__xdata uint8_t ao_log_running;
-__xdata uint8_t ao_log_mutex;
+static __pdata uint32_t ao_log_current_pos;
+static __pdata uint32_t ao_log_start_pos;
+static __xdata uint8_t ao_log_running;
+static __xdata uint8_t ao_log_mutex;
static uint8_t
ao_log_csum(uint8_t *b)
ao_log_state = ao_flight_invalid;
/* Create a task to log events to eeprom */
- ao_add_task(&ao_log_task, ao_log);
+ ao_add_task(&ao_log_task, ao_log, "log");
}
__xdata struct ao_task *__data ao_cur_task;
void
-ao_add_task(__xdata struct ao_task * task, void (*start)(void))
+ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name)
{
uint8_t __xdata *stack;
if (ao_num_tasks == AO_NUM_TASKS)
ao_panic(AO_PANIC_NO_TASK);
ao_tasks[ao_num_tasks++] = task;
task->task_id = ao_num_tasks;
+ task->name = name;
/*
* Construct a stack frame so that it will 'return'
* to the start of the task
if (ao_cur_task_index != AO_NO_TASK_INDEX)
{
- uint8_t stack_len;
- __data uint8_t * stack_ptr;
- __xdata uint8_t * save_ptr;
+ uint8_t stack_len;
+ __data uint8_t *stack_ptr;
+ __xdata uint8_t *save_ptr;
/* Save the current stack */
stack_len = SP - (AO_STACK_START - 1);
ao_cur_task->stack_count = stack_len;
{
uint8_t stack_len;
- __data uint8_t * stack_ptr;
- __xdata uint8_t * save_ptr;
+ __data uint8_t *stack_ptr;
+ __xdata uint8_t *save_ptr;
/* Restore the old stack */
stack_len = ao_cur_task->stack_count;
}
void
-ao_start_scheduler(void)
+ao_task_info(void)
{
+ uint8_t i;
+ uint8_t pc_loc;
+ for (i = 0; i < ao_num_tasks; i++) {
+ pc_loc = ao_tasks[i]->stack_count - 17;
+ printf("%-8s: wchan %04x pc %04x\n",
+ ao_tasks[i]->name,
+ (int16_t) ao_tasks[i]->wchan,
+ (ao_tasks[i]->stack[pc_loc]) | (ao_tasks[i]->stack[pc_loc+1] << 8));
+ }
+}
+
+void
+ao_start_scheduler(void)
+{
ao_cur_task_index = AO_NO_TASK_INDEX;
ao_cur_task = NULL;
ao_yield();
USBOIF = 0;
USBIIF = 0;
- ao_add_task(&ao_usb_task, ao_usb_ep0);
+ ao_add_task(&ao_usb_task, ao_usb_ep0, "usb");
}