RTOS Facilities C API module

Files

file rtos.h

Functions

uint32_t millis(void)
Gets the number of milliseconds since PROS initialized.
uint64_t micros(void)
Gets the number of microseconds since PROS initialized,.
task_t task_create(task_fn_t function, void*const parameters, uint32_t prio, const uint16_t stack_depth, const char*const name)
Creates a new task and add it to the list of tasks that are ready to run.
void task_delete(task_t task)
Removes a task from the RTOS real time kernel's management.
void task_delay(const uint32_t milliseconds)
Delays the current task for a given number of milliseconds.
void delay(const uint32_t milliseconds)
Delays the current task for a given number of milliseconds.
void task_delay_until(uint32_t*const prev_time, const uint32_t delta)
Delays the current task until a specified time.
uint32_t task_get_priority(task_t task)
Gets the priority of the specified task.
void task_set_priority(task_t task, uint32_t prio)
Sets the priority of the specified task.
task_state_e_t task_get_state(task_t task)
Gets the state of the specified task.
void task_suspend(task_t task)
Suspends the specified task, making it ineligible to be scheduled.
void task_resume(task_t task)
Resumes the specified task, making it eligible to be scheduled.
uint32_t task_get_count(void)
Gets the number of tasks the kernel is currently managing, including all ready, blocked, or suspended tasks.
char* task_get_name(task_t task)
Gets the name of the specified task.
task_t task_get_by_name(const char* name)
Gets a task handle from the specified name.
task_t task_get_current()
Get the currently running task handle.
uint32_t task_notify(task_t task)
Sends a simple notification to task and increments the notification counter.
void task_join(task_t task)
Utilizes task notifications to wait until specified task is complete and deleted, then continues to execute the program.
uint32_t task_notify_ext(task_t task, uint32_t value, notify_action_e_t action, uint32_t* prev_value)
Sends a notification to a task, optionally performing some action.
uint32_t task_notify_take(bool clear_on_exit, uint32_t timeout)
Waits for a notification to be nonzero.
bool task_notify_clear(task_t task)
Clears the notification for a task.
mutex_t mutex_create(void)
Creates a mutex.
bool mutex_take(mutex_t mutex, uint32_t timeout)
Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out.
bool mutex_give(mutex_t mutex)
Unlocks a mutex.
void mutex_delete(mutex_t mutex)
Deletes a mutex.

Macros

#define TASK_PRIORITY_MAX
The highest priority that can be assigned to a task.
#define TASK_PRIORITY_MIN
The lowest priority that can be assigned to a task.
#define TASK_PRIORITY_DEFAULT
The default task priority, which should be used for most tasks unless you have a specific need for a higher or lower priority task.
#define TASK_STACK_DEPTH_DEFAULT
The recommended stack size for a new task.
#define TASK_STACK_DEPTH_MIN
The minimal stack size for a task.
#define TASK_NAME_MAX_LEN
The maximum number of characters allowed in a task's name.
#define TIMEOUT_MAX
The maximum timeout value that can be given to, for instance, a mutex grab.

Typedefs

using task_t = void*
An opaque type that pontis to a task handle.
using task_fn_t = void(*)(void*)
A pointer to a task's function.
using mutex_t = void*
A mutex..

Enumerations

enum task_state_e_t { E_TASK_STATE_RUNNING = 0, E_TASK_STATE_READY, E_TASK_STATE_BLOCKED, E_TASK_STATE_SUSPENDED, E_TASK_STATE_DELETED, E_TASK_STATE_INVALID }
The state of a task.
enum notify_action_e_t { E_NOTIFY_ACTION_NONE, E_NOTIFY_ACTION_BITS, E_NOTIFY_ACTION_INCR, E_NOTIFY_ACTION_OWRITE, E_NOTIFY_ACTION_NO_OWRITE }
brief The action to take when a task is notified.

Defines

#define CURRENT_TASK
The task handle of the currently running task.

Function documentation

uint32_t millis(void)
#include <pros/rtos.h>

Gets the number of milliseconds since PROS initialized.

Returns The number of milliseconds since PROS initialized

Example

void opcontrol() {
  uint32_t now = millis();
  while (true) {
    // Do opcontrol things
    task_delay_until(&now, 2);
  }
}

uint64_t micros(void)
#include <pros/rtos.h>

Gets the number of microseconds since PROS initialized,.

Returns The number of microseconds since PROS initialized

Example

void opcontrol() {
  uint64_t now = micros();
  while (true) {
    // Do opcontrol things
    task_delay_until(&now, 2000);
  }
}

task_t task_create(task_fn_t function, void*const parameters, uint32_t prio, const uint16_t stack_depth, const char*const name)
#include <pros/rtos.h>

Creates a new task and add it to the list of tasks that are ready to run.

Parameters
function Pointer to the task entry function
parameters Pointer to memory that will be used as a parameter for the task being created. This memory should not typically come from stack, but rather from dynamically (i.e., malloc'd) or statically allocated memory.
prio The priority at which the task should run. TASK_PRIO_DEFAULT plus/minus 1 or 2 is typically used.
stack_depth The number of words (i.e. 4 * stack_depth) available on the task's stack. TASK_STACK_DEPTH_DEFAULT is typically sufficienct.
name A descriptive name for the task. This is mainly used to facilitate debugging. The name may be up to 32 characters long.
Returns A handle by which the newly created task can be referenced. If an error occurred, NULL will be returned and errno can be checked for hints as to why task_create failed.

This function uses the following values of errno when an error state is reached: ENOMEM - The stack cannot be used as the TCB was not created.

Example

void my_task_fn(void* param) {
  printf("Hello %s\n", (char*)param);
  // ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                              TASK_STACK_DEPTH_DEFAULT, "My Task");
}

void task_delete(task_t task)
#include <pros/rtos.h>

Removes a task from the RTOS real time kernel's management.

Parameters
task The handle of the task to be deleted. Passing NULL will cause the calling task to be deleted.

The task being deleted will be removed from all ready, blocked, suspended and event lists.

Memory dynamically allocated by the task is not automatically freed, and should be freed before the task is deleted.

Example

void my_task_fn(void* param) {
  printf("Hello %s\n", (char*)param);
  // ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
  // Do other things
  task_delete(my_task);
}

void task_delay(const uint32_t milliseconds)
#include <pros/rtos.h>

Delays the current task for a given number of milliseconds.

Parameters
milliseconds The number of milliseconds to wait (1000 milliseconds per second)

This is not the best method to have a task execute code at predefined intervals, as the delay time is measured from when the delay is requested. To delay cyclically, use task_delay_until().

Example

void opcontrol() {
  while (true) {
    // Do opcontrol things
    task_delay(2);
  }
}

void delay(const uint32_t milliseconds)
#include <pros/rtos.h>

Delays the current task for a given number of milliseconds.

Parameters
milliseconds The number of milliseconds to wait (1000 milliseconds per second)

This is not the best method to have a task execute code at predefined intervals, as the delay time is measured from when the delay is requested. To delay cyclically, use task_delay_until().

Example

void opcontrol() {
while (true) {
  // Do opcontrol things
  delay(2);
  }
}

void task_delay_until(uint32_t*const prev_time, const uint32_t delta)
#include <pros/rtos.h>

Delays the current task until a specified time.

Parameters
prev_time A pointer to the location storing the setpoint time. This should typically be initialized to the return value of millis().
delta The number of milliseconds to wait (1000 milliseconds per second)

This function can be used by periodic tasks to ensure a constant execution frequency.

The task will be woken up at the time *prev_time + delta, and *prev_time will be updated to reflect the time at which the task will unblock.

Example

void opcontrol() {
  uint32_t now = millis();
  while (true) {
    // Do opcontrol things
    task_delay_until(&now, 2);
  }
}

uint32_t task_get_priority(task_t task)
#include <pros/rtos.h>

Gets the priority of the specified task.

Parameters
task The task to check
Returns The priority of the task

Example

void my_task_fn(void* param) {
  printf("Hello %s\n", (char*)param);
  // ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
  printf("Task Priority: %d\n", task_get_priority(my_task));
}

void task_set_priority(task_t task, uint32_t prio)
#include <pros/rtos.h>

Sets the priority of the specified task.

Parameters
task The task to set
prio The new priority of the task

If the specified task's state is available to be scheduled (e.g. not blocked) and new priority is higher than the currently running task, a context switch may occur.

Example

void my_task_fn(void* ign) {
  // Do things
}

void opcontrol() {
  task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,
                            TASK_STACK_DEPTH_DEFAULT, "Example Task");
  task_set_priority(my_task, TASK_PRIORITY_DEFAULT + 1);
}

task_state_e_t task_get_state(task_t task)
#include <pros/rtos.h>

Gets the state of the specified task.

Parameters
task The task to check
Returns The state of the task

Example

void my_task_fn(void* param) {
  printf("Hello %s\n", (char*)param);
  // ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
  printf("Task's State: %d\n", task_get_state(my_task));
}

void task_suspend(task_t task)
#include <pros/rtos.h>

Suspends the specified task, making it ineligible to be scheduled.

Parameters
task The task to suspend

Example

mutex_t counter_mutex;
int counter = 0;

void my_task_fn(void* param) {
  while(true) {
    mutex_take(counter_mutex, TIMEOUT_MAX);// Mutexes are used for protecting shared resources
    counter++;
    mutex_give(counter_mutex);
    pros::delay(10);
  }
}

void opcontrol() {
  task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,;

  while(true) {
       mutex_take(counter_mutex, TIMEOUT_MAX);
    if(counter > 100) {
      task_suspepend(task);
       }
    mutex_give(counter_mutex);
    pros::delay(10);
  }
}

void task_resume(task_t task)
#include <pros/rtos.h>

Resumes the specified task, making it eligible to be scheduled.

Parameters
task The task to resume

Example

void my_task_fn(void* param) {
  while(true) {
    // Do stuff
    delay(10);
  }
}

task_t task;

void initialize() {
  task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,
                    TASK_STACK_DEPTH_DEFAULT, "My Task");
}

void autonomous() {
  task_resume(task);

  // Run autonomous , then suspend the task so it doesn't interfere run
  
  // outside of autonomous or opcontrol
  task_suspend(task);
}

void opcontrol() {
  task_resume(task);
  // Opctonrol code here
  task_suspend(task);
}

uint32_t task_get_count(void)
#include <pros/rtos.h>

Gets the number of tasks the kernel is currently managing, including all ready, blocked, or suspended tasks.

Returns The number of tasks that are currently being managed by the kernel.

A task that has been deleted, but not yet reaped by the idle task will also be included in the count. Tasks recently created may take one context switch to be counted.

Example

void my_task_fn(void* param) {
  printf("Hello %s\n", (char*)param);
  // ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
  printf("Number of Running Tasks: %d\n", task_get_count());
}

char* task_get_name(task_t task)
#include <pros/rtos.h>

Gets the name of the specified task.

Parameters
task The task to check
Returns A pointer to the name of the task

Example

void my_task_fn(void* param) {
  printf("Hello %s\n", (char*)param);
  // ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
  printf("Task Name: %d\n", task_get_name(my_task));
}

task_t task_get_by_name(const char* name)
#include <pros/rtos.h>

Gets a task handle from the specified name.

Parameters
name The name to query
Returns A task handle with a matching name, or NULL if none were found.

The operation takes a relatively long time and should be used sparingly.

Example

void my_task_fn(void* param) {
  printf("Hello %s\n", (char*)param);
  // ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
  // Do other things
  task_delete(task_get_by_name("My Task"));
}

task_t task_get_current()
#include <pros/rtos.h>

Get the currently running task handle.

Returns The currently running task handle.

This could be useful if a task wants to tell another task about itself.

Example

void my_task_fn(void* param) {
  task_t this_task = task_get_current();
  if (task_get_state(this_take) == E_TASK_STATE_RUNNING) {
    printf("This task is currently running\n");
  }
// ...
}

void initialize() {
  task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
}

uint32_t task_notify(task_t task)
#include <pros/rtos.h>

Sends a simple notification to task and increments the notification counter.

Parameters
task The task to notify
Returns Always returns true.

Example

void my_task_fn(void* ign) {
  while(task_notify_take(true) == 0) {
    // Code while waiting
  }
  puts("I was unblocked!");
}

void opcontrol() {
  task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,
                            TASK_STACK_DEPTH_DEFAULT, "Notify me! Task");
  while(true) {
    if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) {
      task_notify(my_task);
    }
  }
}

void task_join(task_t task)
#include <pros/rtos.h>

Utilizes task notifications to wait until specified task is complete and deleted, then continues to execute the program.

Parameters
task The handle of the task to wait on.
Returns void

Analogous to std::thread::join in C++.

Example

void my_task_fn(void* ign) {
  lcd_print(1, "%s running", task_get_name(NULL));
  task_delay(1000);
  lcd_print(2, "End of %s", task_get_name(NULL));
}

void opcontrol() {
  task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,
                            TASK_STACK_DEPTH_DEFAULT, "Example Task");
  lcd_set_text(0, "Running task.");
  task_join(my_task);
  lcd_set_text(3, "Task completed.");
}

uint32_t task_notify_ext(task_t task, uint32_t value, notify_action_e_t action, uint32_t* prev_value)
#include <pros/rtos.h>

Sends a notification to a task, optionally performing some action.

Parameters
task The task to notify
value The value used in performing the action
action An action to optionally perform on the receiving task's notification value
prev_value A pointer to store the previous value of the target task's notification, may be NULL
Returns Dependent on the notification action. For NOTIFY_ACTION_NO_WRITE: return 0 if the value could be written without needing to overwrite, 1 otherwise. For all other NOTIFY_ACTION values: always return 0

Will also retrieve the value of the notification in the target task before modifying the notification value.

Example

void my_task_fn(void* param) {
  while(true) {
    // Wait until we have been notified 20 times before running the code
    if(task_notify_take(false, TIMEOUT_MAX) == 20) {
      // ... Code to do stuff here ...

      // Reset the notification counter
      task_notify_take(true, TIMEOUT_MAX);
    }
    delay(10);
     }
}

void opcontrol() {
     task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");
  
  int count = 0;
  
  while(true) {
    if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) {
      task_notify_ext(task, 1, NOTIFY_ACTION_INCREMENT, &count);
    }
    
    delay(20);
  }
}

uint32_t task_notify_take(bool clear_on_exit, uint32_t timeout)
#include <pros/rtos.h>

Waits for a notification to be nonzero.

Parameters
clear_on_exit If true (1), then the notification value is cleared. If false (0), then the notification value is decremented.
timeout Specifies the amount of time to be spent waiting for a notification to occur.
Returns The value of the task's notification value before it is decremented or cleared

See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for details.

Example

void my_task_fn(void* ign) {
  task_t current_task = task_get_current();
  while(task_notify_take(current_task, true, TIMEOUT_MAX)) {
    puts("I was unblocked!");
  }
}

void opcontrol() {
  task_t my_task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,
                            TASK_STACK_DEPTH_DEFAULT, "Notify me! Task");
  while(true) {
    if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) {
      task_notify(my_task);
    }
  }
}

bool task_notify_clear(task_t task)
#include <pros/rtos.h>

Clears the notification for a task.

Parameters
task The task to clear
Returns False if there was not a notification waiting, true if there was

See https://pros.cs.purdue.edu/v5/tutorials/topical/notifications.html for details.

Example

void my_task_fn(void* param) {
  task_t task = task_get_current();
  while(true) {
    printf("Waiting for notification...\n");
       printf("Got a notification: %d\n", task_notify_take(task, false, TIMEOUT_MAX));

       task_notify_clear(task);
    delay(10):
  }
}

void opcontrol() {
 task_t task = task_create(my_task_fn, NULL, TASK_PRIORITY_DEFAULT,
                           TASK_STACK_DEPTH_DEFAULT, "My Task");

  while(true) {
    if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) {
      task_notify(task);
    }
    delay(10);
  }
}

mutex_t mutex_create(void)
#include <pros/rtos.h>

Creates a mutex.

Returns A handle to a newly created mutex. If an error occurred, NULL will be returned and errno can be checked for hints as to why mutex_create failed.

See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes for details.

Example

// Global variables for the robot's odometry, which the rest of the robot's
// subsystems will utilize
double odom_x = 0.0;
double odom_y = 0.0;
double odom_heading = 0.0;

// This mutex protects the odometry data. Whenever we read or write to the
// odometry data, we should make copies into the local variables, and read
// all 3 values at once to avoid errors.
mutex_t odom_mutex;

void odom_task(void* param) {
  while(true) {
    // First we fetch the odom coordinates from the previous iteration of the
    // odometry task. These are put into local variables so that we can
    // keep the size of the critical section as small as possible. This lets
    // other tasks that need to use the odometry data run until we need to
    // update it again.
    mutex_take(odom_mutex, MAX_DELAY);
    double x_old = odom_x;
    double y_old = odom_y;
    double heading_old = odom_heading;
       mutex_give(odom_mutex);

    double x_new = 0.0;
    double y_new = 0.0;
    double heading_new = 0.0;
    
    // --- Calculate new pose for the robot here ---

    // Now that we have the new pose, we can update the global variables
    mutex_take(odom_mutex, MAX_DELAY);
    odom_x = x_new;
    odom_y = y_new;
    odom_heading = heading_new;
    mutex_give(odom_mutex);
    
    delay(10);
  }
}

void chassis_task(void* param) {
  while(true) {
    // Here we copy the current odom values into local variables so that
    // we can use them without worrying about the odometry task changing say,
    // the y value right after we've read the x. This ensures our values are
    // sound.
    mutex_take(odom_mutex, MAX_DELAY);
    double current_x = odom_x;
    double current_y = odom_y;
    double current_heading = odom_heading;
    mutex_give(odom_mutex);
    
    // ---- Move the robot using the current locations goes here ----
    
    delay(10);
  }
}

void initialize() {
  odom_mutex = mutex_create();

  task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task");
  task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task");
}

bool mutex_take(mutex_t mutex, uint32_t timeout)
#include <pros/rtos.h>

Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out.

Parameters
mutex Mutex to attempt to lock.
timeout Time to wait before the mutex becomes available. A timeout of 0 can be used to poll the mutex. TIMEOUT_MAX can be used to block indefinitely.
Returns True if the mutex was successfully taken, false otherwise. If false is returned, then errno is set with a hint about why the the mutex couldn't be taken.

See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes for details.

Example

// Global variables for the robot's odometry, which the rest of the robot's
// subsystems will utilize
double odom_x = 0.0;
double odom_y = 0.0;
double odom_heading = 0.0;

// This mutex protects the odometry data. Whenever we read or write to the
// odometry data, we should make copies into the local variables, and read
// all 3 values at once to avoid errors.
mutex_t odom_mutex;

void odom_task(void* param) {
  while(true) {
    // First we fetch the odom coordinates from the previous iteration of the
    // odometry task. These are put into local variables so that we can
    // keep the size of the critical section as small as possible. This lets
    // other tasks that need to use the odometry data run until we need to
    // update it again.
    mutex_take(odom_mutex, MAX_DELAY);
    double x_old = odom_x;
    double y_old = odom_y;
    double heading_old = odom_heading;
       mutex_give(odom_mutex);

    double x_new = 0.0;
    double y_new = 0.0;
    double heading_new = 0.0;
    
    // --- Calculate new pose for the robot here ---

    // Now that we have the new pose, we can update the global variables
    mutex_take(odom_mutex, MAX_DELAY);
    odom_x = x_new;
    odom_y = y_new;
    odom_heading = heading_new;
    mutex_give(odom_mutex);
    
    delay(10);
  }
}

void chassis_task(void* param) {
  while(true) {
    // Here we copy the current odom values into local variables so that
    // we can use them without worrying about the odometry task changing say,
    // the y value right after we've read the x. This ensures our values are
    // sound.
    mutex_take(odom_mutex, MAX_DELAY);
    double current_x = odom_x;
    double current_y = odom_y;
    double current_heading = odom_heading;
    mutex_give(odom_mutex);
    
    // ---- Move the robot using the current locations goes here ----
    
    delay(10);
  }
}

void initialize() {
  odom_mutex = mutex_create();

  task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task");
  task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task");
}

bool mutex_give(mutex_t mutex)
#include <pros/rtos.h>

Unlocks a mutex.

Parameters
mutex Mutex to unlock.
Returns True if the mutex was successfully returned, false otherwise. If false is returned, then errno is set with a hint about why the mutex couldn't be returned.

See https://pros.cs.purdue.edu/v5/tutorials/topical/multitasking.html#mutexes for details.

Example

// Global variables for the robot's odometry, which the rest of the robot's
// subsystems will utilize
double odom_x = 0.0;
double odom_y = 0.0;
double odom_heading = 0.0;

// This mutex protects the odometry data. Whenever we read or write to the
// odometry data, we should make copies into the local variables, and read
// all 3 values at once to avoid errors.
mutex_t odom_mutex;

void odom_task(void* param) {
  while(true) {
    // First we fetch the odom coordinates from the previous iteration of the
    // odometry task. These are put into local variables so that we can
    // keep the size of the critical section as small as possible. This lets
    // other tasks that need to use the odometry data run until we need to
    // update it again.
    mutex_take(odom_mutex, MAX_DELAY);
    double x_old = odom_x;
    double y_old = odom_y;
    double heading_old = odom_heading;
       mutex_give(odom_mutex);

    double x_new = 0.0;
    double y_new = 0.0;
    double heading_new = 0.0;
    
    // --- Calculate new pose for the robot here ---

    // Now that we have the new pose, we can update the global variables
    mutex_take(odom_mutex, MAX_DELAY);
    odom_x = x_new;
    odom_y = y_new;
    odom_heading = heading_new;
    mutex_give(odom_mutex);
    
    delay(10);
  }
}

void chassis_task(void* param) {
  while(true) {
    // Here we copy the current odom values into local variables so that
    // we can use them without worrying about the odometry task changing say,
    // the y value right after we've read the x. This ensures our values are
    // sound.
    mutex_take(odom_mutex, MAX_DELAY);
    double current_x = odom_x;
    double current_y = odom_y;
    double current_heading = odom_heading;
    mutex_give(odom_mutex);
    
    // ---- Move the robot using the current locations goes here ----
    
    delay(10);
  }
}

void initialize() {
  odom_mutex = mutex_create();

  task_create(odom_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Odometry Task");
  task_create(chassis_task, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Chassis Task");
}

void mutex_delete(mutex_t mutex)
#include <pros/rtos.h>

Deletes a mutex.

Parameters
mutex Mutex to unlock.

Example

mutex_t mutex = mutex_create();
// Acquire the mutex; other tasks using this command will wait until the mutex is released
// timeout can specify the maximum time to wait, or MAX_DELAY to wait forever
// If the timeout expires, "false" will be returned, otherwise "true"
mutex_take(mutex, MAX_DELAY);
// do some work
// Release the mutex for other tasks
mutex_give(mutex);
// Delete the mutex
mutex_delete(mutex);

Enum documentation

enum task_state_e_t
#include <pros/rtos.h>

The state of a task.

Enumerators
E_TASK_STATE_RUNNING

The task is actively executing.

E_TASK_STATE_READY

The task exists and is available to run, but is not currently running.

E_TASK_STATE_BLOCKED

The task is delayed or blocked by a mutex, semaphore, or I/O operation.

E_TASK_STATE_SUSPENDED

The task is supended using task_suspend.

E_TASK_STATE_DELETED

The task has been deleted using task_delete.

E_TASK_STATE_INVALID

The task handle does not point to a current or past task.

enum notify_action_e_t
#include <pros/rtos.h>

brief The action to take when a task is notified.

Enumerators
E_NOTIFY_ACTION_NONE

The task’s notification value will not be touched.

E_NOTIFY_ACTION_BITS

The task’s notification value will be bitwise ORed with the new value.

E_NOTIFY_ACTION_INCR

The task’s notification value will be incremented by one, effectively using it as a notification counter.

E_NOTIFY_ACTION_OWRITE

The task’s notification value will be unconditionally set to the new value.

E_NOTIFY_ACTION_NO_OWRITE

The task’s notification value will be set to the new value if the task does not already have a pending notification.

Typedef documentation

typedef void* task_t
#include <pros/rtos.h>

An opaque type that pontis to a task handle.

This is used for referencing a task.

typedef void(*task_fn_t)(void*)
#include <pros/rtos.h>

A pointer to a task's function.

Such a function is called when a task starts, and exiting said function will terminate the task.

typedef void* mutex_t
#include <pros/rtos.h>

A mutex..

A mutex is a synchronization object that can be used to protect a shared resource from being accessed by multiple tasks at the same time. A mutex can be claimed by a task, which will prevent other tasks from claiming it until that task releases it.

Define documentation

#define CURRENT_TASK
#include <pros/rtos.h>

The task handle of the currently running task.

#define TASK_PRIORITY_MAX
#include <pros/rtos.h>

The highest priority that can be assigned to a task.

A task with this priority will always run if it is available to. Beware of deadlocks when using this priority.

#define TASK_PRIORITY_MIN
#include <pros/rtos.h>

The lowest priority that can be assigned to a task.

This can cause severe performance problems and is generally not recommended that users use this priority.

#define TASK_PRIORITY_DEFAULT
#include <pros/rtos.h>

The default task priority, which should be used for most tasks unless you have a specific need for a higher or lower priority task.

The default tasks, such as autonomous(), are run with this priority

#define TASK_STACK_DEPTH_DEFAULT
#include <pros/rtos.h>

The recommended stack size for a new task.

This stack size is used for the default tasks such as autonomous(). This size is 8,192 words, or 32,768 bytes. This should be enough for the majority of tasks

#define TASK_STACK_DEPTH_MIN
#include <pros/rtos.h>

The minimal stack size for a task.

This equates to 512 words, or 2,048 bytes.

#define TASK_NAME_MAX_LEN
#include <pros/rtos.h>

The maximum number of characters allowed in a task's name.

#define TIMEOUT_MAX
#include <pros/rtos.h>

The maximum timeout value that can be given to, for instance, a mutex grab.