RTOS Facilities C++ API module
Files
- file rtos.hpp
Classes
- class pros::rtos::Task
Functions
-
Task(task_
fn_ t function, void* parameters = nullptr, std::uint32_t prio = TASK_ PRIORITY_ DEFAULT, std::uint16_t stack_depth = TASK_ STACK_ DEPTH_ DEFAULT, const char* name = "") - Creates a new task and add it to the list of tasks that are ready to run.
-
Task(task_
fn_ t function, void* parameters, const char* name) - Creates a new task and add it to the list of tasks that are ready to run.
-
template<class F>static task_
t create(F&& function, std::uint32_t prio = TASK_ PRIORITY_ DEFAULT, std::uint16_t stack_depth = TASK_ STACK_ DEPTH_ DEFAULT, const char* name = "") - Creates a new task and add it to the list of tasks that are ready to run.
-
template<class F>static task_
t create(F&& function, const char* name) - Creates a new task and add it to the list of tasks that are ready to run.
-
template<class F>Task(F&& function, std::uint32_t prio = TASK_
PRIORITY_ DEFAULT, std::uint16_t stack_depth = TASK_ STACK_ DEPTH_ DEFAULT, const char* name = "") explicit - Creates a new task and add it to the list of tasks that are ready to run.
-
template<class F>Task(F&& function, const char* name)
- Creates a new task and add it to the list of tasks that are ready to run.
-
Task(task_
t task) explicit - Create a C++ task object from a task handle.
- static Task current()
- Get the currently running Task.
-
Task& operator=(task_
t in) - Creates a task object from the passed task handle.
- void remove()
- Removes the Task from the RTOS real time kernel's management.
- std::uint32_t get_priority()
- Gets the priority of the specified task.
- void set_priority(std::uint32_t prio)
- Sets the priority of the specified task.
- std::uint32_t get_state()
- Gets the state of the specified task.
- void suspend()
- Suspends the specified task, making it ineligible to be scheduled.
- void resume()
- Resumes the specified task, making it eligible to be scheduled.
- const char* get_name()
- Gets the name of the specified task.
- operator task_t() explicit
- Convert this object to a C task_t handle.
- std::uint32_t notify()
- Sends a simple notification to task and increments the notification counter.
- void join()
- Utilizes task notifications to wait until specified task is complete and deleted, then continues to execute the program.
- std::uint32_t notify_ext(std::uint32_t value, notify_action_e_t action, std::uint32_t* prev_value)
- Sends a notification to a task, optionally performing some action.
- static std::uint32_t notify_take(bool clear_on_exit, std::uint32_t timeout)
- Waits for a notification to be nonzero.
- bool notify_clear()
- Clears the notification for a task.
- static void delay(const std::uint32_t milliseconds)
- Delays the current task for a specified number of milliseconds.
- static void delay_until(std::uint32_t*const prev_time, const std::uint32_t delta)
- Delays the current Task until a specified time.
- static std::uint32_t get_count()
- Gets the number of tasks the kernel is currently managing, including all ready, blocked, or suspended tasks.
- static time_point now()
- Gets the current time.
- Mutex()
- Mutex(const Mutex&) deleted
- Mutex(Mutex&&) deleted
- Mutex& operator=(const Mutex&) deleted
- Mutex& operator=(Mutex&&) deleted
- bool take()
- Takes and locks a mutex indefinetly.
- bool take(std::uint32_t timeout)
- Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out.
- bool give()
- Unlocks a mutex.
- void lock()
- Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds.
- void unlock()
- Unlocks a mutex.
- bool try_lock()
- Try to lock a mutex.
-
template<typename Rep, typename Period>bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
- Takes and locks a mutex, waiting for a specified duration.
-
template<typename Duration>bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time)
- Takes and locks a mutex, waiting until a specified time.
Typedefs
- using rep = std::uint32_t
- using period = std::milli
- using duration = std::chrono::duration<rep, period>
- using time_point = std::chrono::time_point<Clock>
Variables
Function documentation
Task(task_ fn_ t function,
void* parameters = nullptr,
std::uint32_t prio = TASK_ PRIORITY_ DEFAULT,
std::uint16_t stack_depth = TASK_ STACK_ DEPTH_ DEFAULT,
const char* name = "")
#include <pros/rtos.hpp>
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. |
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() { pros::Task my_task(my_task_fn, (void*)"PROS"); }
Task(task_ fn_ t function,
void* parameters,
const char* name)
#include <pros/rtos.hpp>
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. |
name | A descriptive name for the task. This is mainly used to facilitate debugging. The name may be up to 32 characters long. |
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() { pros::Task my_task(my_task_fn, (void*)"PROS", "My Task"); }
#include <pros/rtos.hpp>
template<class F>
static task_ t create(F&& function,
std::uint32_t prio = TASK_ PRIORITY_ DEFAULT,
std::uint16_t stack_depth = TASK_ STACK_ DEPTH_ DEFAULT,
const char* name = "")
Creates a new task and add it to the list of tasks that are ready to run.
Parameters | |
---|---|
function | Callable object to use as entry function |
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. |
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() { pros::c::task_t my_task = pros::Task::create(my_task_fn, (void*)"PROS"); }
#include <pros/rtos.hpp>
template<class F>
static task_ t create(F&& function,
const char* name)
Creates a new task and add it to the list of tasks that are ready to run.
Parameters | |
---|---|
function | Callable object to use as entry function |
name | A descriptive name for the task. This is mainly used to facilitate debugging. The name may be up to 32 characters long. |
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() { pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); }
#include <pros/rtos.hpp>
template<class F>
Task(F&& function,
std::uint32_t prio = TASK_ PRIORITY_ DEFAULT,
std::uint16_t stack_depth = TASK_ STACK_ DEPTH_ DEFAULT,
const char* name = "") explicit
Creates a new task and add it to the list of tasks that are ready to run.
Parameters | |
---|---|
function | Callable object to use as entry function |
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 sufficient. |
name | A descriptive name for the task. This is mainly used to facilitate debugging. The name may be up to 32 characters long. |
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 initialize() { // Create a task function using lambdas auto task_fn = [](void* param) { printf("Hello %s\n", (char*)param); } pros::Task my_task(task_fn, (void*)"PROS", "My Task"); }
#include <pros/rtos.hpp>
template<class F>
Task(F&& function,
const char* name)
Creates a new task and add it to the list of tasks that are ready to run.
Parameters | |
---|---|
function | Callable object to use as entry function |
name | A descriptive name for the task. This is mainly used to facilitate debugging. The name may be up to 32 characters long. |
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() { pros::Task my_task( [](void* param) { printf("Inside the task!\n"); }, "My Task" ); }
Task(task_ t task) explicit
#include <pros/rtos.hpp>
Create a C++ task object from a task handle.
Parameters | |
---|---|
task | A task handle from task_ |
Example
void my_task_fn(void* param) { printf("Hello %s\n", (char*)param); // ... } void initialize() { pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); pros::Task my_task_cpp(my_task); }
static Task current()
#include <pros/rtos.hpp>
Get the currently running Task.
Returns | The currently running Task. |
---|
Example
void my_task_fn(void* param) { printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() } void initialize() { pros::Task my_task(my_task_fn, pros::TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); }
Task& operator=(task_ t in)
#include <pros/rtos.hpp>
Creates a task object from the passed task handle.
Parameters | |
---|---|
in | A task handle from task_ |
Example
void my_task_fn(void* param) { printf("The name of this task is \"%s\"\n", pros::Task::current().get_name() } void initialize() { pros::c::task_t my_task = pros::Task::create(my_task_fn, "My Task"); pros::Task my_task_cpp = my_task; }
void remove()
#include <pros/rtos.hpp>
Removes the Task from the RTOS real time kernel's management.
This task 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() { pros::Task my_task(my_task_fn, "My Task"); my_task.remove(); }
std::uint32_t get_priority()
#include <pros/rtos.hpp>
Gets the priority of the specified task.
Returns | The priority of the task |
---|
Example
void my_task_fn(void* param) { printf("Hello %s\n", (char*)param); // ... } void initialize() { pros::Task my_task(my_task_fn, "My Task"); printf("Task Priority: %d\n", my_task.get_priority()); }
void set_priority(std::uint32_t prio)
#include <pros/rtos.hpp>
Sets the priority of the specified task.
Parameters | |
---|---|
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* param) { printf("Hello %s\n", (char*)param); // ... } void initialize() { pros::Task my_task(my_task_fn, "My Task"); Task.set_priority(pros::DEFAULT_PRIORITY + 1); }
std::uint32_t get_state()
#include <pros/rtos.hpp>
Gets the state of the specified task.
Returns | The state of the task |
---|
Example
void my_task_fn(void* param) { printf("Hello %s\n", (char*)param); // ... } void initialize() { pros::Task my_task(my_task_fn, "My Task"); printf("Task State: %d\n", my_task.get_state()); }
void suspend()
#include <pros/rtos.hpp>
Suspends the specified task, making it ineligible to be scheduled.
Example
pros::Mutex counter_mutex; int counter = 0; void my_task_fn(void* param) { while(true) { counter_mutex.take(); // Mutexes are used for protecting shared resources counter++; counter_mutex.give(); pros::delay(10); } } void opcontrol() { pros::Task task(my_task_fn, "My Task"); while(true) { counter_mutex.take(); if(counter > 100) { task_suspepend(task); } counter_mutex.give(); pros::delay(10); } }
void resume()
#include <pros/rtos.hpp>
Resumes the specified task, making it eligible to be scheduled.
Example
void my_task_fn(void* param) { while(true) { // Do stuff pros::delay(10); } } pros::Task task(my_task_fn); void autonomous() { task.resume(); // Run autonomous , then suspend the task so it doesn't interfere run // outside of autonomous or opcontrol task.suspend(); } void opcontrol() { task.resume(); // Opctonrol code here task.suspend(); }
const char* get_name()
#include <pros/rtos.hpp>
Gets the name of the specified task.
Returns | A pointer to the name of the task |
---|
Example
void my_task_fn(void* param) { printf("Hello %s\n", (char*)param); // ... } void initialize() { pros::Task my_task(my_task_fn, "My Task"); printf("Number of Running Tasks: %d\n", my_task.get_name()); }
operator task_t() explicit
#include <pros/rtos.hpp>
Convert this object to a C task_t handle.
Example
void my_task_fn(void* param) { printf("Hello %s\n", (char*)param); // ... } void initialize() { pros::Task my_task(my_task_fn, "My Task"); pros::c::task_t my_task_c = (pros::c::task_t)my_task; }
std::uint32_t notify()
#include <pros/rtos.hpp>
Sends a simple notification to task and increments the notification counter.
Returns | Always returns true. |
---|
See https:/
Example
void my_task_fn(void* ign) { while(pros::Task::current_task().notify_take(true) == 0) { // Code while waiting } puts("I was unblocked!"); } void opcontrol() { pros::Task my_task(my_task_fn); while(true) { if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { my_task.notify(); } } }
void join()
#include <pros/rtos.hpp>
Utilizes task notifications to wait until specified task is complete and deleted, then continues to execute the program.
Returns | void |
---|
Analogous to std::thread::join in C++.
See https:/
Example
void my_task_fn(void* ign) { lcd_print(1, "%s running", pros::Task::current_task().get_name()); task_delay(1000); lcd_print(2, "End of %s", pros::Task::current_task().get_name()); } void opcontrol() { pros::Task my_task(my_task_fn); pros::lcd::set_text(0, "Running task."); my_task.join(); pros::lcd::lcd_set_text(3, "Task completed."); }
std::uint32_t notify_ext(std::uint32_t value,
notify_action_e_t action,
std::uint32_t* prev_value)
#include <pros/rtos.hpp>
Sends a notification to a task, optionally performing some action.
Parameters | |
---|---|
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.
See https:/
Example
void my_task_fn(void* param) { pros::Task task = pros::Task::current(); 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_clear(); } delay(10); } } void opcontrol() { pros::Task task(my_task_fn); int count = 0; while(true) { if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { task.notify_ext(1, NOTIFY_ACTION_INCREMENT, &count); } delay(20); } }
static std::uint32_t notify_take(bool clear_on_exit,
std::uint32_t timeout)
#include <pros/rtos.hpp>
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:/
Example
void my_task_fn(void* ign) { pros::Task task = pros::task::current(); while(task.notify_take(true, TIMEOUT_MAX)) { puts("I was unblocked!"); } } void opcontrol() { pros::Task task(my_task_fn); while(true) { if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { task.notify(my_task); } } }
bool notify_clear()
#include <pros/rtos.hpp>
Clears the notification for a task.
Returns | False if there was not a notification waiting, true if there was Example void my_task_fn(void* param) { pros::Task task = pros::Task::current(); while(true) { printf("Waiting for notification...\n"); printf("Got a notification: %d\n", task.notify_take(false, TIMEOUT_MAX)); tasK_notify(task); delay(10): } } void opcontrol() { pros::Task task(my_task_fn); while(true) { if(controller_get_digital(CONTROLLER_MASTER, DIGITAL_L1)) { task.notify(); } delay(10); } } |
---|
See https:/
static void delay(const std::uint32_t milliseconds)
#include <pros/rtos.hpp>
Delays the current task for a specified 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_
Example
void opcontrol() { while (true) { // Do opcontrol things pros::Task::delay(2); }
static void delay_until(std::uint32_t*const prev_time,
const std::uint32_t delta)
#include <pros/rtos.hpp>
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 from pros:: |
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() { while (true) { // Do opcontrol things pros::Task::delay(2); } }
static std::uint32_t get_count()
#include <pros/rtos.hpp>
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 opcontrol() { pros::Task my_task(my_task_fn); printf("There are %d tasks running\n", pros::Task::get_count()); }
static time_point now()
#include <pros/rtos.hpp>
Gets the current time.
Returns | The current time |
---|
Effectively a wrapper around pros::
Example
void opcontrol() { pros::Clock::time_point start = pros::Clock::now(); pros::Clock::time_point end = pros::Clock::now(); pros::Clock::duration duration = end - start; printf("Duration: %d\n", duration.count()); if(duration.count() == 500) { // If you see this comment in the DOCS, ping @pros in VTOW. // If you are the first person to do so, you will receive a free PROS // holo! printf("Duration is 500 milliseconds\n"); } }
Mutex()
#include <pros/rtos.hpp>
Mutex(const Mutex&) deleted
#include <pros/rtos.hpp>
Mutex(Mutex&&) deleted
#include <pros/rtos.hpp>
Mutex& operator=(const Mutex&) deleted
#include <pros/rtos.hpp>
Mutex& operator=(Mutex&&) deleted
#include <pros/rtos.hpp>
bool take()
#include <pros/rtos.hpp>
Takes and locks a mutex indefinetly.
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:/
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. pros::Mutex 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. odom_mutex.take(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.give(); 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 odom_mutex.take(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.give(); 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. odom_mutex.take(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.give(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::Mutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
bool take(std::uint32_t timeout)
#include <pros/rtos.hpp>
Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out.
Parameters | |
---|---|
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:/
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. pros::Mutex 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. odom_mutex.take(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.give(); 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 odom_mutex.take(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.give(); 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. odom_mutex.take(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.give(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::Mutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
bool give()
#include <pros/rtos.hpp>
Unlocks a mutex.
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:/
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. pros::Mutex 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. odom_mutex.take(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.give(); 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 odom_mutex.take(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.give(); 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. odom_mutex.take(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.give(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::Mutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
void lock()
#include <pros/rtos.hpp>
Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds.
Exceptions | |
---|---|
std::system_error | Mutex could not be locked within TIMEOUT_MAX milliseconds. see errno for details. |
Effectively equivalent to calling pros::Mutex::take with TIMEOUT_MAX as the parameter.
Conforms to named requirment BasicLockable
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. pros::Mutex 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. odom_mutex.lock(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.unlock(); 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 odom_mutex.lock(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.unlock(); 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. odom_mutex.lock(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.unlock(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::Mutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
void unlock()
#include <pros/rtos.hpp>
Unlocks a mutex.
Equivalent to calling pros::Mutex::give.
Conforms to named requirement BasicLockable
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. pros::Mutex 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. odom_mutex.lock(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.unlock(); 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 odom_mutex.lock(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.unlock(); 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. odom_mutex.lock(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.unlock(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::Mutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
bool try_lock()
#include <pros/rtos.hpp>
Try to lock a mutex.
Returns | True when lock was acquired succesfully, or false otherwise. |
---|
Returns immediately if unsucessful.
Conforms to named requirement Lockable
pros::
void my_task_fn(void* param) { while (true) { if(mutex.try_lock()) { printf("Mutex aquired successfully!\n"); // Do stuff that requires the protected resource here } else { printf("Mutex not aquired!\n"); } } }
#include <pros/rtos.hpp>
template<typename Rep, typename Period>
bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
Takes and locks a mutex, waiting for a specified duration.
Parameters | |
---|---|
rel_time | Time to wait before the mutex becomes available. |
Returns | True if the lock was acquired succesfully, otherwise false. |
Equivalent to calling pros::Mutex::take with a duration specified in milliseconds.
Conforms to named requirement TimedLockable
Example
void my_task_fn(void* param) { while (true) { if(mutex.try_lock_for(std::chrono::milliseconds(100))) { printf("Mutex aquired successfully!\n"); // Do stuff that requires the protected resource here } else { printf("Mutex not aquired after 100 milliseconds!\n"); } } }
#include <pros/rtos.hpp>
template<typename Duration>
bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time)
Takes and locks a mutex, waiting until a specified time.
Parameters | |
---|---|
abs_time | Time point until which to wait for the mutex. |
Returns | True if the lock was acquired succesfully, otherwise false. |
Conforms to named requirement TimedLockable
Example
void my_task_fn(void* param) { while (true) { // Get the current time point auto now = std::chrono::system_clock::now(); // Calculate the time point 100 milliseconds from now auto abs_time = now + std::chrono::milliseconds(100); if(mutex.try_lock_until(abs_time)) { printf("Mutex aquired successfully!\n"); // Do stuff that requires the protected resource here } else { printf("Mutex not aquired after 100 milliseconds!\n"); } } }
Typedef documentation
using rep = std::uint32_t
#include <pros/rtos.hpp>
using period = std::milli
#include <pros/rtos.hpp>
using duration = std::chrono::duration<rep, period>
#include <pros/rtos.hpp>
using time_point = std::chrono::time_point<Clock>
#include <pros/rtos.hpp>
Variable documentation
task_ t task
#include <pros/rtos.hpp>
const bool is_steady
#include <pros/rtos.hpp>
std::shared_ptr<std::remove_pointer_t<mutex_ t>> mutex
#include <pros/rtos.hpp>