XiUOS 内核中的关键数据结构
Assign
kernel/include/xs_assign.h
struct Assign
{
struct OsAssignReadyVector os_assign_read_vector;
struct TaskDescriptor *os_running_task;
struct PriorityReadyVectorDone *ready_vector_done;
uint8 current_priority;
};
void SwitchKtaskContext(x_ubase from, x_ubase to , struct TaskDescriptor *to_task);
void SwitchKtaskContextTo(x_ubase to, struct TaskDescriptor *to_task);
void HwInterruptcontextSwitch( x_ubase from, x_ubase to, struct TaskDescriptor *to_task ,void *context);
里面又包含了一个 OSAssignReadyVector 类和一个 TaskDescriptor 类的指针
同时包含了一个 PriorityReadyVectorDone 的函数指针,一个 current_priority 的值
OsAssignReadyVector
定义在 kernel/include/xs_ktask.h 中
struct OsAssignReadyVector {
DoubleLinklistType priority_ready_vector[KTASK_PRIORITY_MAX];
uint32 priority_ready_group;
#if KTASK_PRIORITY_MAX > 32
/* Maximum priority level, 256 */
uint8 ready_vector[32];
#endif
x_ubase highest_prio;
};
可以看到这里面由一个 双向链表的数组,判断每个里面是否有ready的元素的ready_group以及ready_vector,以及最高的优先级 构成
DoubleLinklistType
定义在 kernel/include/klist.h 中
typedef struct SysDoubleLinklistNode
{
struct SysDoubleLinklistNode *node_next;
struct SysDoubleLinklistNode *node_prev;
} DoubleLinklistType;
TaskDescriptor
定义在 kernel/include/xs_ktask.h 中
struct TaskDescriptor
{
void *stack_point; ///< stack point
TaskDyncSchedMembeType task_dync_sched_member; ///< task dynamic sched member
TaskBaseInfoType task_base_info; ///< task base information
#ifdef ARCH_SMP
TaskSmpInfoType task_smp_info; ///< dual core information
#endif
#if defined(KERNEL_EVENT)
uint32 event_id_trigger : 29 ; ///< event ops (event trigger )
uint32 event_mode : 3; ///< event mode (AND/OR/AUTOCLEAN)
#endif
x_err_t exstatus; ///< exception status
DoubleLinklistType link; ///< manage list
struct IdNode id; ///< task id
struct KTaskDone *Done;
};
typedef struct TaskDescriptor *KTaskDescriptorType;
包括了栈指针、调度属性、 任务基本信息、错误码、link 双向链表、 任务编号、 任务回调函数
TaskDyncSchedMember
定义在 kernel/include/xs_ktask.h 中
struct TaskDyncSchedMember {
uint8 stat; ///< task stat
uint8 advance_cnt; ///< total time slice advance process count
uint8 cur_prio; ///< task current priority
x_ubase origin_timeslice; ///< task init timeslice
x_ubase rest_timeslice; ///< task remaining timeslice
#ifdef SEPARATE_COMPILE
uint8 isolation_flag; ///< task isolation flag
void *isolation; ///< task isolation pointer
uint8 isolation_status;
#if defined(ARCH_ARM)
uint32_t svc_return;
#endif
#endif
DoubleLinklistType sched_link; ///< task sched list
#if KTASK_PRIORITY_MAX > 32
uint8 bitmap_offset;
uint8 bitmap_row;
#endif
uint32 bitmap_column;
DelayType delay;
};
typedef struct TaskDyncSchedMember TaskDyncSchedMembeType;
定义了一个任务在调度时需要一些属性,包括 状态, 增加的运行次数, 目前的优先级, 初始时间片, 剩余时间片, 调度链表双向链表中的它自身
发现在定义了arm的时候还会返回一个svc_return的值,这个是SVC命令申请超级用户模式时给予一个编号
TaskBaseInfoType
定义在 kernel/include/xs_ktask.h 中
truct TaskBaseInfo {
char name[NAME_NUM_MAX]; ///< task name
void *func_entry; ///< task function entry
void *func_param; ///< task parameter
uint8 origin_prio; ///< task init priority
uint32 stack_depth; ///< task stack size
void *stack_start; ///< task stack start address
};
typedef struct TaskBaseInfo TaskBaseInfoType;
包括了任务名字,程序的进入地址,参数,初始优先级,栈深度,栈开始位置
KernelService
xs_service.h
struct KernelService
{
const kservice fun;
const uint8_t param_num;
};
extern struct KernelService g_service_table[] ;
包括了一个 kservice 的类以及一个参数的数量
同时我们可以看到一个更具体的定义:
xs_service.c
struct KernelService g_service_table[256] __attribute__ ((section (".g_service_table"))) =
{
[KS_USER_PRINT_INFO] = { KsPrintInfo, 1 },
/*************** Task ************/
[KS_USER_TASK_CREATE] = { KsTaskCreate, 5 },
[KS_USER_TASK_STARTUP] = { KsStartupTask, 1 },
[KS_USER_TASK_DELETE] = { KsTaskDelete, 1 },
[KS_USER_TASK_SEARCH] = { KsUserTaskSerach, 0 },
[KS_USER_TASK_EXECEXIT] = { KsTaskQuit, 0 },
[KS_USER_TASK_CORE_COMBINE] = { KsTaskCoreCombine, 2 },
[KS_USER_TASK_CORE_UNCOMBINE] = { KsTaskCoreUnCombine, 1 },
[KS_USER_TASK_DELAY] = { KsMdelayTask, 1 },
[KS_USER_GET_TASK_NAME] = { KsGetTaskName, 2 },
[KS_USER_GET_TASK_ID] = { KsGetTaskID, 0 },
[KS_USER_GET_TASK_STAT] = { KsGetTaskStat, 1 },
[KS_USER_GET_TASK_COMBINEED_CORE] = { KsGetTaskCombinedCore, 1 },
[KS_USER_GET_TASK_RUNNING_CORE] = { KsGetTaskRunningCore, 1 },
[KS_USER_GET_TASK_ERROR_STATUS] = { KsGetTaskErrorstatus, 1 },
[KS_USER_GET_TASK_PRIORITY] = { KsGetTaskPriority, 1 },
/*************** Memory ************/
[KS_USER_MALLOC] = { KsMalloc, 1 },
[KS_USER_FREE] = { KsFree, 1 },
#ifdef KERNEL_MUTEX
/*************** Mutex ************/
[KS_USER_MUTEX_CREATE] = { KsCreateMutex, 0 },
[KS_USER_MUTEX_DELETE] = { KsDeleteMutex, 1 },
[KS_USER_MUTEX_OBTAIN] = { KsMutexObtain, 2 },
[KS_USER_MUTEX_ABANDON] = { KsMutexAbandon, 1 },
#endif
#ifdef KERNEL_SEMAPHORE
/*************** Semaphore ************/
[KS_USER_SEMAPHORE_CREATE] = { KsCreateSemaphore, 1 },
[KS_USER_SEMAPHORE_DELETE] = { KsDeleteSemaphore, 1 },
[KS_USER_SEMAPHORE_OBTAIN] = { KsSemaphoreObtain, 2 },
[KS_USER_SEMAPHORE_ABANDON] = { KsSemaphoreAbandon, 1 },
[KS_USER_SEMAPHORE_SETVALUE] = { KsSemaphoreSetValue, 2 },
#endif
/*************** Event ************/
#ifdef KERNEL_EVENT
[KS_USER_EVENT_CREATE] = { KsCreateEvent, 1 },
[KS_USER_EVENT_DELETE] = { KsDeleteEvent, 1 },
[KS_USER_EVENT_TRIGGER] = { KsEventTrigger, 2 },
[KS_USER_EVENT_PROCESS] = { KsEventProcess, 5 },
#endif
#ifdef KERNEL_MESSAGEQUEUE
/*************** Msg queue ************/
[KS_USER_MSGQUEUE_CREATE] = { KsCreateMsgQueue, 2 },
[KS_USER_MSGQUEUE_DELETE] = { KsDeleteMsgQueue, 1 },
[KS_USER_MSGQUEUE_SENDWAIT] = { KsMsgQueueSendwait, 4 },
[KS_USER_MSGQUEUE_SEND] = { KsMsgQueueSend, 3 },
[KS_USER_MSGQUEUE_URGENTSEND] = { KsMsgQueueUrgentSend, 3 },
[KS_USER_MSGQUEUE_RECV] = { KsMsgQueueRecv, 4 },
[KS_USER_MSGQUEUE_REINIT] = { KsMsgQueueReinit, 1 },
#endif
#ifdef FS_VFS
/*************** fs poxix ************/
[KS_USER_OPEN] = { KsOpen , 3 },
[KS_USER_READ] = { KsRead , 3 },
[KS_USER_WRITE] = { KsWrite , 3 },
[KS_USER_CLOSE] = { KsClose , 1 },
[KS_USER_IOCTL] = { KsIoctl , 3 },
[KS_USER_LSEEK] = { KsLseek , 3 },
[KS_USER_RENAME] = { KsRename , 2 },
[KS_USER_UNLINK] = { KsUnlink , 1 },
[KS_USER_STAT] = { KsStat , 2 },
[KS_USER_FS_STAT] = { KsFstat , 2 },
[KS_USER_FS_SYNC] = { KsFsync , 1 },
[KS_USER_FTRUNCATE] = { KsFtruncate , 2 },
[KS_USER_MKDIR] = { KsMkdir , 2 },
[KS_USER_OPENDIR] = { KsOpendir , 1 },
[KS_USER_CLOSEDIR] = { KsClosedir , 1 },
[KS_USER_READDIR] = { KsReaddir , 1 },
[KS_USER_RMDIR] = { KsRmdir , 1 },
[KS_USER_CHDIR] = { KsChdir , 1 },
[KS_USER_GETCWD] = { KsGetcwd, 2 },
[KS_USER_TELLDIR] = { KsTelldir, 1 },
[KS_USER_SEEKDIR] = { KsSeekdir, 2 },
[KS_USER_REWIND_DIR] = { KsRewinddir, 1 },
[KS_USER_STAT_FS] = { KsStatfs, 2 },
#endif
[KS_USER_END ... 255] = {NONE, 0}
};
UserspaceS
定义在各个Board目录下的 board.h 中
struct UserSpaceS
{
main_t us_entrypoint;
exit_t us_taskquit;
uintptr_t us_textstart;
uintptr_t us_textend;
uintptr_t us_datasource;
uintptr_t us_datastart;
uintptr_t us_dataend;
uintptr_t us_bssstart;
uintptr_t us_bssend;
uintptr_t us_heapend;
};
#define USERSPACE (( struct UserSpaceS *)(MEMORY_END_ADDRESS + G_SERVICE_TABLE_LENGTH))
UserSpaceS 是一个类, USERSPACE 是一个类的实例,而这个实例的开始地址的固定的,就是内存结束的地址加上存放 G_SERVICE_TAbLE 的位置