| /* micro_private.h */ |
| |
| /* |
| * Copyright (c) 1997-2015 Wind River Systems, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef MINIK_H |
| #define MINIK_H |
| |
| #include <stddef.h> |
| #include <micro_private_types.h> |
| #include <kernel_main.h> |
| #include <nano_private.h> |
| #include <misc/__assert.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* |
| * The 2 least significant bits of the commands placed on the microkernel |
| * server's command stack identify the type of command; the remaining bits |
| * are the actual argument for the command. (This works because the actual |
| * arguments are always multiples of 4.) |
| */ |
| |
| /* process the specified command packet (containing command & argument info) */ |
| #define KERNEL_CMD_PACKET_TYPE (0u) |
| |
| /* give the specified event */ |
| #define KERNEL_CMD_EVENT_TYPE (1u) |
| |
| /* give the specified semaphore */ |
| #define KERNEL_CMD_SEMAPHORE_TYPE (2u) |
| |
| /* not used */ |
| #define KERNEL_CMD_RESERVED_TYPE (3u) |
| |
| /* mask for isolating the 2 type bits */ |
| #define KERNEL_CMD_TYPE_MASK (3u) |
| |
| |
| #define KERNEL_ENTRY(A) _k_task_call(A) |
| |
| #define OBJ_INDEX(objId) ((uint16_t)objId) |
| |
| extern struct k_tqhd _k_task_priority_list[]; |
| |
| extern struct pool_struct _k_mem_pool_list[]; |
| |
| extern int _k_mem_pool_count; |
| extern const kmemory_pool_t _heap_mem_pool_id; |
| |
| extern struct k_task *_k_current_task; |
| extern uint32_t _k_task_priority_bitmap[]; |
| |
| extern struct k_timer *_k_timer_list_head; |
| extern struct k_timer *_k_timer_list_tail; |
| |
| extern struct nano_stack _k_command_stack; |
| extern struct nano_lifo _k_server_command_packet_free; |
| extern struct nano_lifo _k_timer_free; |
| |
| extern void _k_timer_enlist(struct k_timer *T); |
| extern void _k_timer_delist(struct k_timer *T); |
| |
| extern void _k_timeout_alloc(struct k_args *P); |
| extern void _k_timeout_free(struct k_timer *T); |
| extern void _k_timeout_cancel(struct k_args *A); |
| |
| extern void _k_timer_list_update(int ticks); |
| |
| extern void _k_do_event_signal(kevent_t event); |
| |
| extern void _k_state_bit_set(struct k_task *, uint32_t); |
| extern void _k_state_bit_reset(struct k_task *, uint32_t); |
| extern void _k_task_call(struct k_args *); |
| |
| /* |
| * The task status flags may be OR'ed together to form a task's state. The |
| * existence of one or more non-zero bits indicates that the task can not be |
| * scheduled for execution because of the conditions associated with those |
| * bits. The task status flags are divided into four (4) groups as follows: |
| * |
| * Break flags (bits 0..5) are associated with conditions that require an |
| * external entity to permit further execution. |
| * |
| * Spare flags (bits 6..9) are located between the break and wait flags |
| * to allow either set to be extended without impacting the other group. |
| * |
| * Wait flags (bits 10..27) are associated with operations that the task itself |
| * initiated, and for which task execution will resume when the requested |
| * operation completes. |
| * |
| * Monitoring bits (bits 28..31) are reserved for use with task level |
| * monitoring. |
| */ |
| |
| #define TF_STOP 0x00000001 /* Not started */ |
| #define TF_TERM 0x00000002 /* Terminated */ |
| #define TF_SUSP 0x00000004 /* Suspended */ |
| #define TF_BLCK 0x00000008 /* Blocked */ |
| #define TF_GDBSTOP 0x00000010 /* Stopped by GDB agent */ |
| #define TF_PRIO 0x00000020 /* Task priority is changing */ |
| |
| #define TF_NANO 0x00000400 /* Waiting on a nanokernel object */ |
| #define TF_TIME 0x00000800 /* Sleeping */ |
| #define TF_DRIV 0x00001000 /* Waiting for arch specific driver */ |
| #define TF_RES0 0x00002000 /* Reserved */ |
| #define TF_EVNT 0x00004000 /* Waiting for an event */ |
| #define TF_ENQU 0x00008000 /* Waiting to put data on a FIFO */ |
| #define TF_DEQU 0x00010000 /* Waiting to get data from a FIFO */ |
| #define TF_SEND 0x00020000 /* Waiting to send via mailbox or pipe */ |
| #define TF_RECV 0x00040000 /* Waiting to recv via mailbox or pipe */ |
| #define TF_SEMA 0x00080000 /* Waiting for a semaphore */ |
| #define TF_LIST 0x00100000 /* Waiting for a group of semaphores */ |
| #define TF_LOCK 0x00200000 /* Waiting for a mutex */ |
| #define TF_ALLO 0x00400000 /* Waiting on a memory mapping */ |
| #define TF_GTBL 0x00800000 /* Waiting on a memory pool */ |
| #define TF_RES1 0x01000000 /* Reserved */ |
| #define TF_RES2 0x02000000 /* Reserved */ |
| #define TF_RECVDATA 0x04000000 /* Waiting to receive data */ |
| #define TF_SENDDATA 0x08000000 /* Waiting to send data */ |
| |
| #define TF_ALLW 0x0FFFFC00 /* Mask of all wait flags */ |
| |
| #ifdef CONFIG_TASK_DEBUG |
| extern int _k_debug_halt; |
| #endif |
| |
| #ifdef CONFIG_TASK_MONITOR |
| |
| #define MON_TSWAP 1 |
| #define MON_STATE 2 |
| #define MON_KSERV 4 |
| #define MON_EVENT 8 |
| #define MON_ALL 15 |
| |
| typedef void (*k_task_monitor_hook_t)(ktask_t taskid, uint32_t timestamp); |
| |
| extern void task_monitor_hook_set(k_task_monitor_hook_t func); |
| |
| extern void _k_task_monitor(struct k_task *, uint32_t d2); |
| extern void _k_task_monitor_args(struct k_args *); |
| extern void _k_task_monitor_read(struct k_args *); |
| |
| #ifdef CONFIG_KERNEL_EVENT_LOGGER_DYNAMIC |
| extern int _k_monitor_mask; |
| #else |
| extern const int _k_monitor_mask; |
| #endif |
| |
| /* task level monitor bits */ |
| |
| #define MO_STBIT0 0x20000000 |
| #define MO_STBIT1 0x30000000 |
| #define MO_EVENT 0x40000000 |
| #define MO_LCOMM 0x50000000 |
| #define MO_RCOMM 0x60000000 |
| |
| #endif |
| |
| #ifdef CONFIG_WORKLOAD_MONITOR |
| extern void _k_workload_monitor_calibrate(void); |
| extern void _k_workload_monitor_update(void); |
| extern void _k_workload_monitor_idle_start(void); |
| extern void _k_workload_monitor_idle_end(void); |
| #else |
| #define _k_workload_monitor_update() do { /* nothing */ } while (0) |
| #endif |
| |
| #define INSERT_ELM(L, E) \ |
| { \ |
| struct k_args *X = (L); \ |
| struct k_args *Y = NULL; \ |
| while (X && (X->priority <= (E)->priority)) { \ |
| Y = X; \ |
| X = X->next; \ |
| } \ |
| if (Y) \ |
| Y->next = (E); \ |
| else \ |
| (L) = (E); \ |
| (E)->next = X; \ |
| (E)->head = &(L); \ |
| } |
| |
| #define REMOVE_ELM(E) \ |
| { \ |
| struct k_args *X = *((E)->head); \ |
| struct k_args *Y = NULL; \ |
| \ |
| while (X && (X != (E))) { \ |
| Y = X; \ |
| X = X->next; \ |
| } \ |
| if (X) { \ |
| if (Y) \ |
| Y->next = X->next; \ |
| else \ |
| *((E)->head) = X->next; \ |
| } \ |
| } |
| |
| #define GETARGS(A) \ |
| do { \ |
| (A) = _nano_fiber_lifo_get_panic(&_k_server_command_packet_free); \ |
| } while (0) |
| #define GETTIMER(T) \ |
| do { \ |
| (T) = _nano_fiber_lifo_get_panic(&_k_timer_free); \ |
| } while (0) |
| |
| #define FREEARGS(A) nano_fiber_lifo_put(&_k_server_command_packet_free, (A)) |
| #define FREETIMER(T) nano_fiber_lifo_put(&_k_timer_free, (T)) |
| |
| #define TO_ALIST(L, A) nano_fiber_stack_push((L), (uint32_t)(A)) |
| |
| #define _COMMAND_STACK_SIZE_CHECK() do { \ |
| __ASSERT((_k_command_stack.next - _k_command_stack.base) \ |
| < CONFIG_COMMAND_STACK_SIZE, \ |
| "microkernel server command stack exceeded\n"); \ |
| } while ((0)) |
| |
| #define SENDARGS(A) do { \ |
| _COMMAND_STACK_SIZE_CHECK(); \ |
| nano_fiber_stack_push(&_k_command_stack, (uint32_t)(A)); \ |
| } while ((0)) |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif |