341 lines
11 KiB
C
341 lines
11 KiB
C
/* nanokernel.h - public API for nanokernel */
|
|
|
|
/*
|
|
* Copyright (c) 1997-2015, Wind River Systems, Inc.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1) Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3) Neither the name of Wind River Systems nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef __NANOKERNEL_H__
|
|
#define __NANOKERNEL_H__
|
|
|
|
/* fundamental include files */
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <toolchain.h>
|
|
|
|
/* generic kernel public APIs */
|
|
|
|
#include <kernel_version.h>
|
|
#include <sys_clock.h>
|
|
#include <drivers/rand32.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
* nanokernel private APIs that are exposed via the public API
|
|
*
|
|
* THESE ITEMS SHOULD NOT BE REFERENCED EXCEPT BY THE KERNEL ITSELF!
|
|
*/
|
|
|
|
struct _nano_queue {
|
|
void *head;
|
|
void *tail;
|
|
};
|
|
|
|
#include <misc/dlist.h>
|
|
|
|
struct _nano_timeout {
|
|
sys_dlist_t node;
|
|
struct _nano_queue *wait_q;
|
|
int32_t delta_ticks_from_prev;
|
|
};
|
|
|
|
struct ccs;
|
|
|
|
/* architecture-independent nanokernel public APIs */
|
|
|
|
typedef struct ccs *nano_context_id_t;
|
|
|
|
typedef void (*nano_fiber_entry_t)(int i1, int i2);
|
|
|
|
typedef int nano_context_type_t;
|
|
|
|
|
|
#define NANO_CTX_ISR (0)
|
|
#define NANO_CTX_FIBER (1)
|
|
#define NANO_CTX_TASK (2)
|
|
|
|
/* timeout special values */
|
|
#define TICKS_UNLIMITED (-1)
|
|
#define TICKS_NONE 0
|
|
|
|
/* context APIs
|
|
*/
|
|
extern nano_context_id_t context_self_get(void);
|
|
extern nano_context_type_t context_type_get(void);
|
|
extern int _context_essential_check(nano_context_id_t pCtx);
|
|
|
|
/* fiber APIs
|
|
*/
|
|
/* scheduling context independent method (when context is not known) */
|
|
void fiber_start(char *stack,
|
|
unsigned stack_size,
|
|
nano_fiber_entry_t entry,
|
|
int arg1,
|
|
int arg2,
|
|
unsigned prio,
|
|
unsigned options);
|
|
|
|
/* methods for fibers */
|
|
extern void fiber_fiber_start(char *pStack,
|
|
unsigned int stackSize,
|
|
nano_fiber_entry_t entry,
|
|
int arg1,
|
|
int arg2,
|
|
unsigned prio,
|
|
unsigned options);
|
|
extern void fiber_yield(void);
|
|
extern void fiber_abort(void);
|
|
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern void fiber_sleep(int32_t timeout);
|
|
extern void *fiber_fiber_delayed_start(char *stack,
|
|
unsigned int stack_size_in_bytes,
|
|
nano_fiber_entry_t entry_point, int param1,
|
|
int param2, unsigned int priority,
|
|
unsigned int options, int32_t timeout_in_ticks);
|
|
extern void *fiber_delayed_start(char *stack, unsigned int stack_size_in_bytes,
|
|
nano_fiber_entry_t entry_point, int param1,
|
|
int param2, unsigned int priority,
|
|
unsigned int options, int32_t timeout_in_ticks);
|
|
extern void fiber_delayed_start_cancel(void *handle);
|
|
extern void fiber_fiber_delayed_start_cancel(void *handle);
|
|
#endif
|
|
|
|
/* methods for tasks */
|
|
extern void task_fiber_start(char *pStack,
|
|
unsigned int stackSize,
|
|
nano_fiber_entry_t entry,
|
|
int arg1,
|
|
int arg2,
|
|
unsigned prio,
|
|
unsigned options);
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern void *task_fiber_delayed_start(char *stack,
|
|
unsigned int stack_size_in_bytes,
|
|
nano_fiber_entry_t entry_point, int param1,
|
|
int param2, unsigned int priority,
|
|
unsigned int options, int32_t timeout_in_ticks);
|
|
extern void task_fiber_delayed_start_cancel(void *handle);
|
|
#endif
|
|
|
|
/* FIFO APIs */
|
|
|
|
struct nano_fifo {
|
|
union {
|
|
struct _nano_queue wait_q;
|
|
struct _nano_queue data_q;
|
|
};
|
|
int stat;
|
|
};
|
|
|
|
extern void nano_fifo_init(struct nano_fifo *chan);
|
|
/* scheduling context independent methods (when context is not known) */
|
|
extern void nano_fifo_put(struct nano_fifo *chan, void *data);
|
|
extern void *nano_fifo_get(struct nano_fifo *chan);
|
|
extern void *nano_fifo_get_wait(struct nano_fifo *chan);
|
|
/* methods for ISRs */
|
|
extern void nano_isr_fifo_put(struct nano_fifo *chan, void *data);
|
|
extern void *nano_isr_fifo_get(struct nano_fifo *chan);
|
|
/* methods for fibers */
|
|
extern void nano_fiber_fifo_put(struct nano_fifo *chan, void *data);
|
|
extern void *nano_fiber_fifo_get(struct nano_fifo *chan);
|
|
extern void *nano_fiber_fifo_get_wait(struct nano_fifo *chan);
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern void *nano_fiber_fifo_get_wait_timeout(struct nano_fifo *chan,
|
|
int32_t timeout_in_ticks);
|
|
#endif
|
|
|
|
/* methods for tasks */
|
|
extern void nano_task_fifo_put(struct nano_fifo *chan, void *data);
|
|
extern void *nano_task_fifo_get(struct nano_fifo *chan);
|
|
extern void *nano_task_fifo_get_wait(struct nano_fifo *chan);
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern void *nano_task_fifo_get_wait_timeout(struct nano_fifo *chan,
|
|
int32_t timeout_in_ticks);
|
|
#endif
|
|
|
|
/* LIFO APIs */
|
|
|
|
struct nano_lifo {
|
|
struct _nano_queue wait_q;
|
|
void *list;
|
|
};
|
|
|
|
extern void nano_lifo_init(struct nano_lifo *chan);
|
|
/* methods for ISRs */
|
|
extern void nano_isr_lifo_put(struct nano_lifo *chan, void *data);
|
|
extern void *nano_isr_lifo_get(struct nano_lifo *chan);
|
|
/* methods for fibers */
|
|
extern void nano_fiber_lifo_put(struct nano_lifo *chan, void *data);
|
|
extern void *nano_fiber_lifo_get(struct nano_lifo *chan);
|
|
extern void *nano_fiber_lifo_get_wait(struct nano_lifo *chan);
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern void *nano_fiber_lifo_get_wait_timeout(struct nano_lifo *chan,
|
|
int32_t timeout_in_ticks);
|
|
#endif
|
|
|
|
/* methods for tasks */
|
|
extern void nano_task_lifo_put(struct nano_lifo *chan, void *data);
|
|
extern void *nano_task_lifo_get(struct nano_lifo *chan);
|
|
extern void *nano_task_lifo_get_wait(struct nano_lifo *chan);
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern void *nano_task_lifo_get_wait_timeout(struct nano_lifo *chan,
|
|
int32_t timeout_in_ticks);
|
|
#endif
|
|
|
|
/* semaphore APIs */
|
|
|
|
struct nano_sem {
|
|
struct _nano_queue wait_q;
|
|
int nsig;
|
|
};
|
|
|
|
extern void nano_sem_init(struct nano_sem *chan);
|
|
/* scheduling context independent methods (when context is not known) */
|
|
extern void nano_sem_give(struct nano_sem *chan);
|
|
extern void nano_sem_take_wait(struct nano_sem *chan);
|
|
/* methods for ISRs */
|
|
extern void nano_isr_sem_give(struct nano_sem *chan);
|
|
extern int nano_isr_sem_take(struct nano_sem *chan);
|
|
/* methods for fibers */
|
|
extern void nano_fiber_sem_give(struct nano_sem *chan);
|
|
extern int nano_fiber_sem_take(struct nano_sem *chan);
|
|
extern void nano_fiber_sem_take_wait(struct nano_sem *chan);
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern int nano_fiber_sem_take_wait_timeout(struct nano_sem *chan,
|
|
int32_t timeout);
|
|
#endif
|
|
|
|
/* methods for tasks */
|
|
extern void nano_task_sem_give(struct nano_sem *chan);
|
|
extern int nano_task_sem_take(struct nano_sem *chan);
|
|
extern void nano_task_sem_take_wait(struct nano_sem *chan);
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
extern int nano_task_sem_take_wait_timeout(struct nano_sem *chan,
|
|
int32_t timeout);
|
|
#endif
|
|
|
|
/* stack APIs */
|
|
|
|
struct nano_stack {
|
|
nano_context_id_t fiber;
|
|
uint32_t *base;
|
|
uint32_t *next;
|
|
};
|
|
|
|
extern void nano_stack_init(struct nano_stack *chan, uint32_t *data);
|
|
/* methods for ISRs */
|
|
extern void nano_isr_stack_push(struct nano_stack *chan, uint32_t data);
|
|
extern int nano_isr_stack_pop(struct nano_stack *chan, uint32_t *data);
|
|
/* methods for fibers */
|
|
extern void nano_fiber_stack_push(struct nano_stack *chan, uint32_t data);
|
|
extern int nano_fiber_stack_pop(struct nano_stack *chan, uint32_t *data);
|
|
extern uint32_t nano_fiber_stack_pop_wait(struct nano_stack *chan);
|
|
/* methods for tasks */
|
|
extern void nano_task_stack_push(struct nano_stack *chan, uint32_t data);
|
|
extern int nano_task_stack_pop(struct nano_stack *chan, uint32_t *data);
|
|
extern uint32_t nano_task_stack_pop_wait(struct nano_stack *chan);
|
|
|
|
|
|
/* context custom data APIs */
|
|
#ifdef CONFIG_CONTEXT_CUSTOM_DATA
|
|
extern void context_custom_data_set(void *value);
|
|
extern void *context_custom_data_get(void);
|
|
#endif /* CONFIG_CONTEXT_CUSTOM_DATA */
|
|
|
|
/* nanokernel timers */
|
|
|
|
struct nano_timer {
|
|
struct nano_timer *link;
|
|
uint32_t ticks;
|
|
struct nano_lifo lifo;
|
|
void *userData;
|
|
};
|
|
|
|
extern void nano_timer_init(struct nano_timer *chan, void *data);
|
|
|
|
/* methods for fibers */
|
|
extern void nano_fiber_timer_start(struct nano_timer *chan, int ticks);
|
|
extern void *nano_fiber_timer_test(struct nano_timer *chan);
|
|
extern void *nano_fiber_timer_wait(struct nano_timer *chan);
|
|
extern void nano_fiber_timer_stop(struct nano_timer *chan);
|
|
|
|
/* methods for tasks */
|
|
extern void nano_task_timer_start(struct nano_timer *chan, int ticks);
|
|
extern void *nano_task_timer_test(struct nano_timer *chan);
|
|
extern void *nano_task_timer_wait(struct nano_timer *chan);
|
|
extern void nano_task_timer_stop(struct nano_timer *chan);
|
|
|
|
/* methods for tasks and fibers for handling time and ticks */
|
|
|
|
extern int64_t nano_tick_get(void);
|
|
extern uint32_t nano_tick_get_32(void);
|
|
extern uint32_t nano_cycle_get_32(void);
|
|
extern int64_t nano_tick_delta(int64_t *reftime);
|
|
extern uint32_t nano_tick_delta_32(int64_t *reftime);
|
|
|
|
/*
|
|
* Auto-initialization
|
|
*
|
|
* The SYS_PREKERNEL_INIT() macro is used to indicate that the specified
|
|
* routine be executed before the kernel initializes. All such routines
|
|
* are issued in order of highest priority level to lowest priority level.
|
|
* Values are 000 (highest priority) to 999 (lowest priority). If all
|
|
* three (3) digits are not supplied, unexpected results may occur, as
|
|
* the linker would interpret priority 19 as a lower priority than 2. To
|
|
* prevent that scenario, the proper priorities to specify would be 019
|
|
* and 002 respectively.
|
|
*
|
|
* Example:
|
|
* void my_library_init(void)
|
|
* {
|
|
* ...
|
|
* }
|
|
*
|
|
* SYS_PREKERNEL_INIT(my_library_init, 500);
|
|
*
|
|
*/
|
|
|
|
#define SYS_PREKERNEL_INIT(name, level) \
|
|
void (*__ctor_##name)(void) __prekernel_init_level(level) = name
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
/* architecture-specific nanokernel public APIs */
|
|
|
|
#include <arch/cpu.h>
|
|
|
|
#endif /* __NANOKERNEL_H__ */
|