Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export OBJS := \
\
../src/tasks/task_list.o \
\
../src/tasks/adcs/adcs_main.o \
../src/tasks/adcs/adcs_task.o \
\
../src/tasks/photodiode/photodiode_main.o \
../src/tasks/photodiode/photodiode_task.o \
../src/tasks/photodiode/photodiode_driver.o \
Expand All @@ -84,6 +87,7 @@ export EXTRA_VPATH := \
../../src/tasks/display/image_buffers \
../../src/tasks/task_manager \
../../src/tasks/command_dispatcher \
../../src/tasks/adcs \
../../src/tasks/magnetometer \
../../src/tasks/shell \
../../src/tasks/photodiode \
Expand Down
52 changes: 52 additions & 0 deletions src/tasks/adcs/adcs_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* adcs_main.c
*
* Main loop of the satellite's ADCS (Attitude Determination and Control System) RTOS task
*
* Created: Nov 23, 2025
* Authors: Yi Lyo
**/

#include "adcs_task.h"

// ADCS Task memory structures
adcs_task_memory_t adcs_mem;

/**
* \fn main_adcs
*
* \param pvParameters a void pointer to the parameters required by the
* ADCS task; not currently set by config
*
* \warning should never return
*/
void main_adcs(void *pvParameters) {
info("adcs: Task Started!\n");

// Obtain a pointer to the current task within the global task list
pvdx_task_t *const current_task = get_current_task();
// Cache the watchdog checkin command to avoid creating it every iteration
command_t cmd_checkin = get_watchdog_checkin_command(current_task);
// Calculate the maximum time the command dispatcher should block (and thus be unable to check in with the watchdog)
const TickType_t queue_block_time_ticks = get_command_queue_block_time_ticks(current_task);
// Variable to hold commands popped off the queue
command_t cmd;

while (true) {
debug_impl("\n---------- ADCS Task Loop ----------\n");

// Execute all commands contained in the queue
if (xQueueReceive(p_adcs_task->command_queue, &cmd, queue_block_time_ticks) == pdPASS) {
do {
debug("adcs: Command popped off queue. Target: %s, Operation: %d\n", cmd.target->name, cmd.operation);
exec_command_adcs(&cmd);
} while (xQueueReceive(p_adcs_task->command_queue, &cmd, 0) == pdPASS);
}
debug("adcs: No more commands queued.\n");

if (should_checkin(current_task)) {
enqueue_command(&cmd_checkin);
debug("adcs: Enqueued watchdog checkin command\n");
}
}
}
60 changes: 60 additions & 0 deletions src/tasks/adcs/adcs_task.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* adcs_task.c
*
* RTOS task for Attitude Determination and Control System (ADCS)
*
* Created: Nov 23, 2025
* Authors: Yi Lyo
*/

#include "adcs_task.h"

extern adcs_task_memory_t adcs_mem;

/* ---------- DISPATCHABLE FUNCTIONS (sent as commands through the command dispatcher task) ---------- */

// TODO: Add ADCS-specific dispatchable functions here

/* ---------- NON-DISPATCHABLE FUNCTIONS (do not go through the command dispatcher) ---------- */

/**
* \fn exec_command_adcs
*
* \brief Executes a command received by the ADCS task
*
* \param p_cmd Pointer to the received command
*/
void exec_command_adcs(command_t *const p_cmd) {
if (p_cmd->target != p_adcs_task) {
fatal("adcs: command target is not ADCS! target: %s operation: %d\n", p_cmd->target->name, p_cmd->operation);
}

switch (p_cmd->operation) {
// TODO: Add ADCS-specific operations here
default:
fatal("adcs: Invalid operation! target: %s operation: %d\n", p_cmd->target->name, p_cmd->operation);
break;
}
}

/**
* \fn init_adcs
*
* \brief Initializes the ADCS task, including hardware setup and command queue creation
*
* \return Handle to the ADCS task's command queue
*/
QueueHandle_t init_adcs(void) {
// TODO: Add hardware initialization here
// fatal_on_error(init_adcs_hardware(), "adcs: Hardware initialization failed!");

// Initialize the ADCS command queue
QueueHandle_t adcs_command_queue_handle =
xQueueCreateStatic(COMMAND_QUEUE_MAX_COMMANDS, COMMAND_QUEUE_ITEM_SIZE, adcs_mem.adcs_command_queue_buffer,
&adcs_mem.adcs_task_queue);
if (adcs_command_queue_handle == NULL) {
fatal("Failed to create ADCS queue!\n");
}

return adcs_command_queue_handle;
}
33 changes: 33 additions & 0 deletions src/tasks/adcs/adcs_task.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef ADCS_TASK_H
#define ADCS_TASK_H

#include <atmel_start.h>
#include <driver_init.h>
#include "globals.h"
#include "logging.h"
#include "rtos_start.h"
#include "stdbool.h"
#include "string.h"
#include "watchdog_task.h"

// FreeRTOS Task structs
// Memory for the ADCS task
#define ADCS_TASK_STACK_SIZE 1024 // Size of the stack in words (multiply by 4 to get bytes)

// Placed in a struct to ensure that the TCB is placed higher than the stack in memory
// ^ This ensures that stack overflows do not corrupt the TCB (since the stack grows downwards)
typedef struct {
StackType_t overflow_buffer[TASK_STACK_OVERFLOW_PADDING];
StackType_t adcs_task_stack[ADCS_TASK_STACK_SIZE];
uint8_t adcs_command_queue_buffer[COMMAND_QUEUE_MAX_COMMANDS * COMMAND_QUEUE_ITEM_SIZE];
StaticQueue_t adcs_task_queue;
StaticTask_t adcs_task_tcb;
} adcs_task_memory_t;

extern adcs_task_memory_t adcs_mem;

QueueHandle_t init_adcs(void);
void exec_command_adcs(command_t *const p_cmd);
void main_adcs(void *pvParameters);

#endif // ADCS_TASK_H
20 changes: 20 additions & 0 deletions src/tasks/task_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ pvdx_task_t task_manager_task = {
.task_type = OS
};

pvdx_task_t adcs_task = {
.name = "ADCS",
.enabled = false,
.handle = NULL,
.command_queue = NULL,
.init = init_adcs,
.function = main_adcs,
.stack_size = ADCS_TASK_STACK_SIZE,
.stack_buffer = adcs_mem.adcs_task_stack,
.pvParameters = NULL,
.priority = 2,
.task_tcb = &adcs_mem.adcs_task_tcb,
.watchdog_timeout_ms = 10000,
.last_checkin_time_ticks = 0xDEADBEEF,
.has_registered = false,
.task_type = ACTUATOR
};

pvdx_task_t magnetometer_task = {
.name = "Magnetometer",
.enabled = false,
Expand Down Expand Up @@ -159,6 +177,7 @@ pvdx_task_t heartbeat_task = {
pvdx_task_t *const p_watchdog_task = &watchdog_task;
pvdx_task_t *const p_command_dispatcher_task = &command_dispatcher_task;
pvdx_task_t *const p_task_manager_task = &task_manager_task;
pvdx_task_t *const p_adcs_task = &adcs_task;
pvdx_task_t *const p_magnetometer_task = &magnetometer_task;
pvdx_task_t *const p_photodiode_task = &photodiode_task;
pvdx_task_t *const p_shell_task = &shell_task;
Expand All @@ -176,6 +195,7 @@ pvdx_task_t *task_list[] = {
p_watchdog_task,
p_command_dispatcher_task,
p_task_manager_task,
p_adcs_task,
p_magnetometer_task,
p_photodiode_task,
p_shell_task,
Expand Down
2 changes: 2 additions & 0 deletions src/tasks/task_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define TASK_LIST_H

// Includes
#include "adcs_task.h"
#include "command_dispatcher_task.h"
#include "display_task.h"
#include "globals.h"
Expand All @@ -16,6 +17,7 @@
extern pvdx_task_t *const p_watchdog_task;
extern pvdx_task_t *const p_command_dispatcher_task;
extern pvdx_task_t *const p_task_manager_task;
extern pvdx_task_t *const p_adcs_task;
extern pvdx_task_t *const p_magnetometer_task;
extern pvdx_task_t *const p_photodiode_task;
extern pvdx_task_t *const p_shell_task;
Expand Down