Piccolo OS Plus 1.01
A feature rich extension of Piccolo OS
|
Here are the Piccolo_Plus APIs, grouped by family function
The initializers | |
These are literally the beginning and the end.
| |
void | piccolo_init () |
Initialize the piccolo run time environment. More... | |
void | piccolo_start () |
Start the Piccolo Task scheduler. More... | |
Task creation and execution control | |
These are the functions for creating and ending tasks, and controlling their execution. Once a task is running, it can yield the processor to the next task voluntarily. It can also suspend execution (sleep) for a time and allow other tasks to execute.
| |
piccolo_os_task_t * | piccolo_create_task (void(*pointer_to_task_function)(void)) |
Create a new task and initialize its stack. More... | |
void | piccolo_end_task () |
Ends the current task, never returns. More... | |
static void | piccolo_yield (void) |
Yields the processor to another task. More... | |
void | piccolo_syscall (void) |
Same as piccolo_yield. More... | |
void | piccolo_sleep (uint32_t sleep_time_ms) |
sleeps for a specified number of milliseconds More... | |
void | piccolo_sleep_until (absolute_time_t until) |
sleeps until an absolute time. More... | |
Task Signals | |
Each task has a built in signal channel which can be used for inter-task synchronization. A channel can hold a specified number of signals. (The maximum is a #define value which can be as large as 2^31). Signals are only events which contain no data and do not occupy any memory. Signals can be sent to a task by another task, or by interrupt service handlers or timer or alarm callback routines. (Though only tasks ought to try blocking!) | |
piccolo_os_task_t * | piccolo_get_task_id () |
Get the ID (task struct address) of the running task. More... | |
int32_t | piccolo_send_signal (piccolo_os_task_t *toTask) |
Send a signal to the specified task. More... | |
int32_t | piccolo_send_signal_blocking (piccolo_os_task_t *toTask) |
Send a signal to the specified task. If the signal channel is full, block until it is not. More... | |
int32_t | piccolo_send_signal_blocking_timeout (piccolo_os_task_t *toTask, uint32_t timeout_ms) |
Send a signal to a specified task. If the channel is full, block with a timeout until it is not. More... | |
int32_t | piccolo_get_signal () |
Attempt to get a signal. More... | |
int32_t | piccolo_get_signal_blocking () |
Get a signal. If none are available, block until one arrives. More... | |
int32_t | piccolo_get_signal_blocking_timeout (uint32_t timeout_ms) |
Attempt to get a signal. If none are available, block with a timeout until one arrives. More... | |
int32_t | piccolo_get_signal_all () |
Get all the signals available. More... | |
int32_t | piccolo_get_signal_all_blocking () |
Get all the signals available. If none are available, block until one arrives. More... | |
int32_t | piccolo_get_signal_all_blocking_timeout (uint32_t timeout_ms) |
Get all the signals available. If none are available, block with a timeout until one arrives. More... | |
piccolo_os_task_t * piccolo_create_task | ( | void(*)(void) | pointer_to_task_function | ) |
Create a new task and initialize its stack.
pointer_to_task_function | The task function to call initially |
Allocates a new task and initializes its stack to the start of the given function. Inserts the task at the end of the scheduler task list. Can be called to create a new task while the scheduler is running. (In other words, a running task can create another task at runtime.)
void piccolo_end_task | ( | void | ) |
Ends the current task, never returns.
Marks the current task as dead (ZOMBIE) and yields, so the scheduler can remove it. (The scheduler must do this, since we cannot free the memory for a task while it is running!). The scheduler will immediately remove a ZOMBIE task from the scheduler chain, add it to the zombies list and signal the garbage collector to return the task space to free memory.
return
will also be ended.
|
inline |
Attempt to get a signal.
|
inline |
Get all the signals available.
Empties the signal channel if signals were available.
|
inline |
Get all the signals available. If none are available, block until one arrives.
Empties the signal channel.
|
inline |
Get all the signals available. If none are available, block with a timeout until one arrives.
timeout_ms | Time in ms to wait for a signal to arrive |
Empties the signal channel.
|
inline |
Get a signal. If none are available, block until one arrives.
|
inline |
Attempt to get a signal. If none are available, block with a timeout until one arrives.
timeout_ms | non zero if timeout enabled on blocking |
piccolo_os_task_t * piccolo_get_task_id | ( | ) |
Get the ID (task struct address) of the running task.
Return the task ID of the running task. Useful for telling callback routines (or other tasks) where to send signals.
piccolo_start
is running on that core. But if you don't call this except inside a task, you will always get a valid task ID. void piccolo_init | ( | ) |
Initialize the piccolo run time environment.
Set the scheduler task list to empty and set up the context switching, interrupt handlers, interrupt priorities and interlocks (spinlocks) for the scheduler.
|
inline |
Send a signal to the specified task.
toTask | pointer to task to send to |
Send a signal to the designated task. If there is space the signal is sent. If there is no room for the signal, return the error.
|
inline |
Send a signal to the specified task. If the signal channel is full, block until it is not.
toTask | pointer to task to send to |
Send a signal to the designated task. If there is space the signal is sent. If there is no room for the signal, block until space is available.
|
inline |
Send a signal to a specified task. If the channel is full, block with a timeout until it is not.
toTask | pointer to task to send to |
timeout_ms | maximum time in ms to wait if the channel is full. |
Send a signal to the designated task. If there is space the signal is sent. If there is no room for the signal, wait until the timeout expires or space is available.
void piccolo_sleep | ( | uint32_t | sleep_time_ms | ) |
sleeps for a specified number of milliseconds
sleep_time_ms | number of milliseconds to sleep; |
The scheduler marks the task as blocked and suspends its execution until the delay has expired.
void piccolo_sleep_until | ( | absolute_time_t | until | ) |
sleeps until an absolute time.
until | absolute time to wake up |
Set the wakeup time for the task and mark it as sleeping for the scheduler. Then suspend execution until the scheduler wakes up the task.
void piccolo_start | ( | ) |
Start the Piccolo Task scheduler.
Start the second processor if multi-core mode is enabled. Switch to handler mode and begin the round robin scheduler.
The scheduler starts with the task after the last task run by either core and looks for a task which is not running (on the other core) and not blocked. Along the way it checks if sleeping tasks or tasks blocked for signaling should be unblocked. The first task found ready to run gets run, with the preemption timer reset and armed if preemption is enabled. After the task yields or is preempted, the scheduler checks if it has ended. (Marked as a zombie.) If so, the task is removed from the scheduler's task list and sent to the garbage collector to free the task's memory.
If no task is ready to run, an idle task will be started to sleep for the minimum of PICCOLO_OS_MAX_IDLE or the smallest time remaining of any timeout. Sleep is the Pico sleep routine, so the core goes to sleep for power reduction. If PICCOLO_OS_MAX_IDLE is set to zero, idle will not run.
If PICCOLO_OS_NO_IDLE_FOR_SIGNALS is true (the default), the idle task will not be run if any task is blocked waiting to send or receive a signal in order to minimize system response time. Setting PICCOLO_OS_NO_IDLE_FOR_SIGNALS to false will improve power consumption but potentially delay the response of any task waiting for a signal. This may make good sense for low power applications without serious response time concerns.
void piccolo_syscall | ( | void | ) |
Same as piccolo_yield.
|
static |
Yields the processor to another task.
The scheduler will switch to the next ready task in a "round robin" manner.