Piccolo OS Plus 1.01
A feature rich extension of Piccolo OS
|
Data Structures | |
struct | piccolo_os_task_t |
Piccolo OS task data structure. More... | |
struct | piccolo_os_internals_t |
Piccolo OS internal data structure. More... | |
Macros | |
#define | PICCOLO_OS_STACK_SIZE 1024 |
Size of a task stack in 32 bit words. More... | |
#define | PICCOLO_OS_THREAD_PSP 0xFFFFFFFD |
#define | PICCOLO_OS_TIME_SLICE 1000 |
The OS time slice, in microseconds. More... | |
#define | PICCOLO_OS_MAX_IDLE 700 |
The maximum time that the scheduler will sleep in the idle task (in usec). More... | |
#define | PICCOLO_OS_NO_IDLE_FOR_SIGNALS true |
If true, the scheduler will not idle (sleep) if tasks are blocking for signals. More... | |
#define | PICCOLO_OS_MULTICORE true |
Enable/disable multi-core scheduling. More... | |
#define | PICCOLO_OS_MAX_SIGNAL 10 |
Signal channel size. (max is INT32_MAX) More... | |
#define | PICCOLO_SPIN_LOCK_ID PICO_SPINLOCK_ID_OS1 |
Enumerations | |
enum | piccolo_task_flag_values { PICCOLO_TASK_RUNNING = 0x1 , PICCOLO_TASK_ZOMBIE = 0x2 , PICCOLO_TASK_SLEEPING = 0x4 , PICCOLO_TASK_GET_SIGNAL_BLOCKED = 0x8 , PICCOLO_TASK_SEND_SIGNAL_BLOCKED = 0x10 , PICCOLO_TASK_BLOCKING = (PICCOLO_TASK_SLEEPING | PICCOLO_TASK_GET_SIGNAL_BLOCKED | PICCOLO_TASK_SEND_SIGNAL_BLOCKED) } |
Functions | |
uint32_t * | __piccolo_os_create_task (uint32_t *task_stack, void(*pointer_to_task_function)(void), uint32_t starting_argument) |
Initialize user task stack for execution. More... | |
int32_t | __piccolo_send_signal (piccolo_os_task_t *task, bool block, uint32_t timeout_ms) |
Helper for send signal functions. More... | |
int32_t | __piccolo_get_signal (bool block, uint32_t timeout_ms, bool get_all) |
Helper for get signal functions. More... | |
void | __piccolo_garbage_man (void) |
Task to delete dead tasks. More... | |
void | __piccolo_task_init (void) |
Switch the scheduler to handler mode. More... | |
void | __piccolo_idle (int32_t uSec) |
Internal Idle "task" used by the scheduler to sleep the core. More... | |
void | __piccolo_start_core1 (void) |
Core 1 code to initialize and immediately start the piccolo scheduler on core 1. More... | |
Variables | |
**struct piccolo_os_task_t | piccolo_os_task_t |
struct piccolo_os_task_t |
Piccolo OS task data structure.
Data Fields | ||
---|---|---|
struct piccolo_os_task_t * | next_task |
next task in scheduler chain |
struct piccolo_os_task_t * | prev_task |
previous task in scheduler chain |
volatile uint32_t | signal_in |
input values for the task's input signal channel |
uint32_t | signal_limit |
maximum number of signals (+1) the task can queue |
volatile uint32_t | signal_out |
output values for the task's input signal channel |
uint32_t | stack[PICCOLO_OS_STACK_SIZE] |
the task stack space |
uint32_t * | stack_ptr |
the task stack pointer |
volatile uint32_t | task_flags |
Task Status |
struct piccolo_os_task_t * | task_sending_to |
task that this one if blocked trying to signal |
absolute_time_t | wakeup |
end of sleep time or timeout |
struct piccolo_os_internals_t |
Piccolo OS internal data structure.
Data Fields | ||
---|---|---|
volatile piccolo_os_task_t * | current_task |
last task started on either core for round-robin scheduling |
piccolo_os_task_t * | garbage_man |
Garbage collector task (so schedulers can signal him) |
spin_lock_t * | piccolo_lock |
spin lock instance |
piccolo_os_task_t * | task_list_head |
pointer to the first task in scheduler list |
piccolo_os_task_t * | task_list_tail |
pointer to the last task in scheduler list |
volatile piccolo_os_task_t * | this_task[2] |
|
piccolo_os_task_t * | zombies |
(singly linked) list of dead tasks for garbage collection |
#define PICCOLO_OS_MAX_IDLE 700 |
The maximum time that the scheduler will sleep in the idle task (in usec).
This will influence the latency for tasks waking up for signals, for example. Setting this to zero will disable the idle task.
#define PICCOLO_OS_MAX_SIGNAL 10 |
Signal channel size. (max is INT32_MAX)
The number of signals which can be queued in a signal channel (+1). It can be set smaller for testing or special purposes.
#define PICCOLO_OS_MULTICORE true |
Enable/disable multi-core scheduling.
#define PICCOLO_OS_NO_IDLE_FOR_SIGNALS true |
If true, the scheduler will not idle (sleep) if tasks are blocking for signals.
If set to false, the scheduler will run the idle task for the minimum of PICCOLO_OS_MAX_IDLE or the smallest time remaining for any task with a timeout running. This will improve power consumption but potentially delay the response of any task waiting for a signal. This may make good sense for applications without serious response time concerns.
#define PICCOLO_OS_STACK_SIZE 1024 |
Size of a task stack in 32 bit words.
#define PICCOLO_OS_THREAD_PSP 0xFFFFFFFD |
Exception return behavior value
#define PICCOLO_OS_TIME_SLICE 1000 |
The OS time slice, in microseconds.
Setting time slice to zero will disable preemptive scheduling!
#define PICCOLO_SPIN_LOCK_ID PICO_SPINLOCK_ID_OS1 |
Piccolo spin lock to use
void __piccolo_garbage_man | ( | void | ) |
Task to delete dead tasks.
The task is created during the scheduler start-up on core 0. When it runs, it tries to free the space for all the dead tasks on the zombies list. (The scheduler cannot call free()
, because it is an interrupt handler and would break the mutex that protects free()
and malloc()
).
int32_t __piccolo_get_signal | ( | bool | block, |
uint32_t | timeout_ms, | ||
bool | get_all | ||
) |
Helper for get signal functions.
block | true if blocking on send |
timeout_ms | non zero if timeout enabled on blocking |
get_all | if true, get ALL signals available. Otherwise just get one. |
Get a signal for the current task. Return the number received. If there are no signals available, return zero unless blocking was requested. If blocking is necessary, start a timeout as well if one was requested.
void __piccolo_idle | ( | int32_t | uSec | ) |
Internal Idle "task" used by the scheduler to sleep the core.
uSec | the number of microseconds to sleep |
Enter sleep mode and then "yield" back to the scheduler. Entry and parameter passing is set up in a dummy stack frame before switching context.
uint32_t * __piccolo_os_create_task | ( | uint32_t * | task_stack, |
void(*)(void) | pointer_to_task_function, | ||
uint32_t | starting_argument | ||
) |
Initialize user task stack for execution.
task_stack | pointer to the END of the task stack (array). |
pointer_to_task_function | the function to execute. |
starting_argument | unsigned integer argument for function |
We setup the initial stack frame with:
piccolo_end_task()
in case the task exits or returnsPICCOLO_OS_THREAD_PSP means:
int32_t __piccolo_send_signal | ( | piccolo_os_task_t * | task, |
bool | block, | ||
uint32_t | timeout_ms | ||
) |
Helper for send signal functions.
task | pointer to task to send to |
block | true if blocking on send |
timeout_ms | non zero if timeout enabled on blocking |
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 unless blocking was requested. If blocking is necessary, start a timeout as well, if one was requested.
void __piccolo_start_core1 | ( | void | ) |
Core 1 code to initialize and immediately start the piccolo scheduler on core 1.
Remember that the piccolo_init()
checks the core number and does not setup the data structures or the interrupt vector table if it is not core 0. piccolo_start()
takes similar precautions. The scheduler will run on both cores at once.
void __piccolo_task_init | ( | void | ) |
Switch the scheduler to handler mode.
After a reset, the processor is in thread mode. Switch to handler mode, so that the Piccolo OS kernel runs in handler mode, and to ensure the correct return from an exception/interrupt later when switching to a task. We make a dummy stack and arrange to route the service call exception back to ourselves!
** struct piccolo_os_task_t piccolo_os_task_t |