RTOS Facilities C++ API¶
Note
Additional example code for this module can be found in its Tutorial.
pros¶
millis¶
Analogous to millis.
std::uint32_t pros::millis ( )
1 2 3 4 5 6 7 | void opcontrol() { std::uint32_t now = pros::millis(); while (true) { // Do opcontrol things pros::Task::delay_until(&now, 2); } } |
Returns: Returns the number of milliseconds since PROS initialized.
pros::Task¶
Constructor(s)¶
Analogous to task_create.
1 2 3 4 5 | pros::Task::Task ( pros::task_fn_t function, void* parameters = NULL, std::uint32_t prio = TASK_PRIORITY_DEFAULT, std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "") |
1 2 3 4 5 6 7 8 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { pros::Task my_task (my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); } |
Create 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 sufficient. |
name | A descriptive name for the task. This is mainly used to facilitate debugging. The name may be up to 32 characters long. |
pros::Task::Task ( pros::task_t task )
1 2 3 4 5 6 7 8 9 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { pros::task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); pros::Task my_cpp_task (my_task); } |
Creates a Task object from a task already created with the C API.
Parameters | |
---|---|
task | The task for which to create an object |
pros::Task::Task ( task_fn_t function, void* parameters, const char* name )
1 2 3 4 5 6 7 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { pros::Task my_cpp_task (my_task_fn, (void*)"PROS", "My Task"); } |
Create 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. |
1 2 3 4 5 6 7 | template <class F> pros::Task::Task ( F&& function, std::uint32_t prio = TASK_PRIORITY_DEFAULT, std::uint16_t stack_depth = TASK_STACK_DEPTH_DEFAULT, const char* name = "" ) |
1 2 3 4 5 6 7 | void initialize() { std::unique_ptr<int> data{new int(7)}; pros::Task my_callable_task ([=] { pros::delay(1000); std::cout << *data << std::endl; }); } |
Create a new task from any C++ Callable object and add it to the list of tasks that are ready to run.
Parameters | |
---|---|
function | Callable object to use as entry function. Must also satisfy std::is_invocable_r_v<void, F> . |
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. |
template <class F>
pros::Task::Task ( F&& function, const char* name = "" )
1 2 3 4 5 6 7 | void initialize() { std::unique_ptr<int> data{new int(7)}; pros::Task my_callable_task ([=] { pros::delay(1000); std::cout << *data << std::endl; }, "callable_task"); } |
Create a new task from any C++ Callable object and add it to the list of tasks that are ready to run.
Parameters | |
---|---|
function | Callable object to use as entry function. Must also satisfy std::is_invocable_r_v<void, F> . |
name | A descriptive name for the task. This is mainly used to facilitate debugging. The name may be up to 32 characters long. |
Operator Overloads¶
void operator = ( const pros::task_t in )
1 2 3 4 5 6 7 8 9 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { pros::task_t my_task = task_create(my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); Task my_cpp_task = my_task; } |
Creates a Task object from a task already created with the C API.
Parameters | |
---|---|
task | The task for which to create an object |
Methods¶
delay¶
Delay a task for a given number of milliseconds.
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 delay_until.
static void pros::Task::delay ( const std::uint32_t milliseconds )
1 2 3 4 5 6 | void opcontrol() { while (true) { // Do opcontrol things pros::Task::delay(2); } } |
Parameters | |
---|---|
milliseconds | The number of milliseconds to wait (1000 milliseconds per second) |
delay_until¶
Delay a task until a specified time. 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. *prev_time
should
be initialized to the result from millis().
Analogous to task_delay_until.
void pros::Task::delay_until ( std::uint32_t* const prev_time,
const std::uint32_t delta )
1 2 3 4 5 6 7 | void opcontrol() { std::uint32_t now = pros::millis(); while (true) { // Do opcontrol things pros::Task::delay_until(&now, 2); } } |
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) |
get_count¶
Returns the number of tasks the kernel is currently managing, including all ready, blocked, or suspended tasks. 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.
Analogous to Task_get_count.
std::uint32_t pros::Task::get_count ( )
1 2 3 4 5 6 7 8 9 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { Task my_task (my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); std::cout << "Number of Running Tasks:" << pros::Task::get_count(); } |
Returns: The number of tasks that are currently being managed by the kernel
current¶
Get a handle to the task which called this function.
Analogous to task_get_current.
Task pros::Task::current ( )
1 2 3 4 5 6 7 8 9 10 11 | void my_task_fn(void* param) { Task this_task = pros::Task::current(); if (this_task.get_state() == pros::E_TASK_STATE_RUNNING) { std::cout << "This task is currently running" std::endl; } // ... } void initialize() { Task my_task (my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); } |
Returns: The currently running task.
get_name¶
Obtains the name of the specified task.
Analogous to task_get_name.
char const* pros::Task::get_name ( )
1 2 3 4 5 6 7 8 9 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { Task my_task (my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); std::cout << "Task Name:" << my_task.get_name(); } |
Returns: A pointer to the name of the task
get_priority¶
Obtains the priority of the specified task.
Analogous to task_get_priority.
std::uint32_t pros::Task::get_priority ( )
1 2 3 4 5 6 7 8 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { Task my_task (my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); std::cout << "Task Priority:" << my_task.get_priority(); |
Returns: The priority of the task.
get_state¶
Returns the state of the specified task.
Analogous to task_get_state.
task_state_e_t pros::Task::get_state ( )
1 2 3 4 5 6 7 8 9 | void my_task_fn(void* param) { std::cout << "Hello" << (char*)param; // ... } void initialize() { Task my_task (my_task_fn, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "My Task"); std::cout << "Task's State:" << my_task.get_state(); } |
Returns: The state of the task. (see task_state_e_t).
notify¶
Sends a simple notification to task and increments the notification value, using it as a notification counter.
See Task Notifications for details.
Analogous to task_notify.
Warning
verify this example code
std::uint32_t pros::Task::notify ( )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void my_task_fn(void* ign) { while(my_task.notify_take(true, TIMEOUT_MAX)) { std::cout << "I was unblocked!"; } } void opcontrol() { Task my_task (my_task_fn, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); pros::Controller master (E_CONTROLLER_MASTER); while(true) { if(master.get_digital(DIGITAL_L1)) { my_task.notify(my_task); } } } |
Returns: Always true.
notify_clear¶
Clears the notification for a task.
See Task Notifications for details.
Analogous to task_notify_clear.
bool pros::Task::notify_clear ( )
TO BE ADDED
Returns: False if there was not a notification waiting, true if there was
notify_ext¶
Sends a notification to a task, optionally performing some action. Will also retrieve the value of the notification in the target task before modifying the notification value.
See Task Notifications for details.
Analogous to task_notify_ext.
static std::uint32_t pros::Task::notify_ext ( std::uint32_t value,
notify_action_e_t action,
std::uint32_t* prev_value )
TO BE ADDED
Parameters | |
---|---|
value | The value used in performing the action |
action | An action to optionally perform on the task’s notification value |
prev_value | A pointer to store the previous value of the target task’s notification value, may be NULL |
Returns: Dependent on the notification action. For NOTIFY_ACTION_NO_OWRITE: return 0 if the value could be written without needing to overwrite, 1 otherwise. For all other NOTIFY_ACTION values: always return 0
notify_take¶
Wait for a notification to be nonzero.
See Task Notifications for details.
Analogous to task_notify_take.
std::uint32_t pros::Task::notify_take ( bool clear_on_exit,
std::uint32_t timeout )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void my_task_fn(void* ign) { while(my_task.notify_take(true, TIMEOUT_MAX)) { std::cout << "I was unblocked!"; } } void opcontrol() { Task my_task (my_task_fn, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Notify me! Task"); pros::Controller master (E_CONTROLLER_MASTER); while(true) { if(master.get_digital(DIGITAL_L1)) { my_task.notify(my_task); } } } |
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.
join¶
Utilizes task notifications to wait until specified task is complete and deleted, then continues to execute the program. Replicates the functionality of thread joining in C++.
See Task Notifications for details.
Analogous to task_join.
std::void pros::Task::join ( )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void my_task(void* ign) { std::cout << "Task running" << pros::Task::delay(1000); std::cout << "End of task" << } void opcontrol() { Task my_task (my_task_fn, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Task One"); std::cout << "Before task" << my_task.join(); std::cout << "After task" << } } } |
remove¶
Remove a task from the RTOS real time kernel’s management. 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.
Analogous to task_delete.
void pros::Task::remove ( )
1 2 3 4 5 6 7 8 9 10 11 | void my_task_fn(void* ign) { // Do things } void opcontrol() { Task my_task (my_task_fn, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Example Task"); // Do things my_task.remove(); // Delete the task std::cout << "Task State: " << my_task.get_state() << std::endl; // Prints the value of E_TASK_STATE_DELETED } |
resume¶
Resumes the specified task, making it eligible to be scheduled.
Analogous to task_resume.
void pros::Task::resume ( )
1 2 3 4 5 6 7 8 9 10 11 | void my_task_fn(void* ign) { // Do things } void opcontrol() { Task my_task (my_task_fn, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Example Task"); // Do things my_task.suspend(); // The task will no longer execute // Do other things my_task.resume(); // The task will resume execution } |
set_priority¶
Sets the priority of the specified 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.
Analogous to task_set_priority.
void pros::Task::set_priority ( std::uint32_t prio )
1 2 3 4 5 6 7 8 | void my_task_fn(void* ign) { // Do things } void opcontrol() { Task my_task (my_task_fn, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Example Task"); my_task.set_priority(TASK_PRIORITY_DEFAULT + 1); } |
Parameters | |
---|---|
prio | The new priority of the task |
suspend¶
Suspends the current task, making it ineligible to be scheduled.
Analogous to task_suspend.
void pros::Task::suspend ( )
1 2 3 4 5 6 7 8 9 10 11 | void my_task_fn(void* ign) { // Do things } void opcontrol() { Task my_task (my_task_fn, NULL, TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Example Task"); // Do things my_task.suspend(); // The task will no longer execute // Do other things my_task.resume(); // The task will resume execution } |
pros::Mutex¶
Constructor(s)¶
Creates a mutex.
See Multitasking for details.
Analogous to mutex_create.
pros::Mutex::Mutex ( )
1 2 3 4 5 6 7 8 9 | Mutex mutex; // 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(MAX_DELAY); // do some work // Release the mutex for other tasks mutex.give(); |
Methods¶
destructor¶
Unlocks a mutex.
See Multitasking for details.
Analogous to mutex_give.
void pros::Mutex::destructor ( )
1 2 3 4 5 6 7 8 9 10 | Mutex mutex; // 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(MAX_DELAY); // do some work // Release the mutex for other tasks mutex.give(); // Destructor called here |
give¶
Unlocks a mutex.
See Multitasking for details.
Analogous to mutex_give.
bool pros::Mutex::give ( )
1 2 3 4 5 6 7 8 9 | Mutex mutex; // 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(MAX_DELAY); // do some work // Release the mutex for other tasks mutex.give(); |
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.
take¶
Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out.
See Multitasking for details.
Analogous to mutex_take.
bool pros::Mutex::take ( std::uint32_t timeout )
1 2 3 4 5 6 7 8 9 | Mutex mutex; // 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(MAX_DELAY); // do some work // Release the mutex for other tasks mutex.give(); |
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.
take¶
Takes and locks a mutex, with an infinite timout.
See Multitasking for details.
Analogous to mutex_take.
bool pros::Mutex::take ( )
1 2 3 4 5 6 7 | Mutex mutex; // Acquire the mutex; does not time out if parameter not specified. mutex.take(); // do some work // Release the mutex for other tasks mutex.give(); |
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.
—-
Macros¶
CURRENT_TASK¶
Refers to the current task. To be used for checking attributes of the task in which this macro is called.
Value: ((task_t)NULL)
TASK_PRIORITY_DEFAULT¶
The default task priority, which should be used for most tasks.
Default tasks such as autonomous() inherit this priority.
Value: 8
TASK_PRIORITY_MAX¶
The highest priority that can be assigned to a task. Beware of deadlock.
Value: 16
TASK_PRIORITY_MIN¶
The lowest priority that can be assigned to a task.
This may cause severe performance problems and is generally not recommended.
Value: 1
TASK_STACK_DEPTH_DEFAULT¶
The recommended stack size for a new task. This stack size is used for default tasks such as autonomous(). This equates to 32,768 bytes, or 128 times the default stack size for a task in PROS 2.
Value: 0x2000
TASK_STACK_DEPTH_MIN¶
The minimal stack size for a task. This equates to 2048 bytes, or 8 times the default stack size for a task in PROS 2.
Value: 0x200
TIMEOUT_MAX¶
The maximum timeout value that can be given to, for instance, a mutex grab.
Value: ((uint32_t)0xffffffffUL)
Enumerated Values¶
pros::task_state_e_t¶
1 2 3 4 5 6 7 8 | typedef enum { 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 } task_state_e_t; |
Value | |
---|---|
pros::E_TASK_STATE_RUNNING | The task is actively executing. |
pros::E_TASK_STATE_READY | The task exists and is available to run, but is not currently running. |
pros::E_TASK_STATE_BLOCKED | The task is delayed or blocked by a mutex, semaphore, or I/O operation. |
pros::E_TASK_STATE_SUSPENDED | The task is suspended using task_suspend. |
pros::E_TASK_STATE_DELETED | The task has been deleted using task_delete. |
pros::E_TASK_STATE_INVALID | The task handle does not point to a current or past task. |
pros::task_notify_t¶
1 2 3 4 5 6 7 | typedef enum { E_NOTIFY_ACTION_NONE, E_NOTIFY_ACTION_BITS, E_NOTIFY_ACTION_INCR, E_NOTIFY_ACTION_OWRITE, E_NOTIFY_ACTION_NO_OWRITE } notify_action_e_t; |
Value | |
---|---|
pros::E_NOTIFY_ACTION_NONE | The task’s notification value will not be touched. |
pros::E_NOTIFY_ACTION_BITS | The task’s notification value will be bitwise ORed with the new value. |
pros::E_NOTIFY_ACTION_INCR | The task’s notification value will be incremented by one, effectively using it as a notification counter. |
pros::E_NOTIFY_ACTION_OWRITE | The task’s notification value will be unconditionally set to the new value. |
pros::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. |