forked from xuos/xiuos
First commit XiUOS
This commit is contained in:
317
kernel/Kconfig
Normal file
317
kernel/Kconfig
Normal file
@@ -0,0 +1,317 @@
|
||||
menu "Kernel feature"
|
||||
menu "separate compile(choose none for compile once)"
|
||||
config SEPARATE_COMPILE
|
||||
bool
|
||||
default n
|
||||
|
||||
config COMPILER_APP
|
||||
bool "only compile application"
|
||||
default n
|
||||
select USER_APPLICATION
|
||||
select SEPARATE_COMPILE
|
||||
choice
|
||||
prompt "select the startup site of APP "
|
||||
default APP_STARTUP_FROM_FLASH
|
||||
|
||||
config APP_STARTUP_FROM_SDCARD
|
||||
bool "app start from sd card"
|
||||
|
||||
config APP_STARTUP_FROM_FLASH
|
||||
bool "app start from flash"
|
||||
endchoice
|
||||
|
||||
|
||||
config COMPILER_KERNEL
|
||||
bool "only compile kernel"
|
||||
default n
|
||||
select SEPARATE_COMPILE
|
||||
endmenu
|
||||
|
||||
menu "Memory Management"
|
||||
config KERNEL_MEMBLOCK
|
||||
bool "Using gather block"
|
||||
default n
|
||||
config MEM_ALIGN_SIZE
|
||||
int "Alignment size for CPU architecture data access"
|
||||
default 8
|
||||
help
|
||||
Alignment size for CPU architecture data access
|
||||
|
||||
config MM_PAGE_SIZE
|
||||
int "Config memory page size"
|
||||
default 4096
|
||||
help
|
||||
config memory page size
|
||||
menu "Using small memory allocator"
|
||||
config KERNEL_SMALL_MEM_ALLOC
|
||||
bool "Using small memory allocator"
|
||||
default y
|
||||
if KERNEL_SMALL_MEM_ALLOC
|
||||
config SMALL_NUMBER_32B
|
||||
int "Config 32B small memory number"
|
||||
range 1 256
|
||||
default 64
|
||||
config SMALL_NUMBER_64B
|
||||
int "Config 64B small memory number"
|
||||
range 1 128
|
||||
default 32
|
||||
endif
|
||||
endmenu
|
||||
endmenu
|
||||
|
||||
menu "Task feature"
|
||||
config USER_APPLICATION
|
||||
bool "start system application"
|
||||
default y
|
||||
|
||||
config TASK_ISOLATION
|
||||
bool "Enable task isolation"
|
||||
default n
|
||||
select SEPARATE_COMPILE
|
||||
select COMPILER_APP
|
||||
select COMPILER_KERNEL
|
||||
help
|
||||
Enable task isolation
|
||||
|
||||
menu "Inter-Task communication"
|
||||
config KERNEL_SEMAPHORE
|
||||
bool "Enable semaphore"
|
||||
default y
|
||||
|
||||
config KERNEL_MUTEX
|
||||
bool "Enable mutex"
|
||||
default y
|
||||
|
||||
config KERNEL_EVENT
|
||||
bool "Enable event"
|
||||
default y
|
||||
|
||||
config KERNEL_MESSAGEQUEUE
|
||||
bool "Enable message queue"
|
||||
default y
|
||||
|
||||
config KERNEL_SOFTTIMER
|
||||
bool "Enable softtimer "
|
||||
select KERNEL_WORKQUEUE
|
||||
default y
|
||||
endmenu
|
||||
|
||||
choice
|
||||
prompt "Scheduler Policy Set"
|
||||
default SCHED_POLICY_RR_REMAINSLICE
|
||||
|
||||
config SCHED_POLICY_RR_REMAINSLICE
|
||||
bool "config scheduler policy as RR REMAINSLICE"
|
||||
|
||||
config SCHED_POLICY_RR
|
||||
bool "config scheduler policy as RR "
|
||||
|
||||
config SCHED_POLICY_FIFO
|
||||
bool "config scheduler policy as FIFO"
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "The maximal level value of priority of task"
|
||||
default KTASK_PRIORITY_32
|
||||
|
||||
config KTASK_PRIORITY_8
|
||||
bool "8"
|
||||
|
||||
config KTASK_PRIORITY_32
|
||||
bool "32"
|
||||
|
||||
config KTASK_PRIORITY_256
|
||||
bool "256"
|
||||
endchoice
|
||||
|
||||
config KTASK_PRIORITY_MAX
|
||||
int
|
||||
default 8 if KTASK_PRIORITY_8
|
||||
default 32 if KTASK_PRIORITY_32
|
||||
default 256 if KTASK_PRIORITY_256
|
||||
|
||||
config TICK_PER_SECOND
|
||||
int "Tick frequency, Hz"
|
||||
range 10 1000
|
||||
default 100
|
||||
help
|
||||
System's tick frequency, Hz.
|
||||
|
||||
config KERNEL_STACK_OVERFLOW_CHECK
|
||||
bool "Using stack overflow checking"
|
||||
default y
|
||||
help
|
||||
Enable task stack overflow checking. The stack overflow is checking when
|
||||
each task switch.
|
||||
|
||||
config IDLE_KTASK_STACKSIZE
|
||||
int "The stack size of idle task"
|
||||
default 1024
|
||||
|
||||
config ZOMBIE_KTASK_STACKSIZE
|
||||
int "The stack size of zombie_recycle task"
|
||||
default 2048
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Kernel Console"
|
||||
config KERNEL_CONSOLE
|
||||
bool "config enable console"
|
||||
default y
|
||||
|
||||
if KERNEL_CONSOLE
|
||||
config KERNEL_BANNER
|
||||
bool "config system banner print"
|
||||
default y
|
||||
|
||||
config KERNEL_CONSOLEBUF_SIZE
|
||||
int "default buffer size for console log printf"
|
||||
default 128
|
||||
endif
|
||||
endmenu
|
||||
|
||||
menu "Kernel Hook"
|
||||
menuconfig KERNEL_HOOK
|
||||
bool "Enable system hook"
|
||||
default n
|
||||
help
|
||||
Enable the hook function when system running, such as idle task hook,
|
||||
task context switch etc.
|
||||
|
||||
if KERNEL_HOOK
|
||||
menuconfig KERNEL_IDLE_HOOK
|
||||
bool "Enable IDLE Task hook"
|
||||
default y
|
||||
|
||||
if KERNEL_IDLE_HOOK
|
||||
config IDEL_HOOK_LIST_SIZE
|
||||
int "The max size of idle hook list"
|
||||
default 4
|
||||
range 1 16
|
||||
help
|
||||
The system has a hook list. This is the hook list size.
|
||||
endif
|
||||
endif
|
||||
endmenu
|
||||
|
||||
source "$KERNEL_DIR/tool/shell/Kconfig"
|
||||
|
||||
menu "Kernel data structure Manage"
|
||||
menuconfig KERNEL_QUEUEMANAGE
|
||||
bool "Config Kernel Queue Manage"
|
||||
default y
|
||||
|
||||
if KERNEL_QUEUEMANAGE
|
||||
config KERNEL_WORKQUEUE
|
||||
bool "Config kernel work queue"
|
||||
default y
|
||||
|
||||
if KERNEL_WORKQUEUE
|
||||
config WORKQUEUE_KTASK_STACKSIZE
|
||||
int "The stack size for workqueue task"
|
||||
default 2048
|
||||
|
||||
config WORKQUEUE_KTASK_PRIORITY
|
||||
int
|
||||
default 6 if KTASK_PRIORITY_8
|
||||
default 23 if KTASK_PRIORITY_32
|
||||
default 128 if KTASK_PRIORITY_256
|
||||
config QUEUE_MAX
|
||||
int "Config the max queue length"
|
||||
default 16
|
||||
endif
|
||||
|
||||
config KERNEL_WAITQUEUE
|
||||
bool "Config kernel wait queue"
|
||||
default y
|
||||
|
||||
config KERNEL_DATAQUEUE
|
||||
bool "Config kernel data queue"
|
||||
default y
|
||||
endif
|
||||
|
||||
config KERNEL_CIRCULAR_AREA
|
||||
bool "Config Kernel Circular Area"
|
||||
default n
|
||||
|
||||
config KERNEL_AVL_TREE
|
||||
bool "Config Kernel AVL Tree"
|
||||
default n
|
||||
endmenu
|
||||
|
||||
menu "Kernel components init"
|
||||
menuconfig KERNEL_COMPONENTS_INIT
|
||||
bool "Use components automatically initialization"
|
||||
default y
|
||||
|
||||
if KERNEL_COMPONENTS_INIT
|
||||
config ENV_INIT_KTASK_STACK_SIZE
|
||||
int "Set env init task stack size"
|
||||
default 8192
|
||||
|
||||
menuconfig KERNEL_USER_MAIN
|
||||
bool "The main() function as user entry function"
|
||||
default y
|
||||
endif
|
||||
endmenu
|
||||
|
||||
config NAME_NUM_MAX
|
||||
int "The maximal size of kernel object name"
|
||||
range 2 32
|
||||
default 32
|
||||
help
|
||||
Each kernel object, such as task has a name,
|
||||
the NAME_NUM_MAX is the maximal size of this name.
|
||||
|
||||
menuconfig KERNEL_DEBUG
|
||||
bool "Enable debugging features"
|
||||
default n
|
||||
|
||||
if KERNEL_DEBUG
|
||||
config DEBUG_INIT_CONFIG
|
||||
bool "Enable debugging of components initialization"
|
||||
default y
|
||||
|
||||
config KDYN_LOG_DBG
|
||||
bool "Enable DYNAMIC [DBG] LOG"
|
||||
default y
|
||||
|
||||
config DBG_INIT
|
||||
int
|
||||
default 1 if DEBUG_INIT_CONFIG
|
||||
endif
|
||||
|
||||
menuconfig ARCH_SMP
|
||||
bool "Enable SMP(Symmetric multiprocessing)"
|
||||
default n
|
||||
help
|
||||
This option should be selected by machines which have an SMP-
|
||||
capable CPU.
|
||||
The only effect of this option is to make the SMP-related
|
||||
options available to the user for configuration.
|
||||
|
||||
config CPU_NUMBERS
|
||||
int "Number of CPUs"
|
||||
default 2
|
||||
depends on ARCH_SMP
|
||||
help
|
||||
Number of CPUs in the system
|
||||
menu "hash table config"
|
||||
menuconfig ID_HTABLE_SIZE
|
||||
int "ID hash table size"
|
||||
range 1 256
|
||||
default 16
|
||||
help
|
||||
Size of the hash table that ID manager uses internally
|
||||
menuconfig ID_NUM_MAX
|
||||
int "ID num max"
|
||||
range 16 256
|
||||
default 128
|
||||
help
|
||||
max num of the ID manager
|
||||
endmenu
|
||||
|
||||
|
||||
source "$KERNEL_DIR/kernel/kernel_test/Kconfig"
|
||||
|
||||
endmenu
|
||||
9
kernel/Makefile
Normal file
9
kernel/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
SRC_DIR := thread memory
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST), y)
|
||||
SRC_DIR += kernel_test
|
||||
endif
|
||||
|
||||
SRC_DIR +=kernel_service
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
247
kernel/include/user_api.h
Normal file
247
kernel/include/user_api.h
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: user_api.h
|
||||
* @brief: the priviate user api for application
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_USER_API_H
|
||||
#define XS_USER_API_H
|
||||
|
||||
|
||||
// #include <xiuos.h>
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include "../../../kernel/include/xs_service.h"
|
||||
#include "../../../kernel/include/xs_base.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "../../../arch/kswitch.h"
|
||||
#include <libc.h>
|
||||
|
||||
|
||||
#ifdef SEPARATE_COMPILE
|
||||
|
||||
#define TASK_INFO 1
|
||||
#define MEM_INFO 2
|
||||
#define SEM_INFO 3
|
||||
#define EVENT_INFO 4
|
||||
#define MUTEX_INFO 5
|
||||
#define MEMPOOL_INFO 6
|
||||
#define MSGQUEUE_INFO 7
|
||||
#define DEVICE_INFO 8
|
||||
#define TIMER_INFO 9
|
||||
|
||||
int UserPrintInfo(unsigned long i);
|
||||
|
||||
struct utask
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
};
|
||||
typedef struct utask utask_x;
|
||||
|
||||
typedef void DIR;
|
||||
|
||||
int32_t UserTaskCreate(utask_x utask);
|
||||
|
||||
x_err_t UserTaskStartup(int32_t id);
|
||||
x_err_t UserTaskDelete(int32_t id);
|
||||
void UserTaskQuit(void);
|
||||
x_err_t UserTaskDelay(int32_t ms);
|
||||
x_err_t UserGetTaskName(int32_t id ,char *name);
|
||||
int32_t UserGetTaskID(void);
|
||||
uint8_t UserGetTaskStat(int32_t id);
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
x_err_t UserTaskCoreCombine(int32_t id,uint8_t core_id);
|
||||
x_err_t UserTaskCoreUnCombine(int32_t id);
|
||||
uint8_t UserGetTaskCombinedCore(int32_t id);
|
||||
uint8_t UserGetTaskRunningCore(int32_t id);
|
||||
#endif
|
||||
|
||||
x_err_t UserGetTaskErrorstatus(int32_t id);
|
||||
uint8_t UserGetTaskPriority(int32_t id);
|
||||
|
||||
|
||||
void *UserMalloc(size_t size);
|
||||
void *UserRealloc(void *pointer, size_t size);
|
||||
void *UserCalloc(size_t count, size_t size);
|
||||
void UserFree(void *pointer);
|
||||
|
||||
#ifdef KERNEL_MUTEX
|
||||
int32_t UserMutexCreate();
|
||||
void UserMutexDelete(int32_t mutex);
|
||||
int32_t UserMutexObtain(int32_t mutex, int32_t wait_time);
|
||||
int32_t UserMutexAbandon(int32_t mutex);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_SEMAPHORE
|
||||
typedef int32 sem_t;
|
||||
sem_t UserSemaphoreCreate(uint16_t val);
|
||||
x_err_t UserSemaphoreDelete(sem_t sem);
|
||||
x_err_t UserSemaphoreObtain(sem_t sem, int32_t wait_time);
|
||||
x_err_t UserSemaphoreAbandon(sem_t sem);
|
||||
x_err_t UserSemaphoreSetValue(sem_t sem, uint16_t val);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_EVENT
|
||||
typedef int32 EventIdType;
|
||||
EventIdType UserEventCreate(uint8_t flag);
|
||||
void UserEventDelete(EventIdType event);
|
||||
x_err_t UserEventTrigger(EventIdType event, uint32_t set);
|
||||
x_err_t UserEventProcess(EventIdType event, uint32_t set, uint8_t option,
|
||||
int32_t wait_time, uint32_t *Recved);
|
||||
x_err_t UserEventReinit(EventIdType event);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_MESSAGEQUEUE
|
||||
int32_t UserMsgQueueCreate(size_t msg_size, size_t max_msgs);
|
||||
x_err_t UserMsgQueueDelete(int32_t mq );
|
||||
x_err_t UserMsgQueueSendwait(int32_t mq, const void *buffer,
|
||||
size_t size, int32_t wait_time);
|
||||
x_err_t UserMsgQueueSend(int32_t mq, const void *buffer, size_t size);
|
||||
x_err_t UserMsgQueueUrgentSend(int32_t mq, const void *buffer, size_t size);
|
||||
x_err_t UserMsgQueueRecv(int32_t mq, void *buffer, size_t size,int32_t wait_time);
|
||||
x_err_t UserMsgQueueReinit(int32_t mq);
|
||||
#endif
|
||||
|
||||
int open(const char *path, int flags, ...);
|
||||
int read(int fd, void *buf, size_t len);
|
||||
int write(int fd, const void *buf, size_t len);
|
||||
int close(int fd);
|
||||
int ioctl(int fd, int cmd, void *args);
|
||||
off_t lseek(int fd, off_t offset, int whence);
|
||||
int rename(const char *from, const char *to);
|
||||
int unlink(const char *path);
|
||||
int stat(const char *path, struct stat *buf);
|
||||
int fstat(int fd, struct stat *buf);
|
||||
int fsync(int fd);
|
||||
int ftruncate(int fd, off_t length);
|
||||
|
||||
int mkdir(const char *path, mode_t mode);
|
||||
DIR *opendir(const char *path);
|
||||
int closedir(DIR *dirp);
|
||||
struct dirent *readdir(DIR *dirp);
|
||||
int rmdir(const char *path);
|
||||
int chdir(const char *path);
|
||||
char *getcwd(char *buf, size_t size);
|
||||
long telldir(DIR *dirp);
|
||||
void seekdir(DIR *dirp, off_t offset);
|
||||
void rewinddir(DIR *dirp);
|
||||
|
||||
#ifdef FS_VFS
|
||||
struct statfs {
|
||||
size_t f_bsize;
|
||||
size_t f_blocks;
|
||||
size_t f_bfree;
|
||||
};
|
||||
|
||||
int statfs(const char *path, struct statfs *buf);
|
||||
#endif
|
||||
|
||||
void Userprintf(const char *fmt, ...);
|
||||
|
||||
#define printf Userprintf
|
||||
|
||||
#else
|
||||
|
||||
#ifdef FS_VFS
|
||||
#include <iot-vfs_posix.h>
|
||||
#endif
|
||||
|
||||
struct utask
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
};
|
||||
typedef struct utask utask_x;
|
||||
int32_t UserTaskCreate(utask_x utask);
|
||||
|
||||
#define UserTaskStartup StartupKTask
|
||||
#define UserTaskDelete KTaskDelete
|
||||
#define UserTaskQuit KTaskQuit
|
||||
#define UserTaskDelay MdelayKTask
|
||||
|
||||
x_err_t UserGetTaskName(int32_t id ,char *name);
|
||||
int32_t UserGetTaskID(void);
|
||||
uint8_t UserGetTaskStat(int32_t id);
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
#define UserTaskCoreCombine KTaskCoreCombine
|
||||
#define UserTaskCoreUnCombine KTaskCoreUnCombine
|
||||
|
||||
uint8_t UserGetTaskCombinedCore(int32_t id);
|
||||
uint8_t UserGetTaskRunningCore(int32_t id);
|
||||
#endif
|
||||
|
||||
x_err_t UserGetTaskErrorstatus(int32_t id);
|
||||
uint8_t UserGetTaskPriority(int32_t id);
|
||||
|
||||
#define UserMalloc x_malloc
|
||||
#define UserRealloc x_realloc
|
||||
#define UserCalloc x_calloc
|
||||
#define UserFree x_free
|
||||
|
||||
#ifdef KERNEL_MUTEX
|
||||
#define UserMutexCreate KMutexCreate
|
||||
#define UserMutexDelete KMutexDelete
|
||||
#define UserMutexObtain KMutexObtain
|
||||
#define UserMutexAbandon KMutexAbandon
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_SEMAPHORE
|
||||
#define UserSemaphoreCreate KSemaphoreCreate
|
||||
#define UserSemaphoreDelete KSemaphoreDelete
|
||||
#define UserSemaphoreObtain KSemaphoreObtain
|
||||
#define UserSemaphoreAbandon KSemaphoreAbandon
|
||||
#define UserSemaphoreSetValue KSemaphoreSetValue
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_EVENT
|
||||
#define UserEventCreate KEventCreate
|
||||
#define UserEventDelete KEventDelete
|
||||
#define UserEventTrigger KEventTrigger
|
||||
#define UserEventProcess KEventProcess
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_MESSAGEQUEUE
|
||||
#define UserMsgQueueCreate KCreateMsgQueue
|
||||
#define UserMsgQueueDelete KDeleteMsgQueue
|
||||
#define UserMsgQueueSendwait KMsgQueueSendwait
|
||||
#define UserMsgQueueSend KMsgQueueSend
|
||||
#define UserMsgQueueUrgentSend KMsgQueueUrgentSend
|
||||
#define UserMsgQueueRecv KMsgQueueRecv
|
||||
#define UserMsgQueueReinit KMsgQueueReinit
|
||||
#endif
|
||||
|
||||
#define UserPrintf KPrintf
|
||||
#define printf KPrintf
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
50
kernel/include/xiuos.h
Normal file
50
kernel/include/xiuos.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xiuos.h
|
||||
* @brief: all header files of kernel
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XIUOS_H
|
||||
#define XIUOS_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_mutex.h>
|
||||
#include <xs_sem.h>
|
||||
#include <xs_event.h>
|
||||
#include <xs_msg.h>
|
||||
#include <xs_ktask.h>
|
||||
#include <xs_timer.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_isr.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <xs_memory.h>
|
||||
#include <xs_id.h>
|
||||
#include <xs_ktick.h>
|
||||
#include <xs_kdevice.h>
|
||||
#include <xs_init.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_banner.h>
|
||||
#include <xs_poll.h>
|
||||
#include <xs_workqueue.h>
|
||||
#include <xs_circular_area.h>
|
||||
#include <xs_dataqueue.h>
|
||||
|
||||
#endif
|
||||
138
kernel/include/xs_assign.h
Normal file
138
kernel/include/xs_assign.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_assign.h
|
||||
* @brief: function declaration and structure defintion of system assign
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_ASSIGN_H
|
||||
#define XS_ASSIGN_H
|
||||
|
||||
#include <xs_base.h>
|
||||
#include <xs_ktask.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_spinlock.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MERGE_FLAG(src, flag) *(src) |= flag
|
||||
#define CLEAR_FLAG(src, flag) *(src) &= ~flag
|
||||
|
||||
extern struct Assign Assign;
|
||||
|
||||
struct PriorityReadyVectorDone
|
||||
{
|
||||
void (*init)(struct OsAssignReadyVector *ready_vector);
|
||||
void (*insert)(struct TaskDescriptor *task);
|
||||
void (*remove)(struct TaskDescriptor *task);
|
||||
};
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
struct smp_assign_done
|
||||
{
|
||||
x_ubase (*GetHighest)(void);
|
||||
struct TaskDescriptor* (*select)(void);
|
||||
void (*SwitchToNew)(struct TaskDescriptor* old_task, struct TaskDescriptor* new_task);
|
||||
void (*SwitchToFirst)(struct TaskDescriptor* task);
|
||||
void (*SetSystemTask)(struct TaskDescriptor* task);
|
||||
void (*SmpInit)(void);
|
||||
};
|
||||
struct Assign
|
||||
{
|
||||
struct OsAssignReadyVector os_assign_read_vector;
|
||||
struct OsAssignReadyVector smp_os_assign_ready_rector[CPU_NUMBERS];
|
||||
struct TaskDescriptor *smp_os_running_task[CPU_NUMBERS];
|
||||
|
||||
struct PriorityReadyVectorDone *ready_vector_done;
|
||||
struct smp_assign_done *smp_assign_done;
|
||||
|
||||
uint8 current_priority[CPU_NUMBERS];
|
||||
uint16 assign_lock[CPU_NUMBERS];
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
#else
|
||||
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);
|
||||
#endif
|
||||
|
||||
void KTaskInsertToReadyVector(struct TaskDescriptor *task);
|
||||
int PrioCaculate(uint32 bitmap);
|
||||
void SysInitOsAssign(void);
|
||||
void ResetCriticalAreaLock(void );
|
||||
void StartupOsAssign(void);
|
||||
x_base CriticalAreaLock(void);
|
||||
void CriticalAreaUnLock(x_base lock);
|
||||
uint16 GetOsAssignLockLevel(void);
|
||||
int32 JudgeAssignReadyBitmapIsEmpty(struct OsAssignReadyVector *ready_vector);
|
||||
void OsAssignReadyVectorInit(struct OsAssignReadyVector *ready_vector);
|
||||
void AssignPolicyInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table);
|
||||
struct TaskDescriptor * ChooseTaskWithHighestPrio(struct OsAssignReadyVector *ready_vector);
|
||||
|
||||
#ifdef KERNEL_STACK_OVERFLOW_CHECK
|
||||
void _KTaskOsAssignStackCheck(struct TaskDescriptor *task);
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
extern HwSpinlock AssignSpinLock;
|
||||
#define DO_KTASK_ASSIGN \
|
||||
do \
|
||||
{ \
|
||||
NOT_IN_CRITICAL_AREA; \
|
||||
x_base lock; \
|
||||
lock = DISABLE_INTERRUPT(); \
|
||||
HwLockSpinlock(&AssignSpinLock); \
|
||||
KTaskOsAssign(); \
|
||||
HwUnlockSpinlock(&AssignSpinLock); \
|
||||
ENABLE_INTERRUPT(lock); \
|
||||
} while (0);
|
||||
|
||||
#else
|
||||
|
||||
#define DO_KTASK_ASSIGN \
|
||||
do \
|
||||
{ \
|
||||
NOT_IN_CRITICAL_AREA; \
|
||||
x_base lock; \
|
||||
lock = DISABLE_INTERRUPT(); \
|
||||
KTaskOsAssign(); \
|
||||
ENABLE_INTERRUPT(lock); \
|
||||
} while (0);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
66
kernel/include/xs_avltree.h
Normal file
66
kernel/include/xs_avltree.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_avltree.h
|
||||
* @brief: function declaration and structure defintion of avl tree
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AVL_TREE_H
|
||||
#define AVL_TREE_H
|
||||
|
||||
#include <xs_base.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef KERNEL_AVL_TREE
|
||||
struct AvlNode
|
||||
{
|
||||
int32 data;
|
||||
uint32 height;
|
||||
|
||||
struct AvlNode *left;
|
||||
struct AvlNode *right;
|
||||
};
|
||||
|
||||
typedef struct AvlNode *AvlNodeType;
|
||||
|
||||
#ifndef AVL_MAX
|
||||
#define AVL_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef AVL_ABS
|
||||
#define AVL_ABS(a) ((a > 0) ? (a) : (-a))
|
||||
#endif
|
||||
|
||||
/*This function will insert data to the avl tree*/
|
||||
AvlNodeType AvlTreeInsertNode(AvlNodeType avl_node, int32 data);
|
||||
|
||||
/*This function will delete data from the avl tree*/
|
||||
AvlNodeType AvlTreeDeleteNode(AvlNodeType avl_node, int32 data);
|
||||
|
||||
/*This function will modify certain data of the avl tree*/
|
||||
AvlNodeType AvlNodeModifyNode(AvlNodeType avl_node, int32 src_data, int32 dst_data);
|
||||
|
||||
/*This function will return the avl node which has the data*/
|
||||
AvlNodeType AvlNodeSearchNode(AvlNodeType avl_node, int32 data);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
29
kernel/include/xs_banner.h
Normal file
29
kernel/include/xs_banner.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_banner.h
|
||||
* @brief: function declaration of system banner
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_BANNER_H
|
||||
#define XS_BANNER_H
|
||||
|
||||
#include <xs_base.h>
|
||||
|
||||
void ShowBanner(void);
|
||||
|
||||
#endif
|
||||
133
kernel/include/xs_base.h
Normal file
133
kernel/include/xs_base.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_base.h
|
||||
* @brief: basic data type defintions
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_BASE_H
|
||||
#define XS_BASE_H
|
||||
|
||||
/* import board special configuration */
|
||||
#include <xsconfig.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
/* the basic types of date*/
|
||||
#ifdef ARCH_CPU_64BIT
|
||||
typedef unsigned long int size_t;
|
||||
typedef signed long int ssize_t;
|
||||
#else
|
||||
typedef unsigned int size_t;
|
||||
typedef signed int ssize_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CONFIG_ARCH_DATA_TYPE
|
||||
typedef signed char int8;
|
||||
typedef signed short int16;
|
||||
typedef signed int int32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
|
||||
#ifdef ARCH_CPU_64BIT
|
||||
typedef signed long int64;
|
||||
typedef unsigned long uint64;
|
||||
#else
|
||||
typedef signed long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef int x_bool;
|
||||
typedef long x_base;
|
||||
typedef unsigned long x_ubase;
|
||||
|
||||
typedef x_base x_err_t;
|
||||
typedef uint32 x_time_t;
|
||||
typedef uint32 x_ticks_t;
|
||||
typedef x_base x_flag_t;
|
||||
typedef x_ubase x_size_t;
|
||||
typedef x_ubase x_dev_t;
|
||||
typedef x_base x_OffPos;
|
||||
|
||||
#define RET_TRUE 1
|
||||
#define RET_FALSE 0
|
||||
|
||||
#define UINT8_SIZE_MAX 0xff
|
||||
#define UINT16_SIZE_MAX 0xffff
|
||||
#define UINT32_SIZE_MAX 0xffffffff
|
||||
#define TICK_SIZE_MAX UINT32_SIZE_MAX
|
||||
|
||||
|
||||
/* the type of components*/
|
||||
#define Cmpt_KindN_Null 0
|
||||
#define Cmpt_KindN_Task 1
|
||||
#define Cmpt_KindN_Semaphore 2
|
||||
#define Cmpt_KindN_Mutex 3
|
||||
#define Cmpt_KindN_Event 4
|
||||
#define Cmpt_KindN_MessageQueue 5
|
||||
#define Cmpt_KindN_MemPool 6
|
||||
#define Cmpt_KindN_Timer 7
|
||||
#define Cmpt_KindN_Bus 8
|
||||
#define Cmpt_KindN_Static 0x80
|
||||
|
||||
|
||||
/* the type of error */
|
||||
#define EOK 0
|
||||
#define ERROR 1
|
||||
#define ETIMEOUT 2
|
||||
#define EFULL 3
|
||||
#define EEMPTY 4
|
||||
#define ENOMEMORY 5
|
||||
#define ENONESYS 6
|
||||
#define EDEV_BUSY 7
|
||||
#define EPIO 8
|
||||
#define EINTER 9
|
||||
#define EINVALED 10
|
||||
#define INVALID_TASK_ERROR 11
|
||||
|
||||
|
||||
|
||||
#define ALIGN_MEN_UP(size, align) ((((size) + (align) - 1) /(align))*(align))
|
||||
#define ALIGN_MEN_DOWN(size, align) ((size)/(align)*(align))
|
||||
#define NONE (0)
|
||||
|
||||
#ifndef SECTION
|
||||
#if defined(__GNUC__)
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#else
|
||||
#define SECTION(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define WAITING_FOREVER -1
|
||||
|
||||
void KPrintf(const char *fmt, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
88
kernel/include/xs_circular_area.h
Normal file
88
kernel/include/xs_circular_area.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_circular_area.h
|
||||
* @brief: function declaration and structure defintion of circular area
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CIRCULAR_AREA_H
|
||||
#define CIRCULAR_AREA_H
|
||||
|
||||
#include <xs_base.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef KERNEL_CIRCULAR_AREA
|
||||
typedef struct CircularArea *CircularAreaType;
|
||||
|
||||
struct CircularAreaOps
|
||||
{
|
||||
uint32 (*read) (CircularAreaType circular_area, uint8 *output_buffer, uint32 data_length);
|
||||
uint32 (*write) (CircularAreaType circular_area, uint8 *input_buffer, uint32 data_length, x_bool b_force);
|
||||
void (*release) (CircularAreaType circular_area);
|
||||
void (*reset) (CircularAreaType circular_area);
|
||||
};
|
||||
|
||||
struct CircularArea
|
||||
{
|
||||
uint8 *data_buffer;
|
||||
|
||||
uint8 readidx;
|
||||
uint8 writeidx;
|
||||
|
||||
uint8 *p_head;
|
||||
uint8 *p_tail;
|
||||
|
||||
uint32 area_length;
|
||||
x_bool b_status;
|
||||
|
||||
struct CircularAreaOps *CircularAreaOperations;
|
||||
};
|
||||
|
||||
/*This function will return whether the circular_area is full or not*/
|
||||
x_bool CircularAreaIsFull(CircularAreaType circular_area);
|
||||
|
||||
/*This function will return whether the circular_area is empty or not*/
|
||||
x_bool CircularAreaIsEmpty(CircularAreaType circular_area);
|
||||
|
||||
/*This function will reset the circular_area and set the descriptor to default*/
|
||||
void CircularAreaReset(CircularAreaType circular_area);
|
||||
|
||||
/*This function will release the circular_area descriptor and free the memory*/
|
||||
void CircularAreaRelease(CircularAreaType circular_area);
|
||||
|
||||
/*This function will read data from the circular_area*/
|
||||
uint32 CircularAreaRead(CircularAreaType circular_area, uint8 *output_buffer, uint32 data_length);
|
||||
|
||||
/*This function will write data to the circular_area*/
|
||||
uint32 CircularAreaWrite(CircularAreaType circular_area, uint8 *input_buffer, uint32 data_length, x_bool b_force);
|
||||
|
||||
/*This function will get the circual_area max length*/
|
||||
uint32 CircularAreaGetMaxLength(CircularAreaType circular_area);
|
||||
|
||||
/*This function will get the data length of the circular_area*/
|
||||
uint32 CircularAreaGetDataLength(CircularAreaType circular_area);
|
||||
|
||||
/*This function will initialize the circular_area*/
|
||||
CircularAreaType CircularAreaInit(uint32 circular_area_length);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
69
kernel/include/xs_dataqueue.h
Normal file
69
kernel/include/xs_dataqueue.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_dataqueue.h
|
||||
* @brief: function declaration and structure defintion of circular area
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DATAQUEUE_H
|
||||
#define DATAQUEUE_H
|
||||
|
||||
#include <xs_ktask.h>
|
||||
#include <xs_timer.h>
|
||||
#include <xs_sem.h>
|
||||
#include <xs_queue_manager.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const void *data; ///< data pointer
|
||||
x_size_t length; ///< data length
|
||||
}DataElemType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 front;
|
||||
uint16 rear;
|
||||
uint16 max_len;
|
||||
DataElemType *base;
|
||||
|
||||
int sem_blank;
|
||||
int sem_data;
|
||||
}DataQueueType;
|
||||
|
||||
x_err_t InitDataqueue(DataQueueType *p_queue, uint16 NodeNumber);
|
||||
x_err_t PushDataqueue(DataQueueType *queue,const void *StartAddr, x_size_t DataSize, int32 timeout);
|
||||
x_err_t PopDataqueue(DataQueueType *queue, const void **StartAddr, x_size_t *size, int32 timeout);
|
||||
x_err_t DataqueuePeak(DataQueueType *queue, const void **StartAddr, x_size_t *size);
|
||||
void DeInitDataqueue(DataQueueType *p_queue);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
x_err_t (*InitDataqueue)(DataQueueType *p_queue, uint16 NodeNumber);
|
||||
x_err_t (*PushDataqueue)(DataQueueType *queue,
|
||||
const void *StartAddr,
|
||||
x_size_t DataSize,
|
||||
int32 timeout);
|
||||
x_err_t (*PopDataqueue)(DataQueueType *queue,
|
||||
const void **StartAddr,
|
||||
x_size_t *size,
|
||||
int32 timeout);
|
||||
x_err_t (*DataqueuePeak)(DataQueueType *queue,
|
||||
const void **StartAddr,
|
||||
x_size_t *size);
|
||||
void (*DeInitDataqueue)(DataQueueType *p_queue);
|
||||
} DataQueueDoneType;
|
||||
#endif
|
||||
45
kernel/include/xs_delay.h
Normal file
45
kernel/include/xs_delay.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_delay.h
|
||||
* @brief: function declaration and structure defintion of delay
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/11
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_DELAY_H
|
||||
#define XS_DELAY_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
|
||||
#define TASK_DELAY_INACTIVE 0
|
||||
#define TASK_DELAY_ACTIVE 1
|
||||
|
||||
struct Delay {
|
||||
struct TaskDescriptor *task;
|
||||
x_ticks_t ticks;
|
||||
uint8 status;
|
||||
DoubleLinklistType link;
|
||||
};
|
||||
typedef struct Delay *delay_t;
|
||||
|
||||
x_err_t KTaskSetDelay(struct TaskDescriptor *task, x_ticks_t ticks);
|
||||
x_err_t KTaskUnSetDelay(struct TaskDescriptor *task);
|
||||
void CheckTaskDelay(void);
|
||||
|
||||
#endif
|
||||
66
kernel/include/xs_event.h
Normal file
66
kernel/include/xs_event.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_event.h
|
||||
* @brief: function declaration and structure defintion of event
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_EVENT_H
|
||||
#define XS_EVENT_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_id.h>
|
||||
|
||||
#ifdef KERNEL_EVENT
|
||||
|
||||
#define EVENT_EVENTS_MASK 0x1FFFFFFF
|
||||
#define EVENT_OPTIONS_MASK 0x7
|
||||
|
||||
#define EVENT_AND (1 << 0)
|
||||
#define EVENT_OR (1 << 1)
|
||||
#define EVENT_AUTOCLEAN (1 << 2)
|
||||
|
||||
typedef int32 EventIdType;
|
||||
|
||||
struct Event
|
||||
{
|
||||
struct IdNode id;
|
||||
uint32 options : 3;
|
||||
uint32 events : 29;
|
||||
|
||||
DoubleLinklistType pend_list;
|
||||
DoubleLinklistType link;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32 (*EventCreate)(uint32 options);
|
||||
void (*EventDelete)(struct Event *event);
|
||||
int32 (*EventTrigger)(struct Event *event, uint32 events);
|
||||
int32 (*EventProcess)(struct Event *event, uint32 events, uint32 options, int32 msec, uint32 *processed);
|
||||
} EventDoneType;
|
||||
|
||||
int32 KEventCreate(uint32 options);
|
||||
void KEventDelete(int32 id);
|
||||
int32 KEventTrigger(int32 id, uint32 events);
|
||||
int32 KEventProcess(int32 id, uint32 events, uint32 options, int32 msec, uint32 *processed);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
103
kernel/include/xs_hook.h
Normal file
103
kernel/include/xs_hook.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_hook.h
|
||||
* @brief: function declaration and structure defintion of hook
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_HOOK_H
|
||||
#define XS_HOOK_H
|
||||
|
||||
#include <xs_base.h>
|
||||
#include <xs_ktask.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_memory.h>
|
||||
|
||||
#ifdef KERNEL_HOOK
|
||||
#define HOOK(function, argv) \
|
||||
do { if ((function) != NONE) function argv; } while (0)
|
||||
#else
|
||||
#define HOOK(function, argv)
|
||||
#endif
|
||||
|
||||
#define REGISTER_HOOK(hook, function) \
|
||||
{ if ((function) != NONE) hook = function ; }
|
||||
|
||||
#define UNREGISTER_HOOK(hook) \
|
||||
{ hook = NONE ; }
|
||||
|
||||
struct AssignHook
|
||||
{
|
||||
void (*hook_Assign)(KTaskDescriptorType from, KTaskDescriptorType to);
|
||||
};
|
||||
|
||||
struct TaskHook
|
||||
{
|
||||
void (*hook_TaskCreate) (KTaskDescriptorType task);
|
||||
void (*hook_TaskSuspend)(KTaskDescriptorType task);
|
||||
void (*hook_TaskResume) (KTaskDescriptorType task);
|
||||
|
||||
};
|
||||
|
||||
struct MemHook
|
||||
{
|
||||
void (*hook_Malloc)(void *ptr, x_size_t size);
|
||||
void (*hook_Free)(void *ptr);
|
||||
#ifdef KERNEL_MEMBLOCK
|
||||
void (*hook_GmAlloc)(struct MemGather *gm, void *date_ptr);
|
||||
void (*hook_GmFree)(struct MemGather *gm, void *date_ptr);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct TimerHook
|
||||
{
|
||||
void (*hook_TimerEnter)(struct Timer *timer);
|
||||
void (*hook_TimerExit)(struct Timer *timer);
|
||||
};
|
||||
|
||||
struct IsrHook
|
||||
{
|
||||
void (*hook_IsrEnter)(void);
|
||||
void (*hook_IsrLeave)(void);
|
||||
};
|
||||
|
||||
struct IdleHook
|
||||
{
|
||||
void (*hook_Idle)(void);
|
||||
};
|
||||
|
||||
struct TestHook
|
||||
{
|
||||
void (*hook_test)(const char *buf);
|
||||
};
|
||||
|
||||
struct KernelHook
|
||||
{
|
||||
struct AssignHook assign;
|
||||
struct TaskHook task;
|
||||
struct MemHook mem;
|
||||
struct TimerHook timer;
|
||||
struct IsrHook isr;
|
||||
struct IdleHook idle;
|
||||
struct TestHook test;
|
||||
|
||||
};
|
||||
extern struct KernelHook hook;
|
||||
|
||||
int hook_init(void);
|
||||
|
||||
#endif
|
||||
66
kernel/include/xs_id.h
Normal file
66
kernel/include/xs_id.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_id.h
|
||||
* @brief: function declaration and structure defintion of id manager
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_ID_H
|
||||
#define XS_ID_H
|
||||
|
||||
#include <xs_klist.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct IdNode
|
||||
{
|
||||
uint16 id;
|
||||
DoubleLinklistType link;
|
||||
};
|
||||
|
||||
struct IdManager
|
||||
{
|
||||
uint16 id_max;
|
||||
uint16 hoffset;
|
||||
|
||||
uint8 *id_map;
|
||||
DoubleLinklistType *htable;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define DECLARE_ID_MANAGER(_name, _id_max) \
|
||||
uint8 __id_map_##_name[((_id_max) + 7) / 8]; \
|
||||
DoubleLinklistType __htable_##_name[(_id_max) < ID_HTABLE_SIZE ? (_id_max) : ID_HTABLE_SIZE]; \
|
||||
struct IdManager _name = { \
|
||||
.id_max = _id_max, \
|
||||
.hoffset = (_id_max) < ID_HTABLE_SIZE ? (_id_max) : ID_HTABLE_SIZE, \
|
||||
.id_map = __id_map_##_name, \
|
||||
.htable = __htable_##_name \
|
||||
};
|
||||
|
||||
int IdInsertObj(struct IdManager *manager, struct IdNode *idnode);
|
||||
struct IdNode *IdGetObj(struct IdManager *manager, uint16 id);
|
||||
void IdRemoveObj(struct IdManager *manager, uint16 id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
53
kernel/include/xs_init.h
Normal file
53
kernel/include/xs_init.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_init.h
|
||||
* @brief: init function declaration of components
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_INIT_H
|
||||
#define XS_INIT_H
|
||||
|
||||
typedef int (*InitFnType)(void);
|
||||
struct InitSequenceDesc
|
||||
{
|
||||
const char* fn_name;
|
||||
const InitFnType fn;
|
||||
};
|
||||
|
||||
#ifdef KERNEL_COMPONENTS_INIT
|
||||
void InitCmpts(void);
|
||||
#endif
|
||||
|
||||
|
||||
extern int VfsInit(void);
|
||||
extern int WorkSysWorkQueueInit(void);
|
||||
extern int FlashW25qxxSpiDeviceInit(void);
|
||||
extern int sal_mbedtls_proto_init(void);
|
||||
extern int FatfsInit(void);
|
||||
extern int Ch376fsInit(void);
|
||||
extern int LibcSystemInit(void);
|
||||
extern int sal_init(void);
|
||||
extern int RtcNtpSyncInit(void);
|
||||
extern int MountSDCard(void);
|
||||
extern int dfs_mount_table(void);
|
||||
extern int userShellInit(void);
|
||||
extern int stm32_sdcard_mount(void);
|
||||
extern int STM32USBHostRegister(void);
|
||||
extern int WorkSysWorkQueueInit(void);
|
||||
|
||||
#endif
|
||||
63
kernel/include/xs_isolation.h
Normal file
63
kernel/include/xs_isolation.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_isolation.h
|
||||
* @brief: The macro and callback functions definitions for memory protect
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/14
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MEMORY_PROTECT_H
|
||||
#define MEMORY_PROTECT_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
#include <xiuos.h>
|
||||
#include <board.h>
|
||||
|
||||
#if defined(ARCH_ARM) && defined(SURPORT_MPU)
|
||||
#include <mpu.h>
|
||||
extern struct Mpu *isolation ;
|
||||
#define MOMERY_PROTECT_ENABLE
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_RISCV) && defined(SURPORT_PMP)
|
||||
#include <pmp.h>
|
||||
extern struct Pmp *isolation ;
|
||||
#define MOMERY_PROTECT_ENABLE
|
||||
#endif
|
||||
|
||||
#define REGION_TYPE_CODE (1)
|
||||
#define REGION_TYPE_DATA (2)
|
||||
#define REGION_TYPE_BSS (3)
|
||||
#define REGION_TYPE_HEAP (4)
|
||||
|
||||
struct MemoryAccessLimit {
|
||||
void (* Enable)( uint32_t option);
|
||||
void (* Disable)(void);
|
||||
x_err_t (* Init)(void **mem_access);
|
||||
x_err_t (* InitIsolation)(void **mem_access, x_ubase stack_start , size_t stack_size);
|
||||
x_err_t (* AddRegion)(void *mem_access, x_ubase start , size_t size , uint8_t region_type );
|
||||
x_err_t (* ClearRegion)(void *mem_access, x_ubase addr);
|
||||
void (* Load)(void *mem_access);
|
||||
void (* Free)(void *mem_access);
|
||||
x_bool (* FaultHandle)(void *mem_access, x_ubase addr);
|
||||
};
|
||||
|
||||
extern struct MemoryAccessLimit mem_access ;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
98
kernel/include/xs_isr.h
Normal file
98
kernel/include/xs_isr.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_isr.h
|
||||
* @brief: function declaration and structure defintion of isr
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_ISR_H
|
||||
#define XS_ISR_H
|
||||
|
||||
#include <xs_base.h>
|
||||
#include <arch_interrupt.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define DECLARE_HW_IRQ(_irq_num, _handler, _arg) \
|
||||
const uint32 __irq_desc_idx_##_handler SECTION(".isrtbl.idx") = _irq_num + ARCH_IRQ_NUM_OFFSET ; \
|
||||
const struct IrqDesc __irq_desc_##_handler SECTION(".isrtbl") = { \
|
||||
.handler = _handler, \
|
||||
.param = _arg, \
|
||||
}
|
||||
|
||||
typedef void (*IsrHandlerType)(int vector, void *param);
|
||||
|
||||
struct IrqDesc
|
||||
{
|
||||
IsrHandlerType handler;
|
||||
void *param;
|
||||
|
||||
#ifdef CONFIG_INTERRUPT_INFO
|
||||
char name[NAME_NUM_MAX];
|
||||
uint32 counter;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct IsrDone
|
||||
{
|
||||
x_bool (*isInIsr)();
|
||||
int32 (*registerIrq)(uint32 irq_num, IsrHandlerType handler, void *arg);
|
||||
int32 (*freeIrq)(uint32 irq_num);
|
||||
int32 (*enableIrq)(uint32 irq_num);
|
||||
int32 (*disableIrq)(uint32 irq_num);
|
||||
void (*handleIrq)(uint32 irq_num);
|
||||
uint16 (*getCounter)() ;
|
||||
void (*incCounter)();
|
||||
void (*decCounter)();
|
||||
uint8 (*getSwitchTrigerFlag)();
|
||||
void (*setSwitchTrigerFlag)();
|
||||
void (*clearSwitchTrigerFlag)();
|
||||
};
|
||||
|
||||
struct InterruptServiceRoutines {
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
volatile uint16 isr_count[CPU_NUMBERS];
|
||||
volatile uint8 isr_switch_trigger_flag[CPU_NUMBERS];
|
||||
#else
|
||||
volatile uint16 isr_count ;
|
||||
volatile uint8 isr_switch_trigger_flag;
|
||||
#endif
|
||||
struct IrqDesc irq_table[ARCH_MAX_IRQ_NUM];
|
||||
struct IsrDone *done;
|
||||
};
|
||||
|
||||
extern struct InterruptServiceRoutines isrManager ;
|
||||
|
||||
x_base DisableLocalInterrupt();
|
||||
void EnableLocalInterrupt(x_base level);
|
||||
|
||||
#define DISABLE_INTERRUPT DisableLocalInterrupt
|
||||
#define ENABLE_INTERRUPT EnableLocalInterrupt
|
||||
|
||||
void SysInitIsrManager();
|
||||
void InitHwinterrupt(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
162
kernel/include/xs_kdbg.h
Normal file
162
kernel/include/xs_kdbg.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_kdbg.h
|
||||
* @brief: function declaration and structure defintion of kernel debug
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_KDBG_H
|
||||
#define XS_KDBG_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_DEBUG
|
||||
|
||||
/*Kernel Section Debug Define*/
|
||||
#define KDBG_MEM 0
|
||||
#define KDBG_MEMHEAP 0
|
||||
#define KDBG_SCHED 0
|
||||
#define KDBG_KTASK 0
|
||||
#define KDBG_SOFTTIMER 0
|
||||
#define KDBG_IRQ 0
|
||||
#define KDBG_IPC 0
|
||||
#define KDBG_HOOK 0
|
||||
|
||||
#define SYS_KDEBUG_LOG(section, information) \
|
||||
do \
|
||||
{ \
|
||||
if(section) { \
|
||||
KPrintf information; \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
#define KDYN_NONE 0
|
||||
#define KDYN_DBG 1
|
||||
#define KDYN_ERROR 2
|
||||
#define KDYN_WARNING 3
|
||||
|
||||
#ifdef KDYN_LOG_DBG
|
||||
#define DBG(args, ...) KDYNAMIC_LOG(KDYN_DBG, args, ##__VA_ARGS__)
|
||||
#define SYS_ERR(args, ...) KDYNAMIC_LOG(KDYN_ERROR, args, ##__VA_ARGS__)
|
||||
#define SYS_WARN(args, ...) KDYNAMIC_LOG(KDYN_WARNING, args, ##__VA_ARGS__)
|
||||
#else
|
||||
#define DBG(args, ...) KDYNAMIC_LOG(KDYN_NONE, args, ##__VA_ARGS__)
|
||||
#define SYS_ERR(args, ...) KDYNAMIC_LOG(KDYN_ERROR, args, ##__VA_ARGS__)
|
||||
#define SYS_WARN(args, ...) KDYNAMIC_LOG(KDYN_WARNING, args, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define KDYNAMIC_LOG(level, args, ...) \
|
||||
do \
|
||||
{ \
|
||||
switch(level) \
|
||||
{ \
|
||||
case KDYN_NONE: \
|
||||
break; \
|
||||
case KDYN_DBG: \
|
||||
KPrintf("[DBG]"); \
|
||||
KPrintf(args, ##__VA_ARGS__); \
|
||||
break; \
|
||||
case KDYN_ERROR: \
|
||||
KPrintf("[ERR]"); \
|
||||
KPrintf(args, ##__VA_ARGS__); \
|
||||
break; \
|
||||
case KDYN_WARNING: \
|
||||
KPrintf("[WARN]"); \
|
||||
KPrintf(args, ##__VA_ARGS__); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
#define NULL_PARAM_CHECK(param) \
|
||||
do \
|
||||
{ \
|
||||
if(param == NONE) { \
|
||||
KPrintf("PARAM CHECK FAILED ...%s %d %s is NULL.\n",__FUNCTION__,__LINE__,#param); \
|
||||
while(RET_TRUE); \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
#define CHECK(TRUE_CONDITION) \
|
||||
do \
|
||||
{ \
|
||||
if(!(TRUE_CONDITION)) { \
|
||||
KPrintf("%s CHECK condition is false at line[%d] of [%s] func.\n",#TRUE_CONDITION,__LINE__,__FUNCTION__);\
|
||||
while(RET_TRUE); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define KDEBUG_NOT_IN_INTERRUPT \
|
||||
do \
|
||||
{ \
|
||||
x_base level; \
|
||||
level = DISABLE_INTERRUPT(); \
|
||||
if (isrManager.done->getCounter() != 0) \
|
||||
{ \
|
||||
KPrintf("Function[%s] is not supported in ISR\n", __FUNCTION__); \
|
||||
CHECK(0); \
|
||||
} \
|
||||
ENABLE_INTERRUPT(level); \
|
||||
} while (0)
|
||||
|
||||
#define KDEBUG_IN_KTASK_CONTEXT \
|
||||
do \
|
||||
{ \
|
||||
x_base level; \
|
||||
level = DISABLE_INTERRUPT(); \
|
||||
if (GetKTaskDescriptor() == NONE) \
|
||||
{ \
|
||||
KPrintf("Function[%s] is not supported before task assign\n", __FUNCTION__); \
|
||||
CHECK(0); \
|
||||
} \
|
||||
KDEBUG_NOT_IN_INTERRUPT; \
|
||||
ENABLE_INTERRUPT(level); \
|
||||
} while (0)
|
||||
|
||||
#define NOT_IN_CRITICAL_AREA \
|
||||
do { \
|
||||
if(GetOsAssignLockLevel() != 0){ \
|
||||
KPrintf("Function[%s] is not supported switch in critical area.\n", __FUNCTION__); \
|
||||
CHECK(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define SYS_KDEBUG_LOG(section, information)
|
||||
#define DBG(args, ...)
|
||||
#define SYS_ERR(args, ...)
|
||||
#define SYS_WARN(args, ...)
|
||||
#define NULL_PARAM_CHECK(param)
|
||||
#define CHECK(TRUE_CONDITION)
|
||||
#define KDEBUG_NOT_IN_INTERRUPT
|
||||
#define KDEBUG_IN_KTASK_CONTEXT
|
||||
#define NOT_IN_CRITICAL_AREA
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
119
kernel/include/xs_kdevice.h
Normal file
119
kernel/include/xs_kdevice.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_kdevice.h
|
||||
* @brief: macor and structure defintion of kdevice
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_KDEVICE_H
|
||||
#define XS_KDEVICE_H
|
||||
|
||||
/* import board special configuration */
|
||||
#include <xsconfig.h>
|
||||
#include <xs_klist.h>
|
||||
|
||||
#ifdef TOOL_SHELL
|
||||
#include "shell.h"
|
||||
#else
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum dev
|
||||
{
|
||||
Dev_TYPE_Block,
|
||||
Dev_TYPE_Char ,
|
||||
Dev_TYPE_CAN ,
|
||||
Dev_TYPE_Graphic,
|
||||
Dev_TYPE_I2CBUS,
|
||||
Dev_TYPE_Miscellaneous,
|
||||
Dev_TYPE_NetIf ,
|
||||
Dev_TYPE_RTC ,
|
||||
Dev_TYPE_SPIBUS,
|
||||
Dev_TYPE_SPIDevice,
|
||||
Dev_TYPE_Timer,
|
||||
Dev_TYPE_Touch,
|
||||
Dev_TYPE_USBDevice,
|
||||
Dev_TYPE_USBHost,
|
||||
Dev_TYPE_Unknown
|
||||
};
|
||||
|
||||
#define OSIGN_OPER_CLOSE (0U << 0)
|
||||
#define OSIGN_OPER_RDONLY (1U << 0)
|
||||
#define OSIGN_OPER_WRONLY (1U << 1)
|
||||
#define OSIGN_OPER_RDWR (OSIGN_OPER_WRONLY| OSIGN_OPER_RDONLY )
|
||||
#define OSIGN_OPER_OPEN (1U << 3)
|
||||
#define OSIGN_OPER_MASK 0xf0f
|
||||
|
||||
#define SIGN_OPER_DEACTIVATE (0U << 0)
|
||||
#define SIGN_OPER_RDONLY (1U << 0)
|
||||
#define SIGN_OPER_WRONLY (1U << 1)
|
||||
#define SIGN_OPER_RDWR (SIGN_OPER_RDONLY|SIGN_OPER_WRONLY)
|
||||
#define SIGN_OPER_REMOVABLE (1U << 2)
|
||||
#define SIGN_OPER_STANDALONE (1U << 3)
|
||||
#define SIGN_OPER_ACTIVATED (1U << 4)
|
||||
#define SIGN_OPER_SUSPENDED (1U << 5)
|
||||
#define SIGN_OPER_STREAM (1U << 6)
|
||||
#define SIGN_OPER_INT_RX (1U << 8)
|
||||
#define SIGN_OPER_DMA_RX (1U << 9)
|
||||
#define SIGN_OPER_INT_TX (1U << 10)
|
||||
#define SIGN_OPER_DMA_TX (1U << 11)
|
||||
|
||||
enum SIGN_OPER
|
||||
{
|
||||
OPER_RESUME = 0x01,
|
||||
OPER_SUSPEND = 0x02,
|
||||
OPER_CONFIG = 0x03,
|
||||
OPER_SET_INT = 0x10,
|
||||
OPER_CLR_INT = 0x11,
|
||||
OPER_GET_INT = 0x12,
|
||||
OPER_CHAR_STREAM = 0x10,
|
||||
OPER_BLK_GETGEOME = 0x10,
|
||||
OPER_BLK_SYNC = 0x11,
|
||||
OPER_BLK_ERASE = 0x12,
|
||||
OPER_BLK_AUTOREFRESH = 0x13,
|
||||
OPER_NETIF_GETMAC = 0x10,
|
||||
OPER_MTD_FORMAT = 0x10,
|
||||
OPER_RTC_GET_TIME = 0x10,
|
||||
OPER_RTC_SET_TIME = 0x11,
|
||||
OPER_RTC_GET_ALARM = 0x12,
|
||||
OPER_RTC_SET_ALARM = 0x13,
|
||||
};
|
||||
|
||||
struct DeviceBlockArrange
|
||||
{
|
||||
uint32 bank_num;
|
||||
uint32 size_perbank;
|
||||
uint32 block_size;
|
||||
uint16 bank_start;
|
||||
uint16 bank_end;
|
||||
};
|
||||
|
||||
struct DeviceBlockAddr
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
129
kernel/include/xs_klist.h
Normal file
129
kernel/include/xs_klist.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_klist.h
|
||||
* @brief: function declaration and structure defintion of linklist
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/2
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_KLIST_H
|
||||
#define XS_KLIST_H
|
||||
|
||||
#include <xs_base.h>
|
||||
#include "libc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LINKLIST_FLAG_FIFO 0x00
|
||||
#define LINKLIST_FLAG_PRIO 0x01
|
||||
|
||||
typedef struct SysDoubleLinklistNode
|
||||
{
|
||||
struct SysDoubleLinklistNode *node_next;
|
||||
struct SysDoubleLinklistNode *node_prev;
|
||||
} DoubleLinklistType;
|
||||
|
||||
// Single List
|
||||
typedef struct SingleLinklistNode
|
||||
{
|
||||
struct SingleLinklistNode *node_next;
|
||||
} SysSingleLinklistType;
|
||||
|
||||
|
||||
struct CommonMember
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
uint8 type;
|
||||
uint8 flag;
|
||||
DoubleLinklistType list;
|
||||
};
|
||||
|
||||
#define CONTAINER_OF(item, type, member) \
|
||||
((type *)((char *)(item) - (unsigned long)(&((type *)0)->member)))
|
||||
|
||||
|
||||
#define DOUBLE_LINKLIST_OBJ_INIT(obj) { &(obj), &(obj) }
|
||||
|
||||
void InitDoubleLinkList(DoubleLinklistType *linklist_head);
|
||||
void DoubleLinkListInsertNodeAfter(DoubleLinklistType *linklist, DoubleLinklistType *linklist_node);
|
||||
void DoubleLinkListInsertNodeBefore(DoubleLinklistType *linklist, DoubleLinklistType *linklist_node);
|
||||
void DoubleLinkListRmNode(DoubleLinklistType *linklist_node);
|
||||
int IsDoubleLinkListEmpty(const DoubleLinklistType *linklist);
|
||||
struct SysDoubleLinklistNode *DoubleLinkListGetHead(const DoubleLinklistType *linklist);
|
||||
struct SysDoubleLinklistNode *DoubleLinkListGetNext(const DoubleLinklistType *linklist,
|
||||
const struct SysDoubleLinklistNode *linklist_node);
|
||||
unsigned int DoubleLinkListLenGet(const DoubleLinklistType *linklist);
|
||||
|
||||
#define SYS_DOUBLE_LINKLIST_ENTRY(item, type, member) \
|
||||
CONTAINER_OF(item, type, member)
|
||||
|
||||
#define DOUBLE_LINKLIST_FOR_EACH(item, head) \
|
||||
for (item = (head)->node_next; item != (head); item = item->node_next)
|
||||
|
||||
#define DOUBLE_LINKLIST_FOR_EACH_SAFE(item, node_next, head) \
|
||||
for (item = (head)->node_next, node_next = item->node_next; item != (head); \
|
||||
item = node_next, node_next = item->node_next)
|
||||
|
||||
#define DOUBLE_LINKLIST_FOR_EACH_ENTRY(item, head, member) \
|
||||
for (item = SYS_DOUBLE_LINKLIST_ENTRY((head)->node_next, typeof(*item), member); \
|
||||
&item->member != (head); \
|
||||
item = SYS_DOUBLE_LINKLIST_ENTRY(item->member.node_next, typeof(*item), member))
|
||||
|
||||
#define DOUBLE_LINKLIST_FOR_EACH_ENTRY_SAFE(item, node_next, head, member) \
|
||||
for (item = SYS_DOUBLE_LINKLIST_ENTRY((head)->node_next, typeof(*item), member), \
|
||||
node_next = SYS_DOUBLE_LINKLIST_ENTRY(item->member.node_next, typeof(*item), member); \
|
||||
&item->member != (head); \
|
||||
item = node_next, node_next = SYS_DOUBLE_LINKLIST_ENTRY(node_next->member.node_next, typeof(*node_next), member))
|
||||
|
||||
#define DOUBLE_LINKLIST_FIRST_ENTRY(ptr, type, member) \
|
||||
SYS_DOUBLE_LINKLIST_ENTRY((ptr)->node_next, type, member)
|
||||
|
||||
#define SYS_SINGLE_LINKLIST_OBJ_INIT(obj) { NONE }
|
||||
|
||||
void InitSingleLinkList(SysSingleLinklistType *linklist);
|
||||
void AppendSingleLinkList(SysSingleLinklistType *linklist, SysSingleLinklistType *linklist_node);
|
||||
void SingleLinkListNodeInsert(SysSingleLinklistType *linklist, SysSingleLinklistType *linklist_node);
|
||||
unsigned int SingleLinkListGetLen(const SysSingleLinklistType *linklist);
|
||||
SysSingleLinklistType *SingleLinkListRmNode(SysSingleLinklistType *linklist, SysSingleLinklistType *linklist_node);
|
||||
SysSingleLinklistType *SingleLinkListGetFirstNode(SysSingleLinklistType *linklist);
|
||||
SysSingleLinklistType *SingleLinkListGetTailNode(SysSingleLinklistType *linklist);
|
||||
SysSingleLinklistType *SingleLinkListGetNextNode(SysSingleLinklistType *linklist_node);
|
||||
int IsSingleLinkListEmpty(SysSingleLinklistType *linklist);
|
||||
|
||||
#define SYS_SINGLE_LINKLIST_ENTRY(node, type, member) \
|
||||
CONTAINER_OF(node, type, member)
|
||||
|
||||
#define SINGLE_LINKLIST_FOR_EACH(item, head) \
|
||||
for (item = (head)->node_next; item != NONE; item = item->node_next)
|
||||
|
||||
#define SINGLE_LINKLIST_FOR_EACH_ENTRY(item, head, member) \
|
||||
for (item = SYS_SINGLE_LINKLIST_ENTRY((head)->node_next, typeof(*item), member); \
|
||||
&item->member != (NONE); \
|
||||
item = SYS_SINGLE_LINKLIST_ENTRY(item->member.node_next, typeof(*item), member))
|
||||
|
||||
#define SINGLE_LINKLIST_FIRST_ENTRY(ptr, type, member) \
|
||||
SYS_SINGLE_LINKLIST_ENTRY((ptr)->node_next, type, member)
|
||||
|
||||
#define SINGLE_LINKLIST_TAIL_ENTRY(ptr, type, member) \
|
||||
SYS_SINGLE_LINKLIST_ENTRY(SingleLinkListGetTailNode(ptr), type, member)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
222
kernel/include/xs_ktask.h
Normal file
222
kernel/include/xs_ktask.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_ktask.h
|
||||
* @brief: function declaration and structure defintion of kernel task
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_KTASK_H
|
||||
#define XS_KTASK_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_timer.h>
|
||||
#include <xs_delay.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define KTASK_LOWEST_PRIORITY 0
|
||||
#define KTASK_INIT 0x00
|
||||
#define KTASK_READY 0x01
|
||||
#define KTASK_SUSPEND 0x02
|
||||
#define KTASK_RUNNING 0x03
|
||||
#define KTASK_CLOSE 0x04
|
||||
#define KTASK_STAT_MASK 0x07
|
||||
|
||||
#define KTASK_MAX_ADVANCE_PROCESS_TIME 0x1 ///< task max advance process times
|
||||
#define UNCOMBINE_CPU_CORE CPU_NUMBERS
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
|
||||
#define CPU_MASK ((1 << CPU_NUMBERS) - 1) /**< All CPUs mask bit. */
|
||||
|
||||
#ifndef ASSIGN_IPI
|
||||
#define ASSIGN_IPI 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct 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;
|
||||
|
||||
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;
|
||||
uint32_t exc_return;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
DoubleLinklistType sched_link; ///< task sched list
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
uint8 bitmap_offset;
|
||||
uint8 bitmap_row;
|
||||
#endif
|
||||
uint32 bitmap_column;
|
||||
delay_t delay;
|
||||
};
|
||||
typedef struct TaskDyncSchedMember TaskDyncSchedMembeType;
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
struct TaskSmpInfo {
|
||||
uint8 combined_coreid; ///< task bind core id
|
||||
uint8 runing_coreid; ///< task running core id
|
||||
uint16 critical_lock_cnt; ///< critical lock count
|
||||
};
|
||||
typedef struct TaskSmpInfo TaskSmpInfoType;
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct KTaskDone
|
||||
{
|
||||
int32 (*init)(KTaskDescriptorType task,
|
||||
const char *name,
|
||||
void (*entry)(void *parameter),
|
||||
void *parameter,
|
||||
uint32 stack_size,
|
||||
uint8 priority);
|
||||
|
||||
x_err_t (*start)(KTaskDescriptorType task);
|
||||
x_err_t (*Delete)(KTaskDescriptorType task);
|
||||
x_err_t (*delay)(KTaskDescriptorType task, x_ticks_t ticks);
|
||||
x_err_t (*mdelay)(KTaskDescriptorType task,uint32 ms);
|
||||
x_err_t (*prioset)(KTaskDescriptorType task, uint8 prio);
|
||||
#ifdef ARCH_SMP
|
||||
x_err_t (*combine)(KTaskDescriptorType task, uint8 coreid);
|
||||
x_err_t (*uncombine)(KTaskDescriptorType task);
|
||||
#endif
|
||||
x_err_t (*suspend)(KTaskDescriptorType task);
|
||||
x_err_t (*wake)(KTaskDescriptorType task);
|
||||
};
|
||||
int32 KTaskCreate(const char *name,
|
||||
|
||||
void (*entry)(void *parameter),
|
||||
void *parameter,
|
||||
uint32 stack_size,
|
||||
uint8 priority);
|
||||
void KTaskQuit(void);
|
||||
|
||||
#ifdef SEPARATE_COMPILE
|
||||
int32 UTaskCreate(const char *name,
|
||||
void (*entry)(void *parameter),
|
||||
void *parameter,
|
||||
uint32 stack_size,
|
||||
uint8 priority);
|
||||
|
||||
#endif
|
||||
|
||||
void KUpdateExstatus(x_err_t no);
|
||||
int *KObtainExstatus(void);
|
||||
#if !defined(LIB_NEWLIB) && !defined(_WIN32)
|
||||
#ifndef errno
|
||||
#define errno *KObtainExstatus()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
KTaskDescriptorType GetKTaskDescriptor(void);
|
||||
KTaskDescriptorType KTaskSearch(char *name);
|
||||
x_err_t StartupKTask(int32 id);
|
||||
x_err_t KTaskDelete(int32 id);
|
||||
x_err_t YieldOsAssign(void);
|
||||
x_err_t DelayKTask(x_ticks_t tick);
|
||||
x_err_t MdelayKTask(uint32 ms);
|
||||
x_err_t KTaskPrioSet(int32 id, uint8 prio);
|
||||
x_err_t KTaskCoreCombine(int32 id, uint8 coreid);
|
||||
x_err_t KTaskCoreUnCombine(int32 id);
|
||||
x_err_t SuspendKTask(int32 id);
|
||||
x_err_t KTaskWakeup(int32 id);
|
||||
void KTaskTimeout(void *parameter);
|
||||
void InitIdleKTask(void);
|
||||
void IdleKTaskExec(void);
|
||||
KTaskDescriptorType GetIdleKTaskDescripter(void);
|
||||
void KTaskOsAssign(void);
|
||||
void KTaskOsAssignRemoveKTask(struct TaskDescriptor *task);
|
||||
|
||||
#if defined (SCHED_POLICY_FIFO)
|
||||
void FifoTaskTimesliceInit(struct TaskDescriptor *task);
|
||||
void FifoReadyVectorInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table);
|
||||
void FifoTaskTimesliceUpdate();
|
||||
#elif defined (SCHED_POLICY_RR)
|
||||
void RoundRobinTaskTimesliceInit(struct TaskDescriptor *task);
|
||||
void RoundRobinReadyVectorInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table);
|
||||
void RoundRobinTaskTimesliceUpdate(struct TaskDescriptor *task);
|
||||
#elif defined (SCHED_POLICY_RR_REMAINSLICE)
|
||||
void RoundRobinRemainTaskTimesliceInit(struct TaskDescriptor *task);
|
||||
void RoundRobinRemainReadyVectorInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table);
|
||||
void RoundRobinRemainTaskTimesliceUpdate(struct TaskDescriptor *task);
|
||||
#endif
|
||||
|
||||
x_err_t LinklistSuspend(DoubleLinklistType *list,struct TaskDescriptor *task,uint8 flag);
|
||||
x_err_t LinklistResume(DoubleLinklistType *list);
|
||||
x_err_t LinklistResumeAll(DoubleLinklistType *list);
|
||||
void HwSendIpi(int ipi_vector, unsigned int cpu_mask);
|
||||
void KTaskIdDelete(int32 id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
44
kernel/include/xs_ktask_stat.h
Normal file
44
kernel/include/xs_ktask_stat.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_ktask_stat.h
|
||||
* @brief: function declaration of task stat
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_KTASK_STAT_H
|
||||
#define XS_KTASK_STAT_H
|
||||
|
||||
#include <xs_base.h>
|
||||
#include<xs_ktask.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void KTaskStateSet(KTaskDescriptorType task, uint8 stat);
|
||||
void KTaskStatSetAsInit(KTaskDescriptorType task);
|
||||
void KTaskStatSetAsReady(KTaskDescriptorType task);
|
||||
void KTaskStatSetAsSuspend(KTaskDescriptorType task);
|
||||
void KTaskStatSetAsRunning(KTaskDescriptorType task);
|
||||
void KTaskStatSetAsClose(KTaskDescriptorType task);
|
||||
uint8 KTaskStatGet(KTaskDescriptorType task);
|
||||
bool JudgeKTaskStatIsInit(KTaskDescriptorType task);
|
||||
bool JudgeKTaskStatIsReady(KTaskDescriptorType task);
|
||||
bool JudgeKTaskStatIsSuspend(KTaskDescriptorType task);
|
||||
bool JudgeKTaskStatIsRunning(KTaskDescriptorType task);
|
||||
bool JudgeKTaskStatIsClose(KTaskDescriptorType task);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
32
kernel/include/xs_ktick.h
Normal file
32
kernel/include/xs_ktick.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_ktick.h
|
||||
* @brief: function declaration of kernel tick
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/2
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_KTICK_H
|
||||
#define XS_KTICK_H
|
||||
|
||||
#include <xs_base.h>
|
||||
|
||||
x_ticks_t CurrentTicksGain(void);
|
||||
void TickAndTaskTimesliceUpdate(void);
|
||||
x_ticks_t CalculteTickFromTimeMs(uint32 ms);
|
||||
uint32 CalculteTimeMsFromTick(x_ticks_t ticks);
|
||||
|
||||
#endif
|
||||
107
kernel/include/xs_memory.h
Normal file
107
kernel/include/xs_memory.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_memory.h
|
||||
* @brief: function declaration and structure defintion of memory
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/2
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_MEMORY_H
|
||||
#define XS_MEMORY_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MM_PAGE_SIZE
|
||||
#define MM_PAGE_SIZE 4096
|
||||
#endif
|
||||
|
||||
#define MM_PAGE_MASK (MM_PAGE_SIZE - 1)
|
||||
#define MM_PAGE_BITS 12
|
||||
|
||||
/* Set static memory block */
|
||||
#ifndef SMALL_NUMBER_32B
|
||||
#define SMALL_NUMBER_32B (0) /* Calculate the numbers of SIZEOF_32B blocks*/
|
||||
#endif
|
||||
|
||||
#ifndef SMALL_NUMBER_64B
|
||||
#define SMALL_NUMBER_64B (0) /* Calculate the numbers of SIZEOF_64B blocks*/
|
||||
#endif
|
||||
|
||||
#ifndef KERNEL_MALLOC
|
||||
#define KERNEL_MALLOC(sz) x_malloc(sz)
|
||||
#endif
|
||||
|
||||
#ifndef KERNEL_FREE
|
||||
#define KERNEL_FREE(ptr) x_free(ptr)
|
||||
#endif
|
||||
|
||||
#ifndef KERNEL_REALLOC
|
||||
#define KERNEL_REALLOC(ptr, size) x_realloc(ptr, size)
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_MEMBLOCK
|
||||
struct MemGather
|
||||
{
|
||||
char m_name[NAME_NUM_MAX];
|
||||
uint8 m_kind;
|
||||
uint8 m_sign;
|
||||
|
||||
DoubleLinklistType m_link;
|
||||
|
||||
void *m_start_address;
|
||||
x_size_t m_size;
|
||||
x_size_t one_block_size;
|
||||
uint8 *m_block_link;
|
||||
|
||||
x_size_t block_total_number;
|
||||
x_size_t block_free_number;
|
||||
DoubleLinklistType wait_task;
|
||||
};
|
||||
typedef struct MemGather *GatherMemType;
|
||||
|
||||
x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *begin_address, x_size_t gm_size, x_size_t one_block_size);
|
||||
x_err_t RemoveMemGather(struct MemGather *gm_handler);
|
||||
GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size_t one_block_size);
|
||||
x_err_t DeleteMemGather(GatherMemType gm_handler);
|
||||
void *AllocBlockMemGather(GatherMemType gm_handler, int32 wait_time);
|
||||
void FreeBlockMemGather(void *data_block);
|
||||
#endif
|
||||
|
||||
void InitBoardMemory(void *begin_addr, void *end_addr);
|
||||
void *x_malloc(x_size_t nbytes);
|
||||
void x_free(void *ptr);
|
||||
void *x_realloc(void *ptr, x_size_t nbytes);
|
||||
void *x_calloc(x_size_t count, x_size_t size);
|
||||
|
||||
#ifdef USER_APPLICATION
|
||||
void UserInitBoardMemory(void *begin_addr, void *end_addr);
|
||||
void *x_umalloc(x_size_t nbytes);
|
||||
void x_ufree(void *ptr);
|
||||
void *x_urealloc(void *ptr, x_size_t nbytes);
|
||||
void *x_ucalloc(x_size_t count, x_size_t size);
|
||||
#endif
|
||||
|
||||
void MemoryInfo(uint32 *total, uint32 *used, uint32 *max_used);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
67
kernel/include/xs_msg.h
Normal file
67
kernel/include/xs_msg.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_msg.h
|
||||
* @brief: function declaration and structure defintion of message queue
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/2
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_MSG_H
|
||||
#define XS_MSG_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
|
||||
#ifdef KERNEL_MESSAGEQUEUE
|
||||
|
||||
struct MsgQueue
|
||||
{
|
||||
struct IdNode id;
|
||||
void *msg_buf;
|
||||
uint16 index;
|
||||
uint16 num_msgs;
|
||||
uint16 each_len;
|
||||
uint16 max_msgs;
|
||||
|
||||
DoubleLinklistType send_pend_list;
|
||||
DoubleLinklistType recv_pend_list;
|
||||
DoubleLinklistType link;
|
||||
struct MsgQueueDone *Done;
|
||||
};
|
||||
typedef struct MsgQueue *MsgQueueType;
|
||||
|
||||
struct MsgQueueDone
|
||||
{
|
||||
x_err_t (*init)(struct MsgQueue *mq, x_size_t msg_size, x_size_t max_msgs );
|
||||
x_err_t (*urgensend)(struct MsgQueue *mq, const void *buffer, x_size_t size);
|
||||
x_err_t (*send)(struct MsgQueue *mq, const void *buffer, x_size_t size,int32 timeout);
|
||||
x_err_t (*recv)(struct MsgQueue *mq, void *buffer, x_size_t size, int32 timeout);
|
||||
x_err_t (*reinit)(struct MsgQueue *mq);
|
||||
x_err_t (*Delete)(struct MsgQueue *mq);
|
||||
};
|
||||
|
||||
int32 KCreateMsgQueue( x_size_t msg_size, x_size_t max_msgs );
|
||||
x_err_t KMsgQueueSendwait(int32 id, const void *buffer, x_size_t size, int32 timeout);
|
||||
x_err_t KMsgQueueUrgentSend(int32 id, const void *buffer, x_size_t size);
|
||||
x_err_t KMsgQueueSend(int32 id, const void *buffer, x_size_t size);
|
||||
x_err_t KMsgQueueRecv(int32 id, void *buffer, x_size_t size, int32 timeout);
|
||||
x_err_t KMsgQueueReinit(int32 id);
|
||||
x_err_t KDeleteMsgQueue(int32 id);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
56
kernel/include/xs_mutex.h
Normal file
56
kernel/include/xs_mutex.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_mutex.h
|
||||
* @brief: function declaration and structure defintion of mutex
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_MUTEX_H
|
||||
#define XS_MUTEX_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_id.h>
|
||||
|
||||
#ifdef KERNEL_MUTEX
|
||||
|
||||
struct Mutex {
|
||||
struct IdNode id;
|
||||
uint16 val;
|
||||
uint8 recursive_cnt;
|
||||
uint8 origin_prio;
|
||||
struct TaskDescriptor *holder;
|
||||
DoubleLinklistType pend_list;
|
||||
DoubleLinklistType link;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int32 (*MutexCreate)();
|
||||
void (*MutexDelete)(struct Mutex *mutex);
|
||||
int32 (*MutexObtain)(struct Mutex *mutex, int32 wait_time);
|
||||
int32 (*MutexAbandon)(struct Mutex *mutex);
|
||||
} MutexDoneType;
|
||||
|
||||
int32 KMutexCreate();
|
||||
void KMutexDelete(int32 id);
|
||||
int32 KMutexObtain(int32 id, int32 wait_time);
|
||||
int32 KMutexAbandon(int32 id);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
59
kernel/include/xs_poll.h
Normal file
59
kernel/include/xs_poll.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_pool.h
|
||||
* @brief: function declaration and structure defintion of poll
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_POLL_H
|
||||
#define XS_POLL_H
|
||||
|
||||
#include <xs_base.h>
|
||||
#include <xs_waitqueue.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#if !defined(POLLIN) && !defined(POLLOUT)
|
||||
|
||||
#define POLLIN 0x001
|
||||
#define POLLOUT 0x002
|
||||
#define POLLERR 0x004
|
||||
#define POLLHUP 0x008
|
||||
#define POLLNVAL 0x010
|
||||
|
||||
#define POLLMASK_DEFAULT (POLLIN | POLLOUT )
|
||||
|
||||
typedef unsigned long NfdsType;
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
#endif
|
||||
struct Pollreq;
|
||||
typedef void (*poll_queue_proc)(WaitQueueType *, struct Pollreq *);
|
||||
typedef struct Pollreq
|
||||
{
|
||||
poll_queue_proc _proc;
|
||||
short _key;
|
||||
} pollreqType;
|
||||
|
||||
void PollAdd(WaitQueueType *wq, pollreqType *req);
|
||||
int poll(struct pollfd *fds, NfdsType nfds, int timeout);
|
||||
|
||||
#endif
|
||||
47
kernel/include/xs_queue_manager.h
Normal file
47
kernel/include/xs_queue_manager.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_queue_manager.h
|
||||
* @brief: function declaration and structure defintion of queue manager
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_QUEUE_MANAGER_H
|
||||
#define XS_QUEUE_MANAGER_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
|
||||
#ifndef QUEUE_MAX
|
||||
#define QUEUE_MAX 16
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *property;
|
||||
void *done;
|
||||
} queue;
|
||||
|
||||
enum QUEUE_TYPE
|
||||
{
|
||||
DATA_QUEUE = 1,
|
||||
WORK_QUEUE,
|
||||
WAIT_QUEUE,
|
||||
};
|
||||
|
||||
extern void *g_queue_done[];
|
||||
extern void queuemanager_done_register();
|
||||
|
||||
#endif
|
||||
57
kernel/include/xs_sem.h
Normal file
57
kernel/include/xs_sem.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_sem.h
|
||||
* @brief: function declaration and structure defintion of sem
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/12
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_SEM_H
|
||||
#define XS_SEM_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_id.h>
|
||||
|
||||
#ifdef KERNEL_SEMAPHORE
|
||||
|
||||
struct Semaphore
|
||||
{
|
||||
struct IdNode id;
|
||||
uint16 value;
|
||||
|
||||
DoubleLinklistType pend_list;
|
||||
DoubleLinklistType link;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int32 (*SemaphoreCreate)(uint16 val);
|
||||
void (*SemaphoreDelete)(struct Semaphore *sem);
|
||||
int32 (*SemaphoreObtain)(struct Semaphore *sem, int32 wait_time);
|
||||
int32 (*SemaphoreAbandon)(struct Semaphore *sem);
|
||||
int32 (*SemaphoreSetValue)(struct Semaphore *sem, uint16 val);
|
||||
} SemaphoreDoneType;
|
||||
|
||||
int32 KSemaphoreCreate(uint16 val);
|
||||
void KSemaphoreDelete(int32 id);
|
||||
int32 KSemaphoreObtain(int32 id, int32 wait_time);
|
||||
int32 KSemaphoreAbandon(int32 id);
|
||||
int32 KSemaphoreSetValue(int32 id, uint16 val);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
115
kernel/include/xs_service.h
Normal file
115
kernel/include/xs_service.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_service.h
|
||||
* @brief: maroc and switch table definition of kernel switch
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_SERVICE_H
|
||||
#define XS_SERVICE_H
|
||||
#include <stdint.h>
|
||||
#include "xs_base.h"
|
||||
|
||||
#ifdef SEPARATE_COMPILE
|
||||
// #include <board.h>
|
||||
|
||||
enum KernelService
|
||||
{
|
||||
KS_USER_PRINT_INFO = 0,
|
||||
KS_USER_TASK_CREATE ,
|
||||
KS_USER_TASK_STARTUP ,
|
||||
KS_USER_TASK_DELETE,
|
||||
KS_USER_TASK_EXECEXIT,
|
||||
KS_USER_TASK_CORE_COMBINE,
|
||||
KS_USER_TASK_CORE_UNCOMBINE,
|
||||
KS_USER_TASK_DELAY,
|
||||
KS_USER_GET_TASK_NAME,
|
||||
KS_USER_GET_TASK_ID,
|
||||
KS_USER_GET_TASK_STAT,
|
||||
KS_USER_GET_TASK_COMBINEED_CORE,
|
||||
KS_USER_GET_TASK_RUNNING_CORE,
|
||||
KS_USER_GET_TASK_ERROR_STATUS,
|
||||
KS_USER_GET_TASK_PRIORITY,
|
||||
|
||||
KS_USER_MALLOC,
|
||||
KS_USER_FREE,
|
||||
|
||||
KS_USER_MUTEX_CREATE,
|
||||
KS_USER_MUTEX_DELETE,
|
||||
KS_USER_MUTEX_OBTAIN,
|
||||
KS_USER_MUTEX_ABANDON,
|
||||
|
||||
KS_USER_SEMAPHORE_CREATE,
|
||||
KS_USER_SEMAPHORE_DELETE,
|
||||
KS_USER_SEMAPHORE_OBTAIN,
|
||||
KS_USER_SEMAPHORE_ABANDON,
|
||||
KS_USER_SEMAPHORE_SETVALUE,
|
||||
|
||||
|
||||
KS_USER_EVENT_CREATE,
|
||||
KS_USER_EVENT_DELETE,
|
||||
KS_USER_EVENT_TRIGGER,
|
||||
KS_USER_EVENT_PROCESS,
|
||||
|
||||
KS_USER_MSGQUEUE_CREATE,
|
||||
KS_USER_MSGQUEUE_DELETE,
|
||||
KS_USER_MSGQUEUE_SENDWAIT,
|
||||
KS_USER_MSGQUEUE_SEND,
|
||||
KS_USER_MSGQUEUE_URGENTSEND,
|
||||
KS_USER_MSGQUEUE_RECV,
|
||||
KS_USER_MSGQUEUE_REINIT,
|
||||
|
||||
KS_USER_OPEN,
|
||||
KS_USER_READ,
|
||||
KS_USER_WRITE,
|
||||
KS_USER_CLOSE,
|
||||
KS_USER_IOCTL,
|
||||
KS_USER_LSEEK,
|
||||
KS_USER_RENAME,
|
||||
KS_USER_UNLINK,
|
||||
KS_USER_STAT,
|
||||
KS_USER_FS_STAT,
|
||||
KS_USER_FS_SYNC,
|
||||
KS_USER_FTRUNCATE,
|
||||
KS_USER_MKDIR,
|
||||
KS_USER_OPENDIR,
|
||||
KS_USER_CLOSEDIR,
|
||||
KS_USER_READDIR,
|
||||
KS_USER_RMDIR,
|
||||
KS_USER_CHDIR,
|
||||
KS_USER_GETCWD,
|
||||
KS_USER_TELLDIR,
|
||||
KS_USER_SEEKDIR,
|
||||
KS_USER_REWIND_DIR,
|
||||
KS_USER_STAT_FS,
|
||||
|
||||
KS_USER_END
|
||||
|
||||
};
|
||||
#define SERVICETABLE ((struct Kernel_Service*)SERVICE_TABLE_ADDRESS)
|
||||
#endif
|
||||
|
||||
typedef uintptr_t (*kservice)(uint32_t knum,uintptr_t *param,uint8_t param_num);
|
||||
struct Kernel_Service
|
||||
{
|
||||
const kservice fun;
|
||||
const uint8_t param_num;
|
||||
};
|
||||
|
||||
extern struct Kernel_Service g_service_table[] ;
|
||||
|
||||
#endif
|
||||
107
kernel/include/xs_spinlock.h
Normal file
107
kernel/include/xs_spinlock.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_service.h
|
||||
* @brief: maroc and switch table definition of kernel switch
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/2
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_SPINLOCK_H
|
||||
#define XS_SPINLOCK_H
|
||||
|
||||
#include <xs_isr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned long slock;
|
||||
struct __arch_tickets
|
||||
{
|
||||
unsigned short owner;
|
||||
unsigned short next;
|
||||
} tickets;
|
||||
} HwSpinlock;
|
||||
|
||||
struct SpinLock
|
||||
{
|
||||
HwSpinlock lock;
|
||||
};
|
||||
|
||||
struct Spin_Lockfileops
|
||||
{ //定义自旋锁
|
||||
struct SpinLock node_lock; //原有的自旋锁结构体
|
||||
void (*SPinLock)(struct Spin_Lockfileops *spinlock);
|
||||
void (*UnlockSpinLock)(struct Spin_Lockfileops *spinlock);
|
||||
void (*UnlockSpinLockIrqRestore)(struct Spin_Lockfileops *spinlock, x_base level);
|
||||
x_base (*SpinLockIrqSave)(struct Spin_Lockfileops *spinlock);
|
||||
};
|
||||
|
||||
extern struct Spin_Lockfileops spinlock;
|
||||
extern HwSpinlock _CriticalLock;
|
||||
|
||||
void InitHwSpinlock(HwSpinlock *lock);
|
||||
void HwLockSpinlock(HwSpinlock *lock);
|
||||
void HwUnlockSpinlock(HwSpinlock *lock);
|
||||
int GetCpuId(void);
|
||||
|
||||
#define HW_SPIN_LOCK_INITIALIZER(lockname) {0}
|
||||
#define HW_SPIN_LOCK_UNLOCKED(lockname) (HwSpinlock) HW_SPIN_LOCK_INITIALIZER(lockname)
|
||||
#define DEFINE_SPINLOCK(x) HwSpinlock x = HW_SPIN_LOCK_UNLOCKED(x)
|
||||
#define DECLARE_SPINLOCK(x)
|
||||
|
||||
void StartupSecondaryCpu(void);
|
||||
void ExecSecondaryCpuIdleKtask(void);
|
||||
|
||||
#else
|
||||
|
||||
#define HwLockSpinlock(lock) *(lock) = DISABLE_INTERRUPT()
|
||||
#define HwUnlockSpinlock(lock) ENABLE_INTERRUPT(*(lock))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
struct SpinLock;
|
||||
|
||||
void InitSpinLock(struct Spin_Lockfileops * spinlock);
|
||||
void _SpinLock(struct Spin_Lockfileops * spinlock);
|
||||
void _UnlockSpinLock(struct Spin_Lockfileops * spinlock);
|
||||
x_base _SpinLockIrqSave(struct Spin_Lockfileops * spinlock);
|
||||
void _UnlockSpinLockIrqRestore(struct Spin_Lockfileops * spinlock, x_base level);
|
||||
|
||||
#else
|
||||
#define InitSpinLock(lock) /* nothing */
|
||||
#define SpinLock(lock) CriticalAreaLock()
|
||||
#define UnlockSpinLock(lock) CriticalAreaUnLock()
|
||||
#define SpinLockIrqSave(lock) DISABLE_INTERRUPT()
|
||||
#define UnlockSpinLockIrqRestore(lock, level) ENABLE_INTERRUPT(level)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
87
kernel/include/xs_timer.h
Normal file
87
kernel/include/xs_timer.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_timer.h
|
||||
* @brief: function declaration and structure defintion of timer
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_TIMER_H
|
||||
#define XS_TIMER_H
|
||||
|
||||
#include <xsconfig.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_id.h>
|
||||
|
||||
#define TIMER_TRIGGER_ONCE (1 << 0)
|
||||
#define TIMER_TRIGGER_PERIODIC (1 << 1)
|
||||
|
||||
#define TIMER_ACTIVE_FALSE (1 << 0)
|
||||
#define TIMER_ACTIVE_TRUE (1 << 1)
|
||||
|
||||
|
||||
struct Timer
|
||||
{
|
||||
struct IdNode id_node;
|
||||
char name[NAME_NUM_MAX];
|
||||
uint8 active_status;
|
||||
uint8 trigger_mode;
|
||||
void (*func_callback)(void *param);
|
||||
void *param;
|
||||
x_ticks_t origin_timeslice;
|
||||
x_ticks_t deadline_timeslice;
|
||||
DoubleLinklistType link;
|
||||
DoubleLinklistType sortlist;
|
||||
uint8 prio;
|
||||
struct Work * t_work;
|
||||
struct TimerDone* done;
|
||||
};
|
||||
typedef struct Timer *TimerType;
|
||||
|
||||
struct TimerDone
|
||||
{
|
||||
void (*Init)(struct Timer *timer,
|
||||
const char *name,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter,
|
||||
x_ticks_t time,
|
||||
uint8 trigger_mode);
|
||||
|
||||
x_err_t (*Delete)(TimerType timer);
|
||||
x_err_t (*StartRun)(TimerType timer);
|
||||
x_err_t (*QuitRun)(TimerType timer);
|
||||
x_err_t (*Modify)(TimerType timer, x_ticks_t ticks);
|
||||
};
|
||||
|
||||
int32 KCreateTimer(const char *name,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter,
|
||||
x_ticks_t time,
|
||||
uint8 trigger_mode);
|
||||
x_err_t KDeleteTimer(int32 timer_id);
|
||||
x_err_t KTimerStartRun(int32 timer_id);
|
||||
x_err_t KTimerQuitRun(int32 timer_id);
|
||||
x_err_t KTimerModify(int32 timer_id, x_ticks_t ticks);
|
||||
x_err_t KTimerAssignMemberRun(int32 timer_id, x_ticks_t ticks);
|
||||
|
||||
TimerType KGetTimer(int32 id);
|
||||
int32 KGetTimerID(TimerType timer);
|
||||
x_ticks_t TimerNextTimeoutTick(void);
|
||||
void CheckTimerList(void);
|
||||
|
||||
#endif
|
||||
78
kernel/include/xs_waitqueue.h
Normal file
78
kernel/include/xs_waitqueue.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_waitqueue.h
|
||||
* @brief: function declaration and structure defintion of waitqueue
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_WAITQUEUE_H
|
||||
#define XS_WAITQUEUE_H
|
||||
|
||||
#include <xs_ktask.h>
|
||||
#include <xs_timer.h>
|
||||
#include <xs_queue_manager.h>
|
||||
|
||||
#define WQ_FLAG_CLEAN 0x00
|
||||
#define WQ_FLAG_WAKEUP 0x01
|
||||
|
||||
struct WaitQueue
|
||||
{
|
||||
DoubleLinklistType block_threads_list;
|
||||
};
|
||||
typedef struct WaitQueue WaitQueueType;
|
||||
|
||||
struct WaitqueueNode;
|
||||
typedef int (*wqueue_func_t)(struct WaitqueueNode *wait, void *key);
|
||||
|
||||
struct WaitqueueNode
|
||||
{
|
||||
KTaskDescriptorType polling_task;
|
||||
DoubleLinklistType list;
|
||||
wqueue_func_t cb;
|
||||
x_ticks_t deadline_tick;
|
||||
uint32 key;
|
||||
};
|
||||
typedef struct WaitqueueNode WaitqueueNodeType;
|
||||
|
||||
int __WqueueDefaultWake(struct WaitqueueNode *wait, void *key);
|
||||
void InitWqueue(WaitQueueType *queue);
|
||||
void WqueueAdd(WaitQueueType *queue, struct WaitqueueNode *node);
|
||||
void WqueueRemove(struct WaitqueueNode *node);
|
||||
int WqueueWait(WaitQueueType *queue, x_ticks_t tick);
|
||||
void WakeupWqueue(WaitQueueType *queue, void *key);
|
||||
|
||||
#define DEFINE_WAIT_FUNC(name, function) \
|
||||
struct WaitqueueNode name = { \
|
||||
os_running_task, \
|
||||
DOUBLE_LINKLIST_OBJ_INIT(((name).list)), \
|
||||
\
|
||||
function, \
|
||||
0 \
|
||||
}
|
||||
|
||||
#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, __WqueueDefaultWake)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*InitWqueue)(WaitQueueType *queue);
|
||||
void (*WqueueAdd)(WaitQueueType *queue, WaitqueueNodeType *node);
|
||||
void (*WqueueRemove)(WaitqueueNodeType *node);
|
||||
int (*WqueueWait)(WaitQueueType *queue, x_ticks_t tick);
|
||||
void (*WakeupWqueue)(WaitQueueType *queue, void *key);
|
||||
} WaitQueueDoneType;
|
||||
|
||||
#endif
|
||||
66
kernel/include/xs_workqueue.h
Normal file
66
kernel/include/xs_workqueue.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_workqueue.h
|
||||
* @brief: function declaration and structure defintion of workqueue
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/20
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_WORKQUEUE_H
|
||||
#define XS_WORKQUEUE_H
|
||||
|
||||
#include <xs_ktask.h>
|
||||
#include <xs_timer.h>
|
||||
#include <xs_queue_manager.h>
|
||||
|
||||
#define MAX_WORK_QUEUE 32
|
||||
|
||||
struct Work
|
||||
{
|
||||
void (*cb_func)(struct Work *work, void *work_data);
|
||||
void *cb_param;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int front;
|
||||
int rear;
|
||||
struct Work* base;
|
||||
int32 task;
|
||||
}WorkqueueType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WorkqueueType* p_queue;
|
||||
struct Work* p_work;
|
||||
int32 p_timer;
|
||||
}WorkTimerParamType;
|
||||
|
||||
WorkqueueType *CreateWorkQueue(const char *name, uint16 stack_size, uint8 priority);
|
||||
void WorkInit(struct Work *work, void (*work_func)(struct Work *work,void *work_data), void *work_data);
|
||||
x_err_t WorkSubmit(WorkqueueType* sys_workq, struct Work *work, x_ticks_t time);
|
||||
x_err_t WorkSubmit_immediate(WorkqueueType* sys_workq, struct Work *work);
|
||||
int WorkSysWorkQueueInit(void);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WorkqueueType *(*CreateWorkQueue)(const char *name, uint16 stack_size, uint8 priority);
|
||||
void (*WorkInit)(struct Work *work, void (*work_func)(struct Work *work, void *work_data), void *work_data);
|
||||
x_err_t (*WorkSubmit)(WorkqueueType *sys_workq, struct Work *work, x_ticks_t time);
|
||||
x_err_t (*WorkSubmit_immediate)(WorkqueueType *sys_workq, struct Work *work);
|
||||
} WorkQueueDoneType;
|
||||
|
||||
#endif
|
||||
4
kernel/kernel_service/Makefile
Normal file
4
kernel/kernel_service/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
SRC_FILES := xs_service.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
710
kernel/kernel_service/xs_service.c
Normal file
710
kernel/kernel_service/xs_service.c
Normal file
@@ -0,0 +1,710 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: xs_service.c
|
||||
* @brief: this file is provided for kernel switch of userapi
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/8
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_service.h>
|
||||
#ifdef FS_VFS
|
||||
#include <iot-vfs_posix.h>
|
||||
#endif
|
||||
#ifdef TASK_ISOLATION
|
||||
#include <xs_isolation.h>
|
||||
#endif
|
||||
extern inline struct TaskDescriptor *GetTaskWithIdnodeInfo(int32 id);
|
||||
#ifdef SEPARATE_COMPILE
|
||||
extern long ShowTask(void);
|
||||
extern void ShowMemory(void);
|
||||
extern long ShowSem(void);
|
||||
extern long ShowEvent(void);
|
||||
extern long ShowMutex(void);
|
||||
//extern long ShowMemPool(void);
|
||||
extern long ShowMsgQueue(void);
|
||||
//extern long showdevice(void);
|
||||
extern long ShowTimer(void);
|
||||
uintptr_t KsPrintInfo(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
uintptr_t arg = param[0];
|
||||
uintptr_t ret = arg;
|
||||
struct TaskDescriptor *tid = NONE;
|
||||
KPrintf("ecall from user mode : arg: %d\n", arg );
|
||||
switch (arg)
|
||||
{
|
||||
case 1:
|
||||
#ifdef TOOL_SHELL
|
||||
ShowTask();
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
ShowMemory();
|
||||
break;
|
||||
case 3:
|
||||
#ifdef KERNEL_SEMAPHORE
|
||||
//ShowSem();
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
#ifdef KERNEL_EVENT
|
||||
ShowEvent();
|
||||
#endif
|
||||
break;
|
||||
case 5:
|
||||
#ifdef KERNEL_MUTEX
|
||||
ShowMutex();
|
||||
#endif
|
||||
break;
|
||||
case 6:
|
||||
//ShowMemPool();
|
||||
break;
|
||||
case 7:
|
||||
#ifdef KERNEL_MESSAGEQUEUE
|
||||
ShowMsgQueue();
|
||||
#endif
|
||||
break;
|
||||
case 8:
|
||||
//showdevice();
|
||||
break;
|
||||
case 9:
|
||||
#ifdef KERNEL_SOFTTIMER
|
||||
ShowTimer();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
KPrintf("unsurport \n");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uintptr_t KsTaskCreate(uint32_t knum,uintptr_t *param, uint8_t num)
|
||||
{
|
||||
return (uintptr_t) UTaskCreate((char *)(param[0]), (void *)(param[1]),(void *)(param[2]),(uint32)(param[3]),(uint8)(param[4]));
|
||||
|
||||
}
|
||||
|
||||
uintptr_t KsStartupTask(uint32_t knum,uintptr_t *param, uint8_t num)
|
||||
{
|
||||
x_err_t ret ;
|
||||
int32 id = (int32)(param[0]);
|
||||
ret = StartupKTask(id);
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsTaskDelete(uint32_t knum,uintptr_t *param, uint8_t num)
|
||||
{
|
||||
x_err_t ret ;
|
||||
ret = KTaskDelete((int32) (param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
extern void KTaskQuit(void);
|
||||
uintptr_t KsTaskQuit(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
KTaskQuit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t KsTaskCoreCombine(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret = EOK ;
|
||||
int32 id;
|
||||
#ifdef ARCH_SMP
|
||||
if( param[0] == NONE){
|
||||
id = GetKTaskDescriptor()->id.id;
|
||||
}else{
|
||||
id = (int32 )(param[0]);
|
||||
}
|
||||
ret = KTaskCoreCombine(id, (uint8)(param[1]));
|
||||
#endif
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsTaskCoreUnCombine(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
int32 id;
|
||||
#ifdef ARCH_SMP
|
||||
KTaskDescriptorType tid;
|
||||
if( param[0] == NONE){
|
||||
id = GetKTaskDescriptor()->id.id;
|
||||
}else{
|
||||
id = (int32 )(param[0]);
|
||||
}
|
||||
ret = KTaskCoreUnCombine(id);
|
||||
#endif
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMdelayTask(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret ;
|
||||
ret = MdelayKTask((int32)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsGetTaskID(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
return (uintptr_t)GetKTaskDescriptor()->id.id;
|
||||
}
|
||||
|
||||
uintptr_t KsGetTaskName(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
uint8_t *buf = (uint8_t *)(param[1]);
|
||||
task = GetTaskWithIdnodeInfo( (int32)(param[0]));
|
||||
if ( task == NONE )
|
||||
return -ERROR;
|
||||
|
||||
strncpy(buf, task->task_base_info.name, NAME_NUM_MAX);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
uintptr_t KsGetTaskStat(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo( (int32)(param[0]));
|
||||
return (uintptr_t)task->task_dync_sched_member.stat;
|
||||
}
|
||||
|
||||
uintptr_t KsGetTaskCombinedCore(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
#ifdef ARCH_SMP
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo( (int32)(param[0]));
|
||||
return (uintptr_t)task->task_smp_info.combined_coreid;
|
||||
#else
|
||||
return (uintptr_t)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uintptr_t KsGetTaskRunningCore(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
#ifdef ARCH_SMP
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo( (int32)(param[0]));
|
||||
return (uintptr_t)task->task_smp_info.runing_coreid;
|
||||
#else
|
||||
return (uintptr_t)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uintptr_t KsGetTaskErrorstatus(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo( (int32)(param[0]));
|
||||
return (uintptr_t)task->exstatus;
|
||||
}
|
||||
|
||||
uintptr_t KsGetTaskPriority (uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo( (int32)(param[0]));
|
||||
return (uintptr_t)task->task_dync_sched_member.cur_prio;
|
||||
}
|
||||
|
||||
uintptr_t KsMalloc(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
uintptr_t *ret = (uintptr_t *)x_umalloc( (x_size_t)param[0]);
|
||||
#ifdef MOMERY_PROTECT_ENABLE
|
||||
if( mem_access.AddRegion && ret != NONE){
|
||||
struct TaskDescriptor *task;
|
||||
task = GetKTaskDescriptor();
|
||||
mem_access.AddRegion(task->task_dync_sched_member.isolation, (x_ubase)ret , (x_size_t)param[0] , REGION_TYPE_HEAP );
|
||||
}
|
||||
#endif
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsFree(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_ufree((void *)(param[0]));
|
||||
#ifdef MOMERY_PROTECT_ENABLE
|
||||
if(mem_access.ClearRegion){
|
||||
struct TaskDescriptor *task;
|
||||
task = GetKTaskDescriptor();
|
||||
mem_access.ClearRegion(task->task_dync_sched_member.isolation, (x_ubase)param[0]);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#ifdef KERNEL_MUTEX
|
||||
uintptr_t KsCreateMutex(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int32 ret;
|
||||
ret = KMutexCreate();
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsDeleteMutex(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
KMutexDelete((int32)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMutexObtain(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret ;
|
||||
ret = KMutexObtain((int32)(param[0]),(int32)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMutexAbandon(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret ;
|
||||
ret = KMutexAbandon((int32)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef KERNEL_SEMAPHORE
|
||||
uintptr_t KsCreateSemaphore(uint32_t knum,uintptr_t *param, uint8_t num)
|
||||
{
|
||||
int32 ret;
|
||||
ret = KSemaphoreCreate((uint16)param[0]);
|
||||
return (uintptr_t)ret ;
|
||||
}
|
||||
|
||||
uintptr_t KsDeleteSemaphore(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
KSemaphoreDelete((int32)(param[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t KsSemaphoreObtain(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret ;
|
||||
ret = KSemaphoreObtain((int32)(param[0]),(int32)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsSemaphoreAbandon(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret ;
|
||||
ret = KSemaphoreAbandon((int32)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsSemaphoreSetValue(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret ;
|
||||
ret = KSemaphoreSetValue((int32)(param[0]),(uint16)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_EVENT
|
||||
uintptr_t KsCreateEvent(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
EventIdType ret;
|
||||
ret = KEventCreate((uint8)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsDeleteEvent(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret = 0;
|
||||
KEventDelete((EventIdType)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsEventTrigger(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KEventTrigger((EventIdType)(param[0]), (uint32)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsEventProcess(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KEventProcess((EventIdType)(param[0]), (uint32)(param[1]), (uint8)(param[2]), (int32)(param[3]), (uint32 *)(param[4]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_MESSAGEQUEUE
|
||||
uintptr_t KsCreateMsgQueue(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int32 ret;
|
||||
ret = KCreateMsgQueue((int32)(param[0]), (x_size_t)(param[1]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsDeleteMsgQueue(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KDeleteMsgQueue((int32)(param[0]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMsgQueueSendwait(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KMsgQueueSendwait((int32)(param[0]), (const void *)(param[1]), (x_size_t)(param[2]), (int32)(param[3]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMsgQueueSend(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KMsgQueueSend((int32)(param[0]), (const void *)(param[1]), (x_size_t)(param[2]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMsgQueueUrgentSend(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KMsgQueueUrgentSend((int32)(param[0]), (const void *)(param[1]), (x_size_t)(param[2]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMsgQueueRecv(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KMsgQueueRecv((int32)(param[0]), (void *)(param[1]), (x_size_t)(param[2]), (int32)(param[3]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMsgQueueReinit(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
x_err_t ret;
|
||||
ret = KMsgQueueReinit((int32)(param[0]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
#endif
|
||||
/* fs posix*/
|
||||
|
||||
#ifdef FS_VFS
|
||||
uintptr_t KsOpen(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = open((const char *)(param[0]), (int)(param[1]), (mode_t)(param[2]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsRead(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = read((int)(param[0]), (void *)(param[1]), (size_t)(param[2]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsWrite(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = write((int)(param[0]), (const void *)(param[1]), (size_t)(param[2]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsClose(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = close((int)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsIoctl(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = ioctl((int)(param[0]), (int)(param[1]), (void *)(param[2]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsLseek(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
off_t ret;
|
||||
ret = lseek((int)(param[0]), (off_t)(param[1]), (int)(param[2]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsRename(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = rename((const char *)(param[0]), (const char *)(param[1]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsUnlink(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = unlink((const char *)(param[0]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsStat(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = stat((const char *)(param[0]), (struct stat *)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsFstat(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = fstat((int)(param[0]), (struct stat *)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsFsync(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = fsync((int)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsFtruncate(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = ftruncate((int)(param[0]), (off_t)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsMkdir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = mkdir((const char *)(param[0]), (mode_t)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsOpendir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
DIR *ret;
|
||||
ret = opendir((const char *)(param[0]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsClosedir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = closedir((DIR *)(param[0]) );
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsReaddir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
struct dirent *ret;
|
||||
ret = readdir((DIR *)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsRmdir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = rmdir((const char *)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsChdir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = chdir((const char *)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsGetcwd(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
char *ret;
|
||||
ret = getcwd((char *)(param[0]), (size_t)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsTelldir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
long ret = 0;
|
||||
//ret = telldir((DIR *)(param[0]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
|
||||
uintptr_t KsSeekdir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
seekdir((DIR *)(param[0]), (off_t)(param[1]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t KsRewinddir(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
rewinddir((DIR *)(param[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t KsStatfs(uint32_t knum,uintptr_t *param, uint8_t num )
|
||||
{
|
||||
int ret;
|
||||
ret = statfs((const char *)(param[0]), (struct statfs *)(param[1]));
|
||||
return (uintptr_t)ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Kernel_Service 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_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}
|
||||
|
||||
};
|
||||
#else
|
||||
struct utask
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
};
|
||||
typedef struct utask utask_x;
|
||||
int32_t UserTaskCreate(utask_x utask)
|
||||
{
|
||||
return KTaskCreate(utask.name, utask.func_entry, utask.func_param,utask.stack_size,utask.prio);
|
||||
}
|
||||
|
||||
x_err_t UserGetTaskName(int32_t id ,char *name)
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
uint8_t *buf = (uint8_t *)(name);
|
||||
task = GetTaskWithIdnodeInfo(id);
|
||||
if ( task == NONE )
|
||||
return -ERROR;
|
||||
|
||||
strncpy(buf, task->task_base_info.name, NAME_NUM_MAX);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
int32_t UserGetTaskID(void)
|
||||
{
|
||||
return (uintptr_t)GetKTaskDescriptor()->id.id;
|
||||
}
|
||||
|
||||
uint8_t UserGetTaskStat(int32_t id)
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo(id);
|
||||
return (uintptr_t)task->task_dync_sched_member.stat;
|
||||
}
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
uint8_t UserGetTaskCombinedCore(int32_t id)
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo(id);
|
||||
return (uintptr_t)task->task_smp_info.combined_coreid;
|
||||
}
|
||||
|
||||
uint8_t UserGetTaskRunningCore(int32_t id)
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo(id);
|
||||
return (uintptr_t)task->task_smp_info.runing_coreid;
|
||||
}
|
||||
#endif
|
||||
|
||||
x_err_t UserGetTaskErrorstatus(int32_t id)
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo(id);
|
||||
return (uintptr_t)task->exstatus;
|
||||
}
|
||||
|
||||
uint8_t UserGetTaskPriority(int32_t id)
|
||||
{
|
||||
KTaskDescriptorType task ;
|
||||
task = GetTaskWithIdnodeInfo(id);
|
||||
return (uintptr_t)task->task_dync_sched_member.cur_prio;
|
||||
}
|
||||
|
||||
long occupy_g_service_table __attribute__ ((section (".g_service_table"))) = 0;
|
||||
|
||||
#endif
|
||||
62
kernel/kernel_test/Kconfig
Normal file
62
kernel/kernel_test/Kconfig
Normal file
@@ -0,0 +1,62 @@
|
||||
menuconfig KERNEL_TEST
|
||||
bool "Enable kernel test function "
|
||||
default n
|
||||
|
||||
if KERNEL_TEST
|
||||
config KERNEL_TEST_AVLTREE
|
||||
bool "Config test avl tree"
|
||||
default n
|
||||
select KERNEL_AVL_TREE
|
||||
config KERNEL_TEST_CRICULAR_AREA
|
||||
bool "Config test Circular area"
|
||||
default n
|
||||
select KERNEL_CIRCULAR_AREA
|
||||
config KERNEL_TEST_MEM
|
||||
bool "Config test mem"
|
||||
default n
|
||||
select KERNEL_MEMBLOCK
|
||||
config KERNEL_TEST_TIMER
|
||||
bool "Config test timer"
|
||||
default n
|
||||
config KERNEL_TEST_IWG
|
||||
bool "Config test iwg"
|
||||
default n
|
||||
select BSP_USING_WDT
|
||||
config KERNEL_TEST_REALTIME
|
||||
bool "Config test realtime"
|
||||
default n
|
||||
config KERNEL_TEST_DBG
|
||||
bool "Config test dbg"
|
||||
default n
|
||||
select KERNEL_DEBUG
|
||||
config KERNEL_TEST_SCHED
|
||||
bool "Config test sched"
|
||||
default n
|
||||
config KERNEL_TEST_RTC
|
||||
bool "Config test rtc"
|
||||
default n
|
||||
config KERNEL_TEST_SERIAL
|
||||
bool "Config test serial"
|
||||
default n
|
||||
config KERNEL_TEST_HWTIMER
|
||||
bool "Config test hwtimer"
|
||||
default n
|
||||
config KERNEL_TEST_CAN
|
||||
bool "Config test can"
|
||||
default n
|
||||
config KERNEL_TEST_TOUCH
|
||||
bool "Config test touch"
|
||||
default n
|
||||
config KERNEL_TEST_LCD
|
||||
bool "Config test lcd"
|
||||
default n
|
||||
config KERNEL_TEST_CH438
|
||||
bool "Config test ch438"
|
||||
default n
|
||||
config KERNEL_TEST_I2C
|
||||
bool "Config test i2c"
|
||||
default n
|
||||
config KERNEL_TEST_RISC_CAN
|
||||
bool "Config test riscv can "
|
||||
default n
|
||||
endif
|
||||
88
kernel/kernel_test/Makefile
Normal file
88
kernel/kernel_test/Makefile
Normal file
@@ -0,0 +1,88 @@
|
||||
SRC_FILES := test_main.c
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_SEM),y)
|
||||
SRC_FILES += test_sem.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_MUTEX),y)
|
||||
SRC_FILES += test_mutex.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_EVENT),y)
|
||||
SRC_FILES += test_event.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_MSG),y)
|
||||
SRC_FILES += test_mq.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_AVLTREE),y)
|
||||
SRC_FILES += test_avltree.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_CRICULAR_AREA),y)
|
||||
SRC_FILES += test_circulararea.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_TOUCH),y)
|
||||
SRC_FILES += test_touch.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_MEM),y)
|
||||
SRC_FILES += test_mem.c
|
||||
SRC_FILES += test_gatherblock.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_TIMER),y)
|
||||
SRC_FILES += test_timer.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_IWG),y)
|
||||
SRC_FILES += test_iwg.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_CAN),y)
|
||||
SRC_FILES += test_can.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_REALTIME),y)
|
||||
SRC_FILES += test_realtime.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_DBG),y)
|
||||
SRC_FILES += test_dbg.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_SCHED),y)
|
||||
SRC_FILES += test_threadsched.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_RTC),y)
|
||||
SRC_FILES += test_rtc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_SERIAL),y)
|
||||
SRC_FILES += test_serial.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_HWTIMER),y)
|
||||
SRC_FILES += test_hwtimer.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_LCD),y)
|
||||
SRC_FILES += test_lcd.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_CH438),y)
|
||||
SRC_FILES += test_ch438.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_I2C),y)
|
||||
SRC_FILES += test_i2c.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_TEST_RISC_CAN),y)
|
||||
SRC_FILES += riscv_test_can.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
127
kernel/kernel_test/riscv_test_can.c
Normal file
127
kernel/kernel_test/riscv_test_can.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file riscv_test_can.c
|
||||
* @brief support to test can function on aiit-riscv64-board
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
#ifdef BOARD_AIIT_RISCV_EVB
|
||||
|
||||
#include <device.h>
|
||||
#include <gpiohs.h>
|
||||
#include "board.h"
|
||||
#include "connect_ch438.h"
|
||||
|
||||
static struct Bus *bus;
|
||||
static struct HardwareDev *dev;
|
||||
static struct Driver *drv;
|
||||
|
||||
static int32 Timer = NONE;
|
||||
|
||||
static uint8 idx = 0;
|
||||
|
||||
static void Ch438Read(void *parameter)
|
||||
{
|
||||
uint8 rev_len;
|
||||
uint8 ext_uart_no = 3;
|
||||
static uint8 dat,i,count;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
static uint8 Ch438Buff[8][BUFFSIZE];
|
||||
|
||||
while (1)
|
||||
{
|
||||
read_param.buffer = Ch438Buff[3];
|
||||
rev_len = BusDevReadData(dev, &read_param);
|
||||
|
||||
for(count = 0 ;count < rev_len ;count++)
|
||||
{
|
||||
KPrintf("%#2x ",Ch438Buff[3][count]);
|
||||
KPrintf("\n");
|
||||
}
|
||||
|
||||
for(i=0;i<BUFFSIZE;i++)
|
||||
{
|
||||
Ch438Buff[3][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TestCh438Init(void)
|
||||
{
|
||||
x_err_t flag;
|
||||
|
||||
struct BusConfigureInfo configure_info;
|
||||
|
||||
int32 task_CH438 = KTaskCreate("task_CH438", Ch438Read, NONE, 2048, 10);
|
||||
flag = StartupKTask(task_CH438);
|
||||
if (flag != EOK) {
|
||||
KPrintf("StartupKTask failed .\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
bus = BusFind(CH438_BUS_NAME);
|
||||
drv = BusFindDriver(bus, CH438_DRIVER_NAME);
|
||||
dev = BusFindDevice(bus, CH438_DEVICE_NAME_3);
|
||||
|
||||
struct SerialCfgParam serial_cfg;
|
||||
memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
|
||||
configure_info.configure_cmd = OPE_INT;
|
||||
configure_info.private_data = (void *)&serial_cfg;
|
||||
|
||||
serial_cfg.data_cfg.port_configure = PORT_CFG_INIT;
|
||||
|
||||
serial_cfg.data_cfg.ext_uart_no = 3;
|
||||
serial_cfg.data_cfg.serial_baud_rate = 115200;
|
||||
BusDrvConfigure(drv, &configure_info);
|
||||
}
|
||||
|
||||
void CanTestSend(void)
|
||||
{
|
||||
uint8 MeterInstruction[8]={0x01, 0x04, 0x77, 0x66, 0x20, 0x03, 0xB0, 0x0B};
|
||||
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
write_param.buffer = MeterInstruction;
|
||||
write_param.size = 8;
|
||||
|
||||
TestCh438Init();
|
||||
MdelayKTask(500);
|
||||
while(1)
|
||||
{
|
||||
BusDevWriteData(dev, &write_param);
|
||||
KPrintf("test_can_send!\n");
|
||||
MdelayKTask(500);
|
||||
}
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
CanTestSend, CanTestSend, CanTestSend );
|
||||
|
||||
void CanTestRecv(void)
|
||||
{
|
||||
TestCh438Init();
|
||||
MdelayKTask(500);
|
||||
while(1)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
CanTestRecv, CanTestRecv, CanTestRecv );
|
||||
#endif
|
||||
200
kernel/kernel_test/test_avltree.c
Normal file
200
kernel/kernel_test/test_avltree.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestAvltree.c
|
||||
* @brief support to test avltree function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <xs_avltree.h>
|
||||
|
||||
static char string[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
static AvlNodeType g_avlnode;
|
||||
|
||||
static AvlNodeType create_tree(AvlNodeType avl_node)
|
||||
{
|
||||
uint32 i = 0;
|
||||
uint32 string_len = strlen(string);
|
||||
|
||||
for(i = 0; i < string_len; i ++)
|
||||
{
|
||||
KPrintf("avl_node %8p data %d\n", avl_node, string[i]);
|
||||
avl_node = AvlTreeInsertNode(avl_node, string[i]);
|
||||
}
|
||||
|
||||
return avl_node;
|
||||
}
|
||||
|
||||
static AvlNodeType DeleteNode(AvlNodeType avl_node, int32 data)
|
||||
{
|
||||
avl_node = AvlTreeDeleteNode(avl_node, data);
|
||||
|
||||
return avl_node;
|
||||
}
|
||||
|
||||
static AvlNodeType DeleteTree(AvlNodeType avl_node)
|
||||
{
|
||||
uint32 i = 0;
|
||||
uint32 string_len = strlen(string);
|
||||
|
||||
for(i = 0; i < string_len; i ++)
|
||||
{
|
||||
avl_node = AvlTreeDeleteNode(avl_node, string[i]);
|
||||
}
|
||||
|
||||
return avl_node;
|
||||
}
|
||||
|
||||
static AvlNodeType InsertNode(AvlNodeType avl_node, int32 data)
|
||||
{
|
||||
avl_node = AvlTreeInsertNode(avl_node, data);
|
||||
|
||||
return avl_node;
|
||||
}
|
||||
|
||||
static AvlNodeType SearchNode(AvlNodeType avl_node, int32 data)
|
||||
{
|
||||
AvlNodeType dst_node;
|
||||
dst_node = AvlNodeSearchNode(avl_node, data);
|
||||
|
||||
return dst_node;
|
||||
}
|
||||
|
||||
static AvlNodeType ModyfiNode(AvlNodeType avl_node, int32 src_data, int32 dst_data)
|
||||
{
|
||||
AvlNodeType dst_node;
|
||||
dst_node = AvlNodeModifyNode(avl_node, src_data, dst_data);
|
||||
|
||||
return dst_node;
|
||||
}
|
||||
|
||||
static void PrintfRootnode(void)
|
||||
{
|
||||
KPrintf("g_avlnode %8p data %d left %8p data %d right %8p data %d\n",
|
||||
g_avlnode, g_avlnode->data, g_avlnode->left, g_avlnode->left->data, g_avlnode->right, g_avlnode->right->data);
|
||||
|
||||
KPrintf("g_avlnode left %8p data %d left %8p data %d right %8p data %d\n",
|
||||
g_avlnode->left, g_avlnode->left->data, g_avlnode->left->left, g_avlnode->left->left->data, g_avlnode->left->right, g_avlnode->left->right->data);
|
||||
|
||||
KPrintf("g_avlnode right %8p data %d left %8p data %d right %8p data %d\n",
|
||||
g_avlnode->right, g_avlnode->right->data, g_avlnode->right->left, g_avlnode->right->left->data, g_avlnode->right->right, g_avlnode->right->right->data);
|
||||
}
|
||||
|
||||
static void InorderPrintftree(AvlNodeType avl_node)
|
||||
{
|
||||
if(avl_node)
|
||||
{
|
||||
if(avl_node->left)
|
||||
{
|
||||
InorderPrintftree(avl_node->left);
|
||||
}
|
||||
|
||||
KPrintf("%d ", avl_node->data);
|
||||
|
||||
if(avl_node->right)
|
||||
{
|
||||
InorderPrintftree(avl_node->right);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KPrintf("nil \n");
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 TestAvltree(int argc, char *argv[])
|
||||
{
|
||||
if(0 == argc)
|
||||
{
|
||||
KPrintf("TestAvltree needs parameters. Just return\n");
|
||||
return EOK;
|
||||
}
|
||||
|
||||
if(0 == strcmp("-c", argv[1]))
|
||||
{
|
||||
g_avlnode = create_tree(g_avlnode);
|
||||
if(NONE == g_avlnode)
|
||||
{
|
||||
KPrintf("TestAvltree g_avlnode create failed!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
PrintfRootnode();
|
||||
InorderPrintftree(g_avlnode);
|
||||
}
|
||||
else if(0 == strcmp("-d", argv[1]))
|
||||
{
|
||||
if(3 == argc)
|
||||
{
|
||||
int32 data = atoi(argv[2]);
|
||||
|
||||
g_avlnode = DeleteNode(g_avlnode, data);
|
||||
|
||||
PrintfRootnode();
|
||||
InorderPrintftree(g_avlnode);
|
||||
}
|
||||
else if(2 == argc)
|
||||
{
|
||||
g_avlnode = DeleteTree(g_avlnode);
|
||||
|
||||
PrintfRootnode();
|
||||
InorderPrintftree(g_avlnode);
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("-i", argv[1]))
|
||||
{
|
||||
if(3 == argc)
|
||||
{
|
||||
int32 data = atoi(argv[2]);
|
||||
|
||||
g_avlnode = InsertNode(g_avlnode, data);
|
||||
|
||||
PrintfRootnode();
|
||||
InorderPrintftree(g_avlnode);
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("-s", argv[1]))
|
||||
{
|
||||
if(3 == argc)
|
||||
{
|
||||
int32 data = atoi(argv[2]);
|
||||
|
||||
AvlNodeType dst_node = SearchNode(g_avlnode, data);
|
||||
|
||||
KPrintf("find data %dx%d node %8p\n", dst_node->data, data, dst_node);
|
||||
PrintfRootnode();
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("-m", argv[1]))
|
||||
{
|
||||
if(4 == argc)
|
||||
{
|
||||
int32 src_data = atoi(argv[2]);
|
||||
int32 dst_data = atoi(argv[3]);
|
||||
|
||||
g_avlnode = ModyfiNode(g_avlnode, src_data, dst_data);
|
||||
|
||||
PrintfRootnode();
|
||||
InorderPrintftree(g_avlnode);
|
||||
}
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(4),
|
||||
TestAvltree, TestAvltree, Test the AVL tree Function);
|
||||
169
kernel/kernel_test/test_can.c
Normal file
169
kernel/kernel_test/test_can.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_can.c
|
||||
* @brief support to test can function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include "bus_can.h"
|
||||
#include "dev_can.h"
|
||||
|
||||
|
||||
uint8 buf[8] = {0x33,0x55,0x77,0x99,0x66,0x44,0x88,0x11};
|
||||
uint8 rx_buf[8];
|
||||
struct BusBlockWriteParam cfx = {
|
||||
.pos = 0,
|
||||
.buffer = buf,
|
||||
.size = 8
|
||||
};
|
||||
|
||||
|
||||
uint8 rx_buf[8] = {0};
|
||||
struct BusBlockReadParam read_param = {
|
||||
.pos = 0,
|
||||
.buffer =rx_buf ,
|
||||
.read_length =0
|
||||
};
|
||||
|
||||
|
||||
static struct CanDriverConfigure can_defconfig = {
|
||||
.tsjw = 0,
|
||||
.tbs2 = 5 ,
|
||||
.tbs1 = 6,
|
||||
.brp = 6,
|
||||
.mode = 0
|
||||
};
|
||||
|
||||
struct BusConfigureInfo configure_info ={
|
||||
.configure_cmd = 0,
|
||||
.private_data = &can_defconfig
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int _CanTestSend(const char *bus_name, const char *driver_name, const char *device_name0)
|
||||
{
|
||||
int i;
|
||||
struct Bus *bus;
|
||||
struct Driver *driver, *bus_driver;
|
||||
struct HardwareDev *device0, *device1;
|
||||
struct HardwareDev *bus_device0;
|
||||
|
||||
if(bus_name)
|
||||
{
|
||||
bus = BusFind(bus_name);
|
||||
KPrintf("##test bus %p##\n", bus);
|
||||
}
|
||||
|
||||
if(driver_name)
|
||||
{
|
||||
driver = CanDriverFind(driver_name, TYPE_CAN_DRV);
|
||||
bus_driver = BusFindDriver(bus, driver_name);
|
||||
KPrintf("##test driver %p bus_driver %p##\n", driver, bus_driver);
|
||||
}
|
||||
|
||||
if(device_name0)
|
||||
{
|
||||
device0 = CanDeviceFind(device_name0, TYPE_CAN_DEV);
|
||||
bus_device0 = BusFindDevice(bus, device_name0);
|
||||
KPrintf("####test device0 %p bus_device0 %p####\n", device0, bus_device0);
|
||||
KPrintf("####test device0 private %p\n", device0->private_data);
|
||||
}
|
||||
|
||||
BusDrvConfigure(bus_driver, &configure_info);
|
||||
|
||||
while(1)
|
||||
{
|
||||
BusDevWriteData(device0, &cfx);
|
||||
uint8 * buf =(uint8 *) cfx.buffer;
|
||||
KPrintf("send:");
|
||||
for(i = 0;i<cfx.size;i++)
|
||||
KPrintf("0x%2x ", buf[i]);
|
||||
KPrintf("\n");
|
||||
MdelayKTask(2000);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void CanTestSend(void)
|
||||
{
|
||||
_CanTestSend(CAN_BUS_NAME_1,CAN_DRIVER_NAME,CAN_1_DEVICE_NAME_1);
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),CanTestSend, CanTestSend, Close AC task );
|
||||
|
||||
|
||||
|
||||
|
||||
static int _CanTestRecv(const char *bus_name, const char *driver_name, const char *device_name0)
|
||||
{
|
||||
int len ,i;
|
||||
struct Bus *bus;
|
||||
struct Driver *driver, *bus_driver;
|
||||
struct HardwareDev *device0, *device1;
|
||||
struct HardwareDev *bus_device0;
|
||||
|
||||
if(bus_name)
|
||||
{
|
||||
KPrintf("####test find bus %s\n", bus_name);
|
||||
bus = BusFind(bus_name);
|
||||
KPrintf("####test bus %p####\n", bus);
|
||||
}
|
||||
|
||||
if(driver_name)
|
||||
{
|
||||
KPrintf("####test find driver %s\n", driver_name);
|
||||
driver = CanDriverFind(driver_name, TYPE_CAN_DRV);
|
||||
bus_driver = BusFindDriver(bus, driver_name);
|
||||
KPrintf("####test driver %p bus_driver %p####\n", driver, bus_driver);
|
||||
}
|
||||
|
||||
if(device_name0)
|
||||
{
|
||||
KPrintf("####test find device0 %s\n", device_name0);
|
||||
device0 = CanDeviceFind(device_name0, TYPE_CAN_DEV);
|
||||
bus_device0 = BusFindDevice(bus, device_name0);
|
||||
KPrintf("####test device0 %p bus_device0 %p####\n", device0, bus_device0);
|
||||
KPrintf("####test device0 private %p\n", device0->private_data);
|
||||
}
|
||||
|
||||
BusDrvConfigure(bus_driver, &configure_info);
|
||||
|
||||
while(1)
|
||||
{
|
||||
len = BusDevReadData(bus_device0,&read_param);
|
||||
if(0 != len)
|
||||
{
|
||||
for(i = 0; i<len;i++)
|
||||
KPrintf("0x%02x ", rx_buf[i]);
|
||||
KPrintf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
MdelayKTask(100);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void CanTestRecv(void)
|
||||
{
|
||||
_CanTestRecv(CAN_BUS_NAME_1,CAN_DRIVER_NAME,CAN_1_DEVICE_NAME_1);
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),CanTestRecv, CanTestRecv, Close AC task );
|
||||
|
||||
131
kernel/kernel_test/test_ch438.c
Normal file
131
kernel/kernel_test/test_ch438.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestCh438.c
|
||||
* @brief support to test ch438 function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
#include "board.h"
|
||||
#include "connect_ch438.h"
|
||||
|
||||
#if defined BOARD_AIIT_RISCV_EVB
|
||||
#define EXT_UART_NO 2
|
||||
#elif defined BOARD_STM32F407_EVB
|
||||
#define EXT_UART_NO 4
|
||||
#endif
|
||||
|
||||
#define DATA_BUFF_SIZE 255
|
||||
|
||||
static struct Bus *bus;
|
||||
static struct HardwareDev *dev;
|
||||
static struct Driver *drv;
|
||||
|
||||
|
||||
static void Ch438Read(void *parameter)
|
||||
{
|
||||
uint8 RevLen;
|
||||
uint8 ext_uart_no = EXT_UART_NO;
|
||||
uint8 i;
|
||||
uint16 vol, cur, pwr;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
static uint8 Ch438Buff[8][DATA_BUFF_SIZE];
|
||||
|
||||
while (1)
|
||||
{
|
||||
MdelayKTask(100);
|
||||
|
||||
read_param.buffer = Ch438Buff[ext_uart_no];
|
||||
RevLen = BusDevReadData(dev, &read_param);
|
||||
|
||||
vol = ((uint16)Ch438Buff[ext_uart_no][3] << 8) | Ch438Buff[ext_uart_no][4];
|
||||
cur = ((uint16)Ch438Buff[ext_uart_no][5] << 8) | Ch438Buff[ext_uart_no][6];
|
||||
pwr = ((uint16)Ch438Buff[ext_uart_no][7] << 8) | Ch438Buff[ext_uart_no][8];
|
||||
KPrintf("Board voltage : %d.%d V current : %d mA power : %d.%03d W\n", vol/10, vol%10, cur, pwr/1000, pwr%1000);
|
||||
|
||||
for(i = 0 ; i < DATA_BUFF_SIZE; i ++) {
|
||||
Ch438Buff[ext_uart_no][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Ch438Write(void *parameter)
|
||||
{
|
||||
x_err_t result;
|
||||
uint8 MeterInstruction[8] = {0x01, 0x04, 0x00, 0x00, 0x00, 0x03, 0xB0, 0x0B};
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
write_param.buffer = MeterInstruction;
|
||||
write_param.size = 8;
|
||||
|
||||
while (1)
|
||||
{
|
||||
MdelayKTask(1000);
|
||||
KPrintf("\n");
|
||||
BusDevWriteData(dev, &write_param);
|
||||
}
|
||||
}
|
||||
|
||||
static void TestCh438Init(void)
|
||||
{
|
||||
x_err_t flag;
|
||||
|
||||
struct BusConfigureInfo configure_info;
|
||||
|
||||
bus = BusFind(CH438_BUS_NAME);
|
||||
drv = BusFindDriver(bus, CH438_DRIVER_NAME);
|
||||
|
||||
#if defined BOARD_AIIT_RISCV_EVB
|
||||
dev = BusFindDevice(bus, CH438_DEVICE_NAME_2);
|
||||
#elif defined BOARD_STM32F407_EVB
|
||||
dev = BusFindDevice(bus, CH438_DEVICE_NAME_4);
|
||||
#endif
|
||||
|
||||
struct SerialCfgParam serial_cfg;
|
||||
memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
|
||||
configure_info.configure_cmd = OPE_INT;
|
||||
configure_info.private_data = (void *)&serial_cfg;
|
||||
|
||||
serial_cfg.data_cfg.port_configure = PORT_CFG_INIT;
|
||||
|
||||
serial_cfg.data_cfg.ext_uart_no = EXT_UART_NO;
|
||||
serial_cfg.data_cfg.serial_baud_rate = 9600;
|
||||
BusDrvConfigure(drv, &configure_info);
|
||||
|
||||
int32 task_CH438_read = KTaskCreate("task_CH438_read", Ch438Read, NONE, 2048, 10);
|
||||
flag = StartupKTask(task_CH438_read);
|
||||
if (flag != EOK) {
|
||||
KPrintf("StartupKTask task_CH438_read failed .\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
int32 task_CH438_write = KTaskCreate("task_CH438_write", Ch438Write, NONE, 2048, 10);
|
||||
flag = StartupKTask(task_CH438_write);
|
||||
if (flag != EOK) {
|
||||
KPrintf("StartupKTask task_CH438_write failed .\n");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
void TestCh438(void)
|
||||
{
|
||||
TestCh438Init();
|
||||
MdelayKTask(500);
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
TestCh438, TestCh438, TestCh438 );
|
||||
160
kernel/kernel_test/test_circulararea.c
Normal file
160
kernel/kernel_test/test_circulararea.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestCirculararea.c
|
||||
* @brief support to test circular area function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <string.h>
|
||||
#ifdef KERNEL_CIRCULAR_AREA
|
||||
|
||||
#define READ_LENGTH 2
|
||||
#define Write_LENGTH 3
|
||||
#define CIRCULARAREA_LENGTH 8
|
||||
|
||||
static struct CircularArea *g_circular_area;
|
||||
static int8 test_string[] = "Aiit-XiuOs";
|
||||
|
||||
static int32 task_caread;
|
||||
static int32 task_cawrite;
|
||||
|
||||
int data_lock = -1;
|
||||
|
||||
static void CircularArea_ReadTsk_Entry(void *parameter)
|
||||
{
|
||||
uint8 i;
|
||||
uint8 read_string[8] = {0};
|
||||
uint8 read_cnt = 0;
|
||||
|
||||
while(read_cnt < 30)
|
||||
{
|
||||
KMutexObtain(data_lock, WAITING_FOREVER);
|
||||
|
||||
if(EOK == g_circular_area->CircularAreaOperations->read(g_circular_area, read_string, READ_LENGTH)){
|
||||
for(i = 0; i < READ_LENGTH; i ++){
|
||||
KPrintf("Read data i %u ch %c rdidx %u wridx %u\n", i, read_string[i], g_circular_area->readidx, g_circular_area->writeidx);
|
||||
}
|
||||
|
||||
#ifdef Test_Dbg
|
||||
KPrintf("Read TSK writeidx %u readidx %u status %u len %u\n",
|
||||
g_circular_area->writeidx,
|
||||
g_circular_area->readidx,
|
||||
g_circular_area->b_status,
|
||||
CircularAreaGetDataLength(g_circular_area));
|
||||
#endif
|
||||
}
|
||||
|
||||
read_cnt++;
|
||||
MdelayKTask(500);
|
||||
|
||||
KMutexAbandon(data_lock);
|
||||
}
|
||||
|
||||
KMutexDelete(data_lock);
|
||||
KTaskDelete(task_caread);
|
||||
g_circular_area->CircularAreaOperations->release(g_circular_area);
|
||||
}
|
||||
|
||||
static void CircularAreaWriteTskEntry(void *parameter)
|
||||
{
|
||||
uint8 i;
|
||||
uint8 write_cnt = 0;
|
||||
uint8 string_length = strlen(test_string);
|
||||
static uint32 single_write_length = 0;
|
||||
|
||||
while(write_cnt < 30)
|
||||
{
|
||||
KMutexObtain(data_lock, WAITING_FOREVER);
|
||||
|
||||
uint8 write_string[CIRCULARAREA_LENGTH] = {0};
|
||||
if((write_cnt % string_length + Write_LENGTH) > string_length){
|
||||
memcpy(write_string, &test_string[write_cnt % string_length], string_length - write_cnt % string_length);
|
||||
memcpy(&write_string[string_length - write_cnt % string_length], test_string, Write_LENGTH - string_length + write_cnt % string_length);
|
||||
}
|
||||
else{
|
||||
memcpy(write_string, &test_string[write_cnt % string_length], Write_LENGTH);
|
||||
}
|
||||
|
||||
if(EOK == g_circular_area->CircularAreaOperations->write(g_circular_area, write_string, Write_LENGTH, 0))
|
||||
{
|
||||
for(i = 0; i < Write_LENGTH; i ++) {
|
||||
KPrintf("Write data i %d ch %c rdidx %u wridx %u\n", i, write_string[i], g_circular_area->readidx, g_circular_area->writeidx);
|
||||
}
|
||||
write_cnt += (g_circular_area->writeidx - single_write_length + CIRCULARAREA_LENGTH) % CIRCULARAREA_LENGTH;
|
||||
single_write_length = g_circular_area->writeidx;
|
||||
}
|
||||
|
||||
#ifdef Test_Dbg
|
||||
KPrintf("Write TSK writeidx %u readidx %u status %u len %u\n",
|
||||
g_circular_area->writeidx,
|
||||
g_circular_area->readidx,
|
||||
g_circular_area->b_status,
|
||||
CircularAreaGetDataLength(g_circular_area));
|
||||
#endif
|
||||
MdelayKTask(500);
|
||||
|
||||
KMutexAbandon(data_lock);
|
||||
}
|
||||
|
||||
KTaskDelete(task_cawrite);
|
||||
}
|
||||
|
||||
static uint32 TestCirculararea(void)
|
||||
{
|
||||
x_err_t flag;
|
||||
|
||||
g_circular_area = CircularAreaInit(CIRCULARAREA_LENGTH);
|
||||
if(g_circular_area){
|
||||
KPrintf("CircularAreaInit done buffer 0x%8p length %u phead 0x%8p ptail 0x%8p wridx %u rdidx %u\n",
|
||||
g_circular_area->data_buffer, g_circular_area->area_length,
|
||||
g_circular_area->p_head, g_circular_area->p_tail,
|
||||
g_circular_area->writeidx, g_circular_area->readidx);
|
||||
}
|
||||
else{
|
||||
KPrintf("CircularAreaInit failed!Just return\n");
|
||||
CircularAreaRelease(g_circular_area);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
data_lock = KMutexCreate();
|
||||
if (data_lock < 0){
|
||||
KPrintf("data_lock creat failed.\n");
|
||||
g_circular_area->CircularAreaOperations->release(g_circular_area);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
task_caread = KTaskCreate("task_caread", CircularArea_ReadTsk_Entry, NONE, 2048, 10);
|
||||
flag = StartupKTask(task_caread);
|
||||
if (EOK != flag){
|
||||
KPrintf("CircularArea_Test StartupKTask task_caread failed!\n");
|
||||
g_circular_area->CircularAreaOperations->release(g_circular_area);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
task_cawrite = KTaskCreate("task_cawrite", CircularAreaWriteTskEntry, NONE, 2048, 10);
|
||||
flag = StartupKTask(task_cawrite);
|
||||
if (EOK != flag){
|
||||
KPrintf("CircularArea_Test StartupKTask task_cawrite failed!\n");
|
||||
g_circular_area->CircularAreaOperations->release(g_circular_area);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),
|
||||
TestCirculararea, TestCirculararea, Test the Circular Area Function);
|
||||
#endif
|
||||
40
kernel/kernel_test/test_dbg.c
Normal file
40
kernel/kernel_test/test_dbg.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestDbg.c
|
||||
* @brief support to test dbg function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
#define KDBG_TEST1 1
|
||||
#define KDBG_TEST2 0
|
||||
|
||||
static uint32 TestDbg(void)
|
||||
{
|
||||
x_err_t flag;
|
||||
|
||||
SYS_WARN("TestDbg function 1!\n");
|
||||
SYS_ERR("TestDbg function 2!\n");
|
||||
DBG("TestDbg function 3!\n");
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_TEST1, ("TestDbg kernel function 1!\n"));
|
||||
SYS_KDEBUG_LOG(KDBG_TEST2, ("TestDbg kernel function 2!\n"));
|
||||
|
||||
return EOK;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),
|
||||
TestDbg, TestDbg, Test the log debug Function);
|
||||
570
kernel/kernel_test/test_gatherblock.c
Normal file
570
kernel/kernel_test/test_gatherblock.c
Normal file
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_gatherblock.c
|
||||
* @brief support to test gather block function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <string.h>
|
||||
|
||||
extern long ShowMemPool(void);
|
||||
extern void ShowMemory(void);
|
||||
extern void ListBuddy(void);
|
||||
/**************************single gatherblock test sample***********************************/
|
||||
static uint8 *ptr[30];
|
||||
static uint8 mempool[2048];
|
||||
static struct MemGather gm;
|
||||
static GatherMemType gm_d;
|
||||
|
||||
#define TASK_PRIORITY 25
|
||||
#define TASK_STACK_SIZE 2048
|
||||
#define TASK_TIMESLICE 5
|
||||
|
||||
/* thread control pointer */
|
||||
static int32 tid1;
|
||||
static int32 tid2;
|
||||
|
||||
/* task1 entry */
|
||||
static void Task1GmAlloc(void *parameter)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < 30 ; i++){
|
||||
if (ptr[i] == NONE){
|
||||
/* alloc memory blocks for 50 times, if failed, suspend task1 and start task2 */
|
||||
if (0 == strncmp("static", parameter, strlen("static"))){
|
||||
ptr[i] = AllocBlockMemGather(&gm, WAITING_FOREVER);
|
||||
if (ptr[i] != NONE)
|
||||
KPrintf("task1: allocate No.%d from static gatherblock\n", i);
|
||||
}
|
||||
else{
|
||||
ptr[i] = AllocBlockMemGather(gm_d, WAITING_FOREVER);
|
||||
if (ptr[i] != NONE)
|
||||
KPrintf("task1: allocate No.%d from dynamic gatherblock\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* task2 entry, its priority is lower than task1 */
|
||||
static void Task2GmRelease(void *parameter)
|
||||
{
|
||||
int i;
|
||||
KPrintf("task2 try to release block\n");
|
||||
for (i = 0; i < 30 ; i++){
|
||||
DelayKTask(10);
|
||||
|
||||
/* release all memory blocks */
|
||||
if (ptr[i] != NONE){
|
||||
KPrintf("release block %d\n", i);
|
||||
FreeBlockMemGather(ptr[i]);
|
||||
ptr[i] = NONE;
|
||||
}
|
||||
}
|
||||
if (0 == strncmp("static", parameter, strlen("static"))) {
|
||||
KPrintf("**************** detach gatherblock test *****************\n");
|
||||
RemoveMemGather(&gm);
|
||||
} else {
|
||||
KPrintf("**************** delete gatherblock test *****************\n");
|
||||
DeleteMemGather(gm_d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SingleGatherblockTest(char * parameter)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 30; i ++) ptr[i] = NONE;
|
||||
/* init memory blocks object */
|
||||
if(0 == strncmp("static", parameter, strlen("static"))){
|
||||
KPrintf("test static create gatherblock.\n");
|
||||
InitMemGather(&gm, "mp_s", &mempool[0], sizeof(mempool), 80);
|
||||
ShowMemPool();
|
||||
}
|
||||
|
||||
if(0 == strncmp("dynamic", parameter, strlen("dynamic"))){
|
||||
KPrintf("test dynamic create gatherblock.\n");
|
||||
//FreeBlockMemGather(&mp, "mp1", &mempool[0], sizeof(mempool), 80);
|
||||
gm_d = CreateMemGather("mp_d",20,80);
|
||||
if(gm_d == NONE){
|
||||
KPrintf("%s: allocate failure.\n",__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ShowMemPool();
|
||||
}
|
||||
/* create task1, alloc memory blocks */
|
||||
tid1 = KTaskCreate("task1", Task1GmAlloc, parameter,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY);
|
||||
if (tid1 >= 0){
|
||||
KPrintf("single test: task1 startup.\n");
|
||||
StartupKTask(tid1);
|
||||
}
|
||||
|
||||
/* create task2, release memory blocks */
|
||||
tid2 = KTaskCreate("task2", Task2GmRelease, parameter,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY + 1);
|
||||
if (tid2 >= 0){
|
||||
StartupKTask(tid2);
|
||||
}
|
||||
else{
|
||||
KPrintf("create task2 for release failure.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************************/
|
||||
|
||||
|
||||
/**********************mutiple gatherblock test sample**************************************/
|
||||
struct MemGather s_gm1;
|
||||
struct MemGather *d_gm1 = NONE;
|
||||
|
||||
static uint8 mempool_gm1[1024];
|
||||
|
||||
#define MAX_SIZE 11
|
||||
#define TASK_PRIORITY 25
|
||||
#define TASK_STACK_SIZE 2048
|
||||
#define TASK_TIMESLICE 5
|
||||
|
||||
/* thread control pointer */
|
||||
static int32 m_tid1 = NONE;
|
||||
static int32 m_tid2 = NONE;
|
||||
|
||||
static uint8 *multiple_s_ptr[20];
|
||||
static uint8 *multiple_d_ptr[20];
|
||||
|
||||
void Task1AllocEntry(void *parameter){
|
||||
int index = 0;
|
||||
for(int i=0;i<20;i++){
|
||||
|
||||
multiple_s_ptr[i] = AllocBlockMemGather(&s_gm1, WAITING_FOREVER);
|
||||
if(multiple_s_ptr[i] != NONE){
|
||||
KPrintf("task1: allocate No.%d from static\n", i);
|
||||
}
|
||||
multiple_d_ptr[i] = AllocBlockMemGather(d_gm1, WAITING_FOREVER);
|
||||
|
||||
if (ptr[i] != NONE)
|
||||
KPrintf("task1: allocate No.%d from dynamic\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
void Task2FreeEntry(void *parameter){
|
||||
DelayKTask(100);
|
||||
for(int i=0;i<20;i++){
|
||||
|
||||
DelayKTask(10);
|
||||
if(multiple_s_ptr[i]){
|
||||
FreeBlockMemGather(multiple_s_ptr[i]);
|
||||
KPrintf("task2: free No.%d of static\n", i);
|
||||
}
|
||||
DelayKTask(10);
|
||||
if(multiple_d_ptr[i]){
|
||||
FreeBlockMemGather(multiple_d_ptr[i]);
|
||||
|
||||
KPrintf("task2: free No.%d of dynamic\n", i);
|
||||
}
|
||||
}
|
||||
KPrintf("**************** detach gatherblock test *****************\n");
|
||||
RemoveMemGather(&s_gm1);
|
||||
KPrintf("**************** delete gatherblock test *****************\n");
|
||||
DeleteMemGather(d_gm1);
|
||||
}
|
||||
|
||||
int MultipleGatherblockTest(void)
|
||||
{
|
||||
|
||||
KPrintf("****************mutiple gatherblock test start*****************\n");
|
||||
|
||||
for(int i=0;i<20;i++){
|
||||
multiple_s_ptr[i] = NONE;
|
||||
multiple_d_ptr[i] = NONE;
|
||||
}
|
||||
|
||||
InitMemGather(&s_gm1, "m_gm_s1", &mempool_gm1[0], sizeof(mempool_gm1), 80);
|
||||
|
||||
d_gm1 = CreateMemGather("m_gm_d1", MAX_SIZE, 80);
|
||||
if (mempool_gm1 == NONE){
|
||||
KPrintf("create m_gm_d2 failed.");
|
||||
CHECK(0);
|
||||
}
|
||||
ShowMemPool();
|
||||
|
||||
/* create task1, alloc memory blocks */
|
||||
m_tid1 = KTaskCreate("task1_m", Task1AllocEntry, NONE,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY);
|
||||
if (m_tid1 >= 0){
|
||||
StartupKTask(m_tid1);
|
||||
}
|
||||
|
||||
/* create task2, release memory blocks */
|
||||
m_tid2 = KTaskCreate("task2_m", Task2FreeEntry, NONE,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY + 1);
|
||||
if (m_tid2 >= 0){
|
||||
StartupKTask(m_tid2);
|
||||
}
|
||||
else{
|
||||
KPrintf("create task2 for release failure.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**************************************************************************************/
|
||||
|
||||
/* thread control pointer */
|
||||
static int32 l_tid1 = NONE;
|
||||
static int32 l_tid2 = NONE;
|
||||
struct MemGather *gm_l = NONE;
|
||||
void *l_ptr[50];
|
||||
|
||||
void LTask1AllocEntry(void *parameter){
|
||||
int index = 0;
|
||||
for(int i=0;i<50;i++){
|
||||
l_ptr[i] = AllocBlockMemGather(gm_l, WAITING_FOREVER);
|
||||
if(l_ptr[i] != NONE){
|
||||
KPrintf("l_task1: allocate No.%d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LTask2FreeEntry(void *parameter){
|
||||
DelayKTask(100);
|
||||
for(int i=0;i<50;i++){
|
||||
DelayKTask(10);
|
||||
if(l_ptr[i]){
|
||||
FreeBlockMemGather(l_ptr[i]);
|
||||
KPrintf("l_task2: free No.%d\n", i);
|
||||
}
|
||||
}
|
||||
KPrintf("**************** delete gatherblock test *****************\n");
|
||||
DeleteMemGather(gm_l);
|
||||
}
|
||||
|
||||
|
||||
void GatherblockLimitTest(char *name, int count, int blocksize){
|
||||
gm_l = CreateMemGather(name, count, blocksize);
|
||||
if(gm_l == NONE){
|
||||
KPrintf("no memory.\n");
|
||||
return;
|
||||
}
|
||||
ListBuddy();
|
||||
/* create task1, alloc memory blocks */
|
||||
l_tid1 = KTaskCreate("task1_l", LTask1AllocEntry, NONE,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY);
|
||||
if (l_tid1 >= 0){
|
||||
StartupKTask(l_tid1);
|
||||
}
|
||||
|
||||
/* create task2, release memory blocks */
|
||||
l_tid2 = KTaskCreate("task2_l", LTask2FreeEntry, NONE,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY + 1);
|
||||
if (l_tid2 >= 0){
|
||||
StartupKTask(l_tid2);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ARCH_ARM
|
||||
#define CACHE_COUNT 1024
|
||||
#else
|
||||
#define CACHE_COUNT 8000
|
||||
#endif
|
||||
|
||||
struct MemGather *pools[CACHE_COUNT];
|
||||
void GatherblockLimitcountTest(char *name, int count, int blocksize, int poolcount){
|
||||
if(poolcount>CACHE_COUNT || poolcount<=0){
|
||||
KPrintf("type the poolcount between 0-%d\n",CACHE_COUNT);
|
||||
return;
|
||||
}
|
||||
int index;
|
||||
for(index=0;index < poolcount;index++){
|
||||
pools[index] = CreateMemGather(name, count, blocksize);
|
||||
if(pools[index] == NONE){
|
||||
KPrintf("gatherblock allocation failure,count[%d],size[%d]\n", count, blocksize);
|
||||
break;
|
||||
}
|
||||
KPrintf("gatherblock allocation,count[%d],size[%d]\n", count, blocksize);
|
||||
}
|
||||
ListBuddy();
|
||||
|
||||
index--;
|
||||
for(;index>=0;index--){
|
||||
DeleteMemGather(pools[index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
static int32 traverse_tid = NONE;
|
||||
static struct MemGather *traverse_gm = NONE;
|
||||
|
||||
void TraverseGmEntry(void *parameter){
|
||||
int count,size;
|
||||
int limit_count, limit_size;
|
||||
|
||||
for(count =1; count <= 30; count++){
|
||||
for(size = 1; ;size++){
|
||||
traverse_gm = CreateMemGather("hello",count,size);
|
||||
if( traverse_gm == NONE ){
|
||||
KPrintf("gatherblock allocation failure,count[%d],size[%d]\n", count, size);
|
||||
|
||||
if(count == 1)
|
||||
limit_size = size;
|
||||
break;
|
||||
}else{
|
||||
DeleteMemGather(traverse_gm);
|
||||
}
|
||||
}
|
||||
if(size ==1){
|
||||
limit_count = count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
KPrintf("\n\n--------------------------- bound -----------------------------\n\n");
|
||||
KPrintf("\n\n--------------------------- over end -----------------------------\n\n");
|
||||
}
|
||||
|
||||
#define TRAVERSE_TASK_PRIORITY 5
|
||||
void TraverseGmTest(){
|
||||
|
||||
traverse_tid = KTaskCreate("traverse_task", TraverseGmEntry, NONE,
|
||||
TASK_STACK_SIZE ,
|
||||
TRAVERSE_TASK_PRIORITY);
|
||||
if(traverse_tid >= 0){
|
||||
StartupKTask(traverse_tid);
|
||||
}else{
|
||||
KPrintf("Fail.\n");
|
||||
}
|
||||
}
|
||||
/********************************************************************/
|
||||
/***************************test random read and write **************/
|
||||
static uint8 *random_ptr[50];
|
||||
static struct MemGather random_static_gm;
|
||||
static GatherMemType random_dynamic_gm;
|
||||
static uint8 dynamic_mempool[2048];
|
||||
|
||||
/* thread control pointer */
|
||||
static int32 random_tid1 = NONE;
|
||||
static int32 random_tid2 = NONE;
|
||||
/* task1 entry */
|
||||
int time_seed = 1;
|
||||
char temp_parameter[40];
|
||||
|
||||
static void RandomTask1GmAlloc(void *parameter)
|
||||
{
|
||||
int i;
|
||||
int total=0;
|
||||
time_seed++;
|
||||
srand(time_seed);
|
||||
char string[10];
|
||||
|
||||
while(total<40){
|
||||
i = rand()%40;
|
||||
if (random_ptr[i] == NONE){
|
||||
/* alloc memory blocks for 50 times, if failed, suspend task1 and start task2 */
|
||||
if (0 == strncmp("static", temp_parameter, strlen("static"))){
|
||||
random_ptr[i] = AllocBlockMemGather(&random_static_gm, WAITING_FOREVER);
|
||||
if (random_ptr[i] != NONE){
|
||||
itoa(i,string,10);
|
||||
memcpy(random_ptr[i],string,sizeof(string));
|
||||
KPrintf("%s No.%d: %s\n",temp_parameter, i, random_ptr[i]);
|
||||
}
|
||||
}else{
|
||||
random_ptr[i] = AllocBlockMemGather(random_dynamic_gm, WAITING_FOREVER);
|
||||
if (random_ptr[i] != NONE){
|
||||
itoa(i,string,10);
|
||||
memcpy(random_ptr[i],string,sizeof(string));
|
||||
KPrintf("%s No.%d: %s\n", temp_parameter, i, random_ptr[i]);
|
||||
}
|
||||
}
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* task2 entry, its priority is lower than task1 */
|
||||
static void RandomTask2GmRelease(void *parameter)
|
||||
{
|
||||
int i;
|
||||
time_seed++;
|
||||
srand(time_seed);
|
||||
|
||||
|
||||
int total = 0;
|
||||
|
||||
while(total<40){
|
||||
i = rand()%40;
|
||||
|
||||
/* release all memory blocks */
|
||||
if (random_ptr[i] != NONE){
|
||||
DelayKTask(10);
|
||||
KPrintf("release block %d: %s\n",i, random_ptr[i]);
|
||||
FreeBlockMemGather(random_ptr[i]);
|
||||
random_ptr[i] = NONE;
|
||||
total++;
|
||||
}
|
||||
}
|
||||
if (0 == strncmp("static", temp_parameter, strlen("static"))) {
|
||||
KPrintf("**************** detach gatherblock test *****************\n");
|
||||
RemoveMemGather(&random_static_gm);
|
||||
} else {
|
||||
KPrintf("**************** delete gatherblock test *****************\n");
|
||||
DeleteMemGather(random_dynamic_gm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int RandomAllocFreeTest(void *parameter)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 40; i ++) random_ptr[i] = NONE;
|
||||
memcpy(temp_parameter,parameter, 10);
|
||||
/* init memory block object */
|
||||
if(0 == strncmp("static", parameter, strlen("static"))){
|
||||
KPrintf("test static create gatherblock-%s.\n",parameter);
|
||||
InitMemGather(&random_static_gm, "ran_mp_s", &dynamic_mempool[0], sizeof(dynamic_mempool), 80);
|
||||
ShowMemPool();
|
||||
}else{
|
||||
KPrintf("test dynamic create gatherblock.\n");
|
||||
random_dynamic_gm = CreateMemGather("ran_mp_d",40,80);
|
||||
if(random_dynamic_gm == NONE){
|
||||
KPrintf("%s: allocate failure.\n",__func__);
|
||||
return -1;
|
||||
}
|
||||
ShowMemPool();
|
||||
}
|
||||
/* create task1, alloc memory blocks */
|
||||
random_tid1 = KTaskCreate("r_task1", RandomTask1GmAlloc, parameter,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY);
|
||||
if (random_tid1 >= 0){
|
||||
StartupKTask(random_tid1);
|
||||
}
|
||||
|
||||
/* create task2, release memory blocks */
|
||||
random_tid2 = KTaskCreate("r_task2", RandomTask2GmRelease, parameter,
|
||||
TASK_STACK_SIZE,
|
||||
TASK_PRIORITY + 1);
|
||||
if (random_tid2 >= 0){
|
||||
StartupKTask(random_tid2);
|
||||
}
|
||||
else{
|
||||
KPrintf("create task2 for release failure.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************/
|
||||
void TestGatherblockUsage(void)
|
||||
{
|
||||
KPrintf("TestGatherblockUsage.\n");
|
||||
KPrintf("test_main gm -a --static, dynamic and multiple test.\n");
|
||||
KPrintf("test_main gm -s static/dynamic --test static create gatherblock to allocate and free.\n");
|
||||
KPrintf("test_main gm -m --test multiple gatherblock to allocate and free.\n");
|
||||
KPrintf("test_main gm count_size [count] [size] --create a gatherblock with typed count and size "
|
||||
"to allocate and free.\n");
|
||||
KPrintf("test_main gm multiple_gms [count] [size] [gm_ns] --create multiple gatherblocks with typed count and \n");
|
||||
KPrintf(" size to allocate and free.\n");
|
||||
KPrintf("test_main gm traverse --traverse.\n");
|
||||
KPrintf("test_main gm -r static/dynamic --random allocate and free.\n");
|
||||
|
||||
}
|
||||
|
||||
int TestGatherblock(char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (NONE == argv || 0 == strncmp("-h", argv[0], strlen("-h")) || 0 == strncmp("usage", argv[0], strlen("usage"))) {
|
||||
TestGatherblockUsage();
|
||||
return -EINVALED;
|
||||
}
|
||||
/**************** gatherblock auto test ******************/
|
||||
if (0 == strncmp("-a", argv[0], strlen("-a"))) {
|
||||
ret = SingleGatherblockTest("static"); ///< static creat single gatherblock test
|
||||
MdelayKTask(7000);
|
||||
ret |= SingleGatherblockTest("dynamic"); ///< dynamic creat single gatherblock test
|
||||
MdelayKTask(7000);
|
||||
ret |= MultipleGatherblockTest();
|
||||
MdelayKTask(7000);
|
||||
ret |= RandomAllocFreeTest("static");
|
||||
MdelayKTask(7000);
|
||||
ret |= RandomAllocFreeTest("dynamic");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**************** single gatherblock test ****************/
|
||||
if (0 == strncmp("-s",argv[0],strlen("-s")) ) {
|
||||
if (0 == strncmp("static",argv[1],strlen("static"))) {
|
||||
ret = SingleGatherblockTest("static"); ///< static creat single gatherblock test
|
||||
} else {
|
||||
ret = SingleGatherblockTest("dynamic"); ///< dynamic creat single gatherblock test
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**************** mutiple gatherblock test ****************/
|
||||
if (0 == strncmp("-m",argv[0],strlen("-m")) ) {
|
||||
ret = MultipleGatherblockTest();
|
||||
goto out;
|
||||
}
|
||||
/******************** limitation test **********************/
|
||||
if (0 == strncmp("count_size",argv[0],strlen("count_size")) ) {
|
||||
int size = atoi(argv[2]);
|
||||
int count = atoi(argv[1]);
|
||||
GatherblockLimitTest("xsos",count,size);
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/******************** limitation test **********************/
|
||||
if (0 == strncmp("multiple_gms",argv[0],strlen("multiple_gms")) ) {
|
||||
int size = atoi(argv[2]);
|
||||
int count = atoi(argv[1]);
|
||||
int poolnumber = atoi(argv[3]);
|
||||
GatherblockLimitcountTest("xsos",count,size,poolnumber);
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/********************** traverse test **********************/
|
||||
if (0 == strncmp("traverse",argv[0],strlen("traverse")) ) {
|
||||
TraverseGmTest();
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**************** random alloc and free test ****************/
|
||||
if (0 == strncmp("-r",argv[0],strlen("-r")) ) {
|
||||
ret = RandomAllocFreeTest(argv[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
KPrintf("test gatherblock failed ret = %d.\n",ret);
|
||||
return -ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
74
kernel/kernel_test/test_hwtimer.c
Normal file
74
kernel/kernel_test/test_hwtimer.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_hwtimer.c
|
||||
* @brief support to test hwtimer function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <bus.h>
|
||||
#include <xsconfig.h>
|
||||
#include <dev_hwtimer.h>
|
||||
|
||||
#if defined (ARCH_ARM)
|
||||
#define HWTIMER_BUS_NAME HWTIMER_BUS_NAME_2
|
||||
#define HWTIMER_DEVICE_NAME HWTIMER_2_DEVICE_NAME_2
|
||||
#elif defined (ARCH_RISCV)
|
||||
#define HWTIMER_BUS_NAME HWTIMER_BUS_NAME_1
|
||||
#define HWTIMER_DEVICE_NAME HWTIMER_1_DEVICE_NAME_1
|
||||
#elif
|
||||
#define HWTIMER_BUS_NAME
|
||||
#define HWTIMER_DEVICE_NAME
|
||||
#endif
|
||||
|
||||
void TimeoutCb(void* param){
|
||||
KPrintf("resource_sample callback come ... \n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void HwtimerSample(void)//int argc, char *argv[]
|
||||
{
|
||||
struct Bus * hwtimer_bus = BusFind(HWTIMER_BUS_NAME);
|
||||
if (NULL == hwtimer_bus){
|
||||
KPrintf("hwtimer bus find failed !\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
struct HardwareDev* dev = BusFindDevice(hwtimer_bus, HWTIMER_DEVICE_NAME);
|
||||
struct HwtimerHardwareDevice* hwtimer_dev = (struct HwtimerHardwareDevice*)dev;
|
||||
if (NULL == hwtimer_dev){
|
||||
KPrintf("hwtimer hwtimer_dev find failed !\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
hwtimer_dev->hwtimer_param.repeat = 1;
|
||||
hwtimer_dev->hwtimer_param.period_millisecond = 3000;
|
||||
hwtimer_dev->hwtimer_param.cb_info.param = NULL;
|
||||
hwtimer_dev->hwtimer_param.cb_info.TimeoutCb = TimeoutCb;
|
||||
|
||||
BusDevOpen(dev);
|
||||
|
||||
MdelayKTask(20000);
|
||||
|
||||
KPrintf("close hwtimer...\n");
|
||||
BusDevClose(dev);
|
||||
|
||||
}
|
||||
/* export to shell cmd */
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_DISABLE_RETURN|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
HwtimerSample, HwtimerSample, HwtimerSample );
|
||||
178
kernel/kernel_test/test_i2c.c
Normal file
178
kernel/kernel_test/test_i2c.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_i2c.c
|
||||
* @brief support to test i2c function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
#include <bus.h>
|
||||
|
||||
/*********************************************************************************************************************************************************/
|
||||
/*
|
||||
* function:I2C device sample support reading temperature and humidity sensor data and printfing on the terminal
|
||||
* shell cmd:i2c_HS3000_sample i2c1
|
||||
* shell cmd param:i2c device name,if null means default i2c device name
|
||||
*/
|
||||
|
||||
#define HS_I2C_BUS_NAME I2C_BUS_NAME_1 /* I2C bus name */
|
||||
#define HS_I2C_DEV_NAME I2C_1_DEVICE_NAME_0/* I2C device name */
|
||||
#define HS_I2C_DRV_NAME I2C_DRV_NAME_1 /* I2C driver name */
|
||||
#define ADDR 0x44 /* slave address */
|
||||
|
||||
static struct Bus *i2c_bus = NONE; /* I2C bus handle */
|
||||
|
||||
typedef struct Hs300xData
|
||||
{
|
||||
int humi_high;
|
||||
int humi_low;
|
||||
int temp_high;
|
||||
int temp_low;
|
||||
}Hs300xDataType;
|
||||
|
||||
Hs300xDataType g_hs300x_data;
|
||||
|
||||
static x_err_t WriteReg(struct HardwareDev *dev)
|
||||
{
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
/* use I2C device API transfer data */
|
||||
if(1 == BusDevWriteData(dev, &write_param)) {
|
||||
return EOK;
|
||||
}
|
||||
else{
|
||||
return -ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* read sensor register data */
|
||||
static x_err_t ReadRegs(struct HardwareDev *dev, uint8 len, uint8 *buf)
|
||||
{
|
||||
struct BusBlockReadParam read_param;
|
||||
|
||||
read_param.buffer = (void *)buf;
|
||||
read_param.size = len;
|
||||
|
||||
/* use I2C device API transfer data */
|
||||
if(1 == BusDevReadData(dev, &read_param)){
|
||||
return EOK;
|
||||
}
|
||||
else{
|
||||
return -ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static void read_temp_humi(float *cur_temp, float *cur_humi)
|
||||
{
|
||||
uint8 temp[4],ret=0;
|
||||
MdelayKTask(15);
|
||||
ret = WriteReg(i2c_bus->owner_haldev); //reset
|
||||
if(EOK != ret){
|
||||
KPrintf("read_temp_humi WriteReg failed!\n");
|
||||
}
|
||||
MdelayKTask(50);
|
||||
ret = ReadRegs(i2c_bus->owner_haldev, 4, temp); /* get sensor data */
|
||||
if(EOK != ret){
|
||||
KPrintf("read_temp_humi ReadRegs failed\n");
|
||||
}
|
||||
|
||||
*cur_humi = ((temp[0] <<8 | temp[1] )& 0x3fff ) * 100.0 / ( (1 << 14) - 1); /* humidity data */
|
||||
|
||||
*cur_temp = ((temp[2] << 8 | temp[3]) >> 2) * 165.0 /( (1 << 14) - 1) - 40.0; /* temperature data */
|
||||
}
|
||||
|
||||
static void _HS3000Init(const char *bus_name, const char *dev_name, const char *drv_name)
|
||||
{
|
||||
/* find I2C device and get I2C handle */
|
||||
i2c_bus = BusFind(bus_name);
|
||||
if (NONE == i2c_bus){
|
||||
KPrintf("_HS3000Init can't find %s bus!\n", bus_name);
|
||||
}
|
||||
else{
|
||||
KPrintf("_HS3000Init find %s bus!\n", bus_name);
|
||||
}
|
||||
|
||||
i2c_bus->owner_haldev = BusFindDevice(i2c_bus, dev_name);
|
||||
i2c_bus->owner_driver = BusFindDriver(i2c_bus, drv_name);
|
||||
|
||||
if(i2c_bus->match(i2c_bus->owner_driver, i2c_bus->owner_haldev)){
|
||||
KPrintf("i2c match drv %s %p dev %s %p error\n", drv_name, i2c_bus->owner_driver, dev_name, i2c_bus->owner_haldev);
|
||||
}
|
||||
else{
|
||||
KPrintf("_HS3000Init successfully!write %p read %p\n",
|
||||
i2c_bus->owner_haldev->dev_done->write,
|
||||
i2c_bus->owner_haldev->dev_done->read);
|
||||
}
|
||||
}
|
||||
|
||||
void Hs300xInit(void)
|
||||
{
|
||||
_HS3000Init(HS_I2C_BUS_NAME, HS_I2C_DEV_NAME, HS_I2C_DRV_NAME); /* init sensor */
|
||||
}
|
||||
|
||||
void Hs300xRead(Hs300xDataType *Hs300xDataType)
|
||||
{
|
||||
float humidity = 0.0, temperature = 0.0;
|
||||
read_temp_humi(&temperature, &humidity); /* read temperature and humidity sensor data */
|
||||
Hs300xDataType->humi_high = (int)humidity;
|
||||
Hs300xDataType->humi_low = (int)(humidity*10)%10;
|
||||
if( temperature >= 0 ) {
|
||||
Hs300xDataType->temp_high = (int)temperature;
|
||||
Hs300xDataType->temp_low = (int)(temperature*10)%10;
|
||||
}
|
||||
else{
|
||||
Hs300xDataType->temp_high = (int)temperature;
|
||||
Hs300xDataType->temp_low = (int)(-temperature*10)%10;
|
||||
}
|
||||
}
|
||||
|
||||
void Tsk_hs300x_test()
|
||||
{
|
||||
memset(&g_hs300x_data, 0, sizeof(Hs300xDataType));
|
||||
KPrintf("Tsk create successfully!\n");
|
||||
|
||||
while(1)
|
||||
{
|
||||
Hs300xRead(&g_hs300x_data);
|
||||
|
||||
KPrintf("HS300X:I2C humidity:%d.%d temperature:%d.%d\n",
|
||||
g_hs300x_data.humi_high,
|
||||
g_hs300x_data.humi_low,
|
||||
g_hs300x_data.temp_high,
|
||||
g_hs300x_data.temp_low);
|
||||
|
||||
MdelayKTask(1000);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Hs300xI2cTest(void)
|
||||
{
|
||||
Hs300xInit();
|
||||
MdelayKTask(1000);
|
||||
|
||||
x_err_t flag;
|
||||
int32 Tsk_hs300x = KTaskCreate("Tsk_hs300x", Tsk_hs300x_test, NONE, 2048, 10);
|
||||
flag = StartupKTask(Tsk_hs300x);
|
||||
if (EOK != flag){
|
||||
KPrintf("Hs300xI2cTest StartupKTask failed!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),
|
||||
Hs300xI2cTest, Hs300xI2cTest, Test the HS300X using I2C);
|
||||
67
kernel/kernel_test/test_iwg.c
Normal file
67
kernel/kernel_test/test_iwg.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestIwg.c
|
||||
* @brief support to test watchdog function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
|
||||
static BusType wdt;
|
||||
|
||||
/**
|
||||
* @description: Feed watchdog task function
|
||||
*/
|
||||
static void FeedWatchdog(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
/* keep watchdog alive in idle task */
|
||||
struct BusConfigureInfo cfg;
|
||||
cfg.configure_cmd = OPER_WDT_KEEPALIVE;
|
||||
cfg.private_data = NONE;
|
||||
BusDrvConfigure(wdt->owner_driver, &cfg);
|
||||
KPrintf("feed the dog!\n ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Watchdog test function
|
||||
* @return success: EOK, failure: other
|
||||
*/
|
||||
int TestIwg(void)
|
||||
{
|
||||
x_err_t res = EOK;
|
||||
uint32 timeout = 1000; /* timeout time */
|
||||
|
||||
wdt = BusFind(WDT_BUS_NAME_0);
|
||||
wdt->owner_driver = BusFindDriver(wdt, WDT_DRIVER_NAME_0);
|
||||
wdt->owner_haldev = BusFindDevice(wdt, WDT_0_DEVICE_NAME_0);
|
||||
|
||||
/* set watchdog timeout time */
|
||||
struct BusConfigureInfo cfg;
|
||||
cfg.configure_cmd = OPER_WDT_SET_TIMEOUT;
|
||||
cfg.private_data = &timeout;
|
||||
res = BusDrvConfigure(wdt->owner_driver, &cfg);
|
||||
KPrintf("feed the dog!\n");
|
||||
|
||||
int32 WdtTask = KTaskCreate("WdtTask", (void *)FeedWatchdog, NONE, 2048, 20);
|
||||
res = StartupKTask(WdtTask);
|
||||
|
||||
return res;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),TestIwg, TestIwg, TestIwg );
|
||||
99
kernel/kernel_test/test_lcd.c
Normal file
99
kernel/kernel_test/test_lcd.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file EnableLcd.c
|
||||
* @brief support to test lcd function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include "bus_lcd.h"
|
||||
#include "dev_lcd.h"
|
||||
|
||||
uint16 color = RED;
|
||||
|
||||
char *addr ="LCD Testing ";
|
||||
|
||||
/**
|
||||
* @description: Enable LCD function
|
||||
* @param bus_name - LCD bus name
|
||||
* @param driver_name - LCD driver name
|
||||
* @param device_name - LCD device name
|
||||
*/
|
||||
int EnableLcd(const char *bus_name, const char *driver_name, const char *device_name)
|
||||
{
|
||||
struct Bus *bus;
|
||||
struct Driver *driver, *bus_driver;
|
||||
struct HardwareDev *device;
|
||||
struct HardwareDev *bus_device;
|
||||
|
||||
|
||||
if (bus_name) {
|
||||
KPrintf("##test find bus %s\n", bus_name);
|
||||
bus = BusFind(bus_name);
|
||||
KPrintf("##test bus %p##\n", bus);
|
||||
}
|
||||
|
||||
if (driver_name) {
|
||||
KPrintf("##test find driver %s\n", driver_name);
|
||||
driver = LcdDriverFind(driver_name, TYPE_LCD_DRV);
|
||||
bus_driver = BusFindDriver(bus, driver_name);
|
||||
KPrintf("##test driver %p bus_driver %p####\n", driver, bus_driver);
|
||||
}
|
||||
|
||||
if (device_name) {
|
||||
KPrintf("##test find device %s\n", device_name);
|
||||
device = LcdDeviceFind(device_name, TYPE_LCD_DEV);
|
||||
bus_device = BusFindDevice(bus, device_name);
|
||||
KPrintf("##test device %p bus_device %p##\n", device, bus_device);
|
||||
}
|
||||
|
||||
LcdStringParam str;
|
||||
str.x_pos = 60 ;
|
||||
str.y_pos = 40;
|
||||
str.width = 250;
|
||||
str.height = 24;
|
||||
str.font_size = 24;
|
||||
str.addr = addr;
|
||||
str.font_color = WHITE;
|
||||
str.back_color = RED;
|
||||
|
||||
struct BusBlockWriteParam write_param;
|
||||
memset(&write_param,0,sizeof(struct BusBlockWriteParam ));
|
||||
|
||||
struct BusConfigureInfo pdata = {RED,NONE};
|
||||
|
||||
write_param.pos = 0;
|
||||
write_param.buffer = &str ;
|
||||
|
||||
while (1) {
|
||||
|
||||
BusDrvConfigure(bus_driver, &pdata );
|
||||
MdelayKTask(1000);
|
||||
|
||||
BusDevWriteData(device,&write_param);
|
||||
MdelayKTask(1000);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: LCD test function
|
||||
*/
|
||||
void TestLcd(void)
|
||||
{
|
||||
EnableLcd(LCD_BUS_NAME_1,LCD_DRV_NAME_1,LCD_1_DEVICE_NAME_0);
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),TestLcd, TestLcd, Test LCD );
|
||||
125
kernel/kernel_test/test_main.c
Normal file
125
kernel/kernel_test/test_main.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestMain.c
|
||||
* @brief support to test function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <stdio.h>
|
||||
#define MAX_ITEM_NAME_LENGTH 16
|
||||
extern int TestIwg(void);
|
||||
|
||||
int TestTmrD(void);
|
||||
int TestTmrM(void);
|
||||
|
||||
extern int TestTmr(int argc, char *argv[]);
|
||||
extern int TestMem(int argc, char *argv[]);
|
||||
extern int TestGatherblock(char *argv[]);
|
||||
extern int TestTaskReadyAndSched(int argc, char *argv[]);
|
||||
extern int TestRealtime(int argc, char * argv[]);
|
||||
|
||||
void KernelTestusage(void)
|
||||
{
|
||||
KPrintf("test usage.\n");
|
||||
KPrintf("e.g., TestMain -mem\n");
|
||||
}
|
||||
struct TestSubitem
|
||||
{
|
||||
char name[MAX_ITEM_NAME_LENGTH];
|
||||
int item;
|
||||
};
|
||||
|
||||
enum TestItem
|
||||
{
|
||||
USAGE = 0, /* usage idex */
|
||||
MEM, /* mem test item index */
|
||||
TIMER, /* timer test item index */
|
||||
GATHERBLOCK,
|
||||
SCHED, /* task sched test */
|
||||
IWG, /* iwg test item index */
|
||||
REALTIME,
|
||||
INVALID_ITEM, /* invalid index */
|
||||
};
|
||||
|
||||
static struct TestSubitem kernel_subitem[INVALID_ITEM] =
|
||||
{
|
||||
{ "-h", USAGE },
|
||||
{ "-mem", MEM },
|
||||
{ "-timer", TIMER},
|
||||
{ "-gm", GATHERBLOCK},
|
||||
{ "-sched", SCHED},
|
||||
{ "-iwg", IWG},
|
||||
{ "-realtime", REALTIME},
|
||||
|
||||
};
|
||||
|
||||
int TestMain(int argc, char*argv[])
|
||||
{
|
||||
char name[MAX_ITEM_NAME_LENGTH] = {0};
|
||||
int i = 0;
|
||||
int item = -1;
|
||||
|
||||
strncpy(name, argv[1], MAX_ITEM_NAME_LENGTH); ///< getting input name of test item
|
||||
for(i = 0; i < INVALID_ITEM; i++) {
|
||||
if(0 == strncmp(kernel_subitem[i].name, name, MAX_ITEM_NAME_LENGTH) ){
|
||||
item = kernel_subitem[i].item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(item)
|
||||
{
|
||||
case USAGE:
|
||||
KernelTestusage();
|
||||
break;
|
||||
case MEM:
|
||||
#ifdef KERNEL_TEST_MEM
|
||||
TestMem(argc-2,&argv[2]);
|
||||
#endif
|
||||
break;
|
||||
case TIMER:
|
||||
#ifdef KERNEL_TEST_TIMER
|
||||
TestTmr(argc-2,&argv[2]);
|
||||
#endif
|
||||
break;
|
||||
case GATHERBLOCK:
|
||||
#ifdef KERNEL_TEST_MEM
|
||||
TestGatherblock(&argv[2]);
|
||||
#endif
|
||||
break;
|
||||
case SCHED:
|
||||
#ifdef KERNEL_TEST_SCHED
|
||||
TestTaskReadyAndSched(argc-2, &argv[2]);
|
||||
#endif
|
||||
break;
|
||||
case IWG:
|
||||
#ifdef KERNEL_TEST_IWG
|
||||
TestIwg();
|
||||
#endif
|
||||
case REALTIME:
|
||||
#ifdef KERNEL_TEST_REALTIME
|
||||
TestRealtime(argc-2, &argv[2]);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_DISABLE_RETURN|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
TestMain, TestMain, test main sample );
|
||||
451
kernel/kernel_test/test_mem.c
Normal file
451
kernel/kernel_test/test_mem.c
Normal file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestMem.c
|
||||
* @brief support to test mem function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <string.h>
|
||||
|
||||
extern void ShowMemory(void);
|
||||
extern void ListBuddy(void);
|
||||
|
||||
/**************************test memory usage***********************************/
|
||||
|
||||
#include<time.h>
|
||||
#include<stdlib.h>
|
||||
|
||||
#define TASK_PRIORITY 5
|
||||
#define TASK_STACK_SIZE 4096
|
||||
#define TASK_TIMESLICE 5
|
||||
#define MEM_TEST_NUMBER 23
|
||||
|
||||
int number_imm=0;
|
||||
static int arr[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22};
|
||||
|
||||
void Fimm(void *parameter)
|
||||
{
|
||||
KPrintf("%s: task starts.\n",__func__);
|
||||
int i=0;
|
||||
unsigned long size;
|
||||
char *ptr = NONE;
|
||||
|
||||
srand(number_imm);
|
||||
while (i<50) {
|
||||
size = 1 << arr[rand() % MEM_TEST_NUMBER];
|
||||
ptr = x_malloc(size);
|
||||
|
||||
if (ptr != NULL) {
|
||||
KPrintf("alloc-memory: %d btye\n",size);
|
||||
x_free(ptr);
|
||||
KPrintf("free--memory: %d byte\n",size);
|
||||
ptr=NONE;
|
||||
} else {
|
||||
KPrintf("try to get %d byte memory failed!\n",size);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
number_imm++;
|
||||
}
|
||||
|
||||
int FreeImmediatelly(void){
|
||||
|
||||
KPrintf("\033[32;1m***********test limitations*************\033[0m\n");
|
||||
KPrintf("allocation and free pointer immdiatetely. \n");
|
||||
|
||||
int32 tid;
|
||||
tid = KTaskCreate("Fimm",Fimm,NONE,TASK_STACK_SIZE,TASK_PRIORITY);
|
||||
|
||||
if (tid >= 0)
|
||||
StartupKTask(tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int num_FTillEnd=1;
|
||||
|
||||
void FTillEnd(void *parameter)
|
||||
{
|
||||
int i=0;
|
||||
unsigned long size;
|
||||
char *ptr[55];
|
||||
unsigned long arrsize[55];
|
||||
// srand((unsigned)time(NULL)*10);
|
||||
srand(num_FTillEnd);
|
||||
num_FTillEnd++;
|
||||
|
||||
while (i<50) {
|
||||
size = 1 << arr[rand() % MEM_TEST_NUMBER];
|
||||
ptr[i] = x_malloc(size);
|
||||
arrsize[i]=size;
|
||||
|
||||
if (ptr[i] != NULL) {
|
||||
KPrintf("get memory: %d btye\n",size);
|
||||
} else {
|
||||
KPrintf("try to get %d byte memory failed!\n",size);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i -= 1;
|
||||
for( ; i>=0 ; i-- ) {
|
||||
x_free(ptr[i]);
|
||||
KPrintf("free memory: %d byte\n",arrsize[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int FreeEnd(void)
|
||||
{
|
||||
KPrintf("\033[32;1m***********test limitations*************\033[0m\n");
|
||||
KPrintf("-------allocation until no memory-------\n");
|
||||
|
||||
int32 tid;
|
||||
tid = KTaskCreate("fend",FTillEnd,NONE,TASK_STACK_SIZE,TASK_PRIORITY);
|
||||
|
||||
if (tid >= 0)
|
||||
StartupKTask(tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ARCH_ARM
|
||||
#define MEM_GRIN_COUNT 1024
|
||||
#else
|
||||
#define MEM_GRIN_COUNT 8000
|
||||
#endif
|
||||
|
||||
char *ptr[MEM_GRIN_COUNT];
|
||||
unsigned int arr_grin[MEM_GRIN_COUNT];
|
||||
|
||||
extern void ListBuddy();
|
||||
int FendGrin()
|
||||
{
|
||||
KPrintf("\033[32;1m***********test limitations*************\033[0m\n");
|
||||
KPrintf("-------allocation for 1 byte with step 1-------\n");
|
||||
int i=0;
|
||||
int tempvalue = 1;
|
||||
|
||||
while( i< MEM_GRIN_COUNT) {
|
||||
KPrintf("\033[32;1malloc memory [%d]\033[0m\n",tempvalue);
|
||||
ptr[i] = x_malloc(tempvalue);
|
||||
|
||||
if (ptr[i]) {
|
||||
arr_grin[i] = tempvalue;
|
||||
i++;
|
||||
tempvalue++;
|
||||
} else {
|
||||
if (tempvalue == 60)
|
||||
break;
|
||||
tempvalue=60;
|
||||
}
|
||||
}
|
||||
KPrintf("------------- limitation until [%d] -----------\n",i);
|
||||
ListBuddy();
|
||||
|
||||
DelayKTask(2000);
|
||||
|
||||
i -= 1;
|
||||
for ( ; i>=0 ; i-- ) {
|
||||
x_free(ptr[i]);
|
||||
KPrintf("free memory: %d byte\n",arr_grin[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ARCH_ARM
|
||||
#define MEM_CACHE_COUNT 1024
|
||||
#else
|
||||
#define MEM_CACHE_COUNT 8000
|
||||
#endif
|
||||
|
||||
char *cache_ptr[MEM_CACHE_COUNT];
|
||||
|
||||
void TestCacheLimitation(int timers,int init)
|
||||
{
|
||||
KPrintf("\033[32;1m******test small memory limit****\033[0m\n");
|
||||
int temp = init;
|
||||
int index;
|
||||
void *temp_ptr;
|
||||
|
||||
timers = timers > MEM_CACHE_COUNT? MEM_CACHE_COUNT: timers;
|
||||
|
||||
for (index = 1; index <= timers;index++) {
|
||||
if (index&1) {
|
||||
KPrintf("%d: x_malloc size [%d]. \n", index, temp);
|
||||
cache_ptr[index] = x_malloc(temp);
|
||||
} else {
|
||||
KPrintf("%d: x_calloc size [%d]. \n", index, temp);
|
||||
cache_ptr[index] = x_calloc(1,temp);
|
||||
}
|
||||
|
||||
if (cache_ptr[index] == NONE) {
|
||||
KPrintf("%d: malloc or calloc failure. \n", index);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((index % 4) == 0) {
|
||||
KPrintf("%d: x_realloc size [%d]. \n", index, temp+index);
|
||||
temp_ptr = cache_ptr[index];
|
||||
cache_ptr[index] = x_realloc(cache_ptr[index], temp+index);
|
||||
if (cache_ptr[index] == NONE) {
|
||||
KPrintf("%d: x_realloc failure, roll back old pointer. \n", index);
|
||||
cache_ptr[index] = temp_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
temp++;
|
||||
temp %= 64;
|
||||
temp = ((temp==0) ? (temp + 1) : temp);
|
||||
}
|
||||
ListBuddy();
|
||||
|
||||
DelayKTask(1000);
|
||||
|
||||
index--;
|
||||
|
||||
for(; index > 0; index--){
|
||||
//KPrintf("free %d\n",index);
|
||||
x_free(cache_ptr[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void UsageMem()
|
||||
{
|
||||
KPrintf("%s: invalidate parameter\n",__func__);
|
||||
KPrintf("%s: usage for memory \n",__func__);
|
||||
KPrintf("%s: -s, test malloc allocation, e.g., test_main mem -s 64 \n",__func__);
|
||||
KPrintf("%s: -c, test calloc allocation, e.g., test_main mem -c 64 \n",__func__);
|
||||
KPrintf("%s: -r, test realloc allocation, e.g., test_main mem -r 64 80 \n",__func__);
|
||||
KPrintf("%s: -Fimm, test limit allocation, e.g., test_main mem -Fimm \n",__func__);
|
||||
KPrintf("%s: -fend, test limit allocation, e.g., test_main mem -fend \n",__func__);
|
||||
KPrintf("%s: -grin, test limit allocation, e.g., test_main mem -grin \n",__func__);
|
||||
KPrintf("%s: rw, test read and write opts, e.g., test_main mem rw 100 \"oldcontent\" \"newcontent\"\n",__func__);
|
||||
KPrintf("%s: cache, test limit allocation, e.g., test_main mem cache 100 1,\n",__func__);
|
||||
KPrintf("%s: allocate small mem for 100 timers started from 1. \n",__func__);
|
||||
KPrintf("%s: exception, make exception, e.g., test_main mem exception 100\n",__func__);
|
||||
}
|
||||
|
||||
void TestMalloc(x_size_t size)
|
||||
{
|
||||
KPrintf("\033[32;1m**********x_malloc & x_free***********\033[0m\n");
|
||||
KPrintf("the memory size is [%u] for allocation. \n", size);
|
||||
KPrintf("-------------before x_malloc-----------\n");
|
||||
|
||||
ShowMemory();
|
||||
|
||||
void *ptr = x_malloc(size);
|
||||
if (ptr) {
|
||||
KPrintf("----------x_malloc successfully--------\n");
|
||||
ShowMemory();
|
||||
x_free(ptr);
|
||||
KPrintf("-----------x_free successfully---------\n");
|
||||
ShowMemory();
|
||||
} else {
|
||||
KPrintf("------------x_malloc failure-----------\n");
|
||||
}
|
||||
KPrintf("****************** end *****************\n");
|
||||
}
|
||||
|
||||
void TestReAlloc(x_size_t size_prev, x_size_t size_next)
|
||||
{
|
||||
KPrintf("\033[32;1m**********x_realloc & x_free**********\033[0m\n");
|
||||
KPrintf("the memory size is [%u] for x_malloc. \n", size_prev);
|
||||
KPrintf("-------------before x_malloc-----------\n");
|
||||
ShowMemory();
|
||||
|
||||
void *ptr = x_malloc(size_prev);
|
||||
void *ptr2;
|
||||
if (ptr) {
|
||||
KPrintf("---------x_malloc successfully--------\n");
|
||||
ShowMemory();
|
||||
KPrintf("-----------before x_realloc-----------\n");
|
||||
KPrintf("the memory size is [%u] for x_malloc. \n", size_next);
|
||||
ptr2 = x_realloc(ptr, size_next);
|
||||
if (ptr2) {
|
||||
KPrintf("-----------realloc successfully---------\n");
|
||||
ShowMemory();
|
||||
x_free(ptr2);
|
||||
KPrintf("-----------x_free successfully---------\n");
|
||||
ShowMemory();
|
||||
} else {
|
||||
KPrintf("-----------x_realloc failure-----------\n");
|
||||
if(size_next !=0)
|
||||
x_free(ptr);
|
||||
KPrintf("-----------x_free successfully---------\n");
|
||||
ShowMemory();
|
||||
}
|
||||
} else {
|
||||
KPrintf("-----------x_malloc failure------------\n");
|
||||
}
|
||||
KPrintf("****************** end *****************\n");
|
||||
}
|
||||
|
||||
void TestCalloc(x_size_t size)
|
||||
{
|
||||
KPrintf("\033[32;1m**********x_calloc & x_free***********\033[0m\n");
|
||||
KPrintf("the memory size is [%u] for x_malloc. \n", size);
|
||||
KPrintf("------------before x_calloc------------\n");
|
||||
ShowMemory();
|
||||
|
||||
void*ptr = x_calloc(1, size);
|
||||
if (ptr) {
|
||||
KPrintf("---------x_calloc successfully---------\n");
|
||||
ShowMemory();
|
||||
x_free(ptr);
|
||||
KPrintf("----------x_free successfully----------\n");
|
||||
ShowMemory();
|
||||
} else {
|
||||
KPrintf("------------x_calloc failure-----------\n");
|
||||
}
|
||||
KPrintf("****************** end *****************\n");
|
||||
}
|
||||
|
||||
void TestReadWrite(x_size_t size, char *raw_content, char *new_content)
|
||||
{
|
||||
KPrintf("\033[32;1m**********read and write opts***********\033[0m\n");
|
||||
KPrintf("the memory size is [%u] for allocation. \n", size);
|
||||
KPrintf("-------------before x_malloc-----------\n");
|
||||
int endposition;
|
||||
|
||||
void *ptr = x_malloc(size);
|
||||
if (ptr) {
|
||||
KPrintf("----------x_malloc successfully--------\n");
|
||||
KPrintf("---------- show raw content --------\n");
|
||||
memcpy(ptr,raw_content, size > strlen(raw_content) ? strlen(raw_content): size);
|
||||
endposition = size > strlen(raw_content) ? strlen(raw_content): size;
|
||||
*((char*)ptr + endposition) = 0;
|
||||
|
||||
KPrintf("raw content is [\033[41;1m%s\033[0m]\n",ptr);
|
||||
KPrintf("----- write and show new content -----\n");
|
||||
memcpy(ptr,new_content, size > strlen(new_content)? strlen(new_content): size);
|
||||
endposition = size>strlen(new_content)? strlen(new_content): size;
|
||||
|
||||
*((char*)ptr + endposition) = 0;
|
||||
DelayKTask(100);
|
||||
|
||||
KPrintf("new content is [\033[41;1m%s\033[0m]\n",ptr);
|
||||
x_free(ptr);
|
||||
KPrintf("-----------x_free successfully---------\n");
|
||||
} else {
|
||||
KPrintf("------------x_malloc failure-----------\n");
|
||||
}
|
||||
KPrintf("\n------------------ end -----------------\n\n");
|
||||
|
||||
ptr = x_calloc(1,size);
|
||||
if (ptr) {
|
||||
KPrintf("----------x_calloc successfully--------\n");
|
||||
KPrintf("---------- show raw content --------\n");
|
||||
memcpy(ptr,raw_content,size > strlen(raw_content) ? strlen(raw_content): size);
|
||||
endposition = size > strlen(raw_content) ? strlen(raw_content): size;
|
||||
*((char*)ptr + endposition) = 0;
|
||||
|
||||
KPrintf("raw content is [\033[41;1m%s\033[0m]\n",ptr);
|
||||
KPrintf("----- write and show new content -----\n");
|
||||
memcpy(ptr,new_content,size > strlen(new_content) ? strlen(new_content): size);
|
||||
endposition = size > strlen(new_content) ? strlen(new_content): size;
|
||||
*((char*)ptr + endposition)=0;
|
||||
|
||||
DelayKTask(100);
|
||||
KPrintf("new content is [\033[41;1m%s\033[0m]\n",ptr);
|
||||
x_free(ptr);
|
||||
KPrintf("-----------x_free successfully---------\n");
|
||||
} else {
|
||||
KPrintf("------------x_calloc failure-----------\n");
|
||||
}
|
||||
KPrintf("****************** end *****************\n");
|
||||
}
|
||||
|
||||
void TestException(x_size_t size)
|
||||
{
|
||||
KPrintf("\033[32;1m**********test make exception***********\033[0m\n");
|
||||
KPrintf("the memory size is [%u] for allocation. \n", size);
|
||||
|
||||
void*ptr = x_malloc(size);
|
||||
if (ptr == NONE) {
|
||||
KPrintf("------------x_malloc failure-----------\n");
|
||||
} else {
|
||||
memset(ptr-8, 5, size+8);
|
||||
x_free(ptr);
|
||||
}
|
||||
KPrintf("****************** end *****************\n");
|
||||
}
|
||||
|
||||
int TestMem(int argc,char*argv[])
|
||||
{
|
||||
x_size_t size;
|
||||
x_size_t newsize;
|
||||
if (0 == strncmp("-h", argv[0], strlen("-h"))) {
|
||||
UsageMem();
|
||||
}
|
||||
|
||||
if (0 == strncmp("cache", argv[0], strlen("cache"))) {
|
||||
if (argc == 2) {
|
||||
size = atoi(argv[1]);
|
||||
newsize =1;
|
||||
}
|
||||
|
||||
if(argc == 3) {
|
||||
size = atoi(argv[1]);
|
||||
newsize = atoi(argv[2]);
|
||||
newsize = newsize==0 ? 1: newsize;
|
||||
}
|
||||
|
||||
TestCacheLimitation(size, newsize);
|
||||
}
|
||||
|
||||
if (0 == strncmp("-s", argv[0], strlen("-s"))) {
|
||||
size = atoi(argv[1]);
|
||||
TestMalloc(size);
|
||||
}
|
||||
|
||||
if (0 == strncmp("-r", argv[0], strlen("-r"))) {
|
||||
size = atoi(argv[1]);
|
||||
newsize = atoi(argv[2]);
|
||||
TestReAlloc(size,newsize);
|
||||
}
|
||||
|
||||
if (0 == strncmp("-c", argv[0], strlen("-c"))) {
|
||||
size = atoi(argv[1]);
|
||||
TestCalloc(size);
|
||||
}
|
||||
|
||||
if (0 == strncmp("-Fimm", argv[0], strlen("-Fimm"))) {
|
||||
FreeImmediatelly();
|
||||
}
|
||||
|
||||
if (0 == strncmp("-fend", argv[0], strlen("-fend"))) {
|
||||
FreeEnd();
|
||||
}
|
||||
|
||||
if (0 == strncmp("-grin", argv[0], strlen("-grin"))) {
|
||||
FendGrin();
|
||||
}
|
||||
|
||||
if (0 == strncmp("rw", argv[0], strlen("rw"))) {
|
||||
size = atoi(argv[1]);
|
||||
TestReadWrite(size, argv[2], argv[3]);
|
||||
}
|
||||
|
||||
if (0 == strncmp("exception",argv[0],strlen("exception"))) {
|
||||
size = atoi(argv[1]);
|
||||
TestException(size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************** end ***********************************/
|
||||
351
kernel/kernel_test/test_realtime.c
Normal file
351
kernel/kernel_test/test_realtime.c
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestRealtime.c
|
||||
* @brief support to test realtime function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <string.h>
|
||||
#include <dev_pin.h>
|
||||
|
||||
extern unsigned int usleep(unsigned int seconds);
|
||||
static BusType pin;
|
||||
|
||||
#ifdef ARCH_ARM
|
||||
#include <hardware_gpio.h>
|
||||
#define GPIO_C13 7
|
||||
#define GPIO_C2 17
|
||||
|
||||
void PinIrqIsr(void *args)
|
||||
{
|
||||
*(volatile unsigned int *)0x40020818 = 0x2000;
|
||||
|
||||
*(volatile unsigned int *)0x4002081a = 0x2000;
|
||||
}
|
||||
|
||||
int RealtimeIrqTest()
|
||||
{
|
||||
struct PinParam testpin_1;
|
||||
struct PinStat testpin_1_stat;
|
||||
struct PinParam testpin_2;
|
||||
int ret = 0;
|
||||
|
||||
struct BusConfigureInfo configure_info_1;
|
||||
struct BusConfigureInfo configure_info_2;
|
||||
struct BusBlockWriteParam write_param_1;
|
||||
|
||||
configure_info_1.configure_cmd = OPE_CFG;
|
||||
configure_info_1.private_data = (void *)&testpin_1;
|
||||
write_param_1.buffer = (void *)&testpin_1_stat;
|
||||
|
||||
configure_info_2.configure_cmd = OPE_CFG;
|
||||
configure_info_2.private_data = (void *)&testpin_2;
|
||||
|
||||
KPrintf("%s irq test\n",__func__);
|
||||
/* config test pin 1 as output*/
|
||||
testpin_1.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_1.pin = GPIO_C13;
|
||||
testpin_1.mode = GPIO_CFG_OUTPUT;
|
||||
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info_1);
|
||||
if (ret != EOK) {
|
||||
KPrintf("config testpin_1 %d failed!\n", GPIO_C13);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
/* set test pin 1 as high*/
|
||||
testpin_1_stat.pin = GPIO_C13;
|
||||
testpin_1_stat.val = GPIO_LOW;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param_1);
|
||||
|
||||
/* config test pin 2 as input*/
|
||||
testpin_2.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_2.pin = GPIO_C2;
|
||||
testpin_2.mode = GPIO_CFG_INPUT;
|
||||
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info_2);
|
||||
if (ret != EOK) {
|
||||
KPrintf("config testpin_2 %d input failed!\n", testpin_2.pin);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
testpin_2.cmd = GPIO_IRQ_REGISTER;
|
||||
testpin_2.pin = GPIO_C2;
|
||||
testpin_2.irq_set.irq_mode = GPIO_IRQ_EDGE_BOTH;
|
||||
testpin_2.irq_set.hdr = PinIrqIsr;
|
||||
testpin_2.irq_set.args = NONE;
|
||||
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info_2);
|
||||
if (ret != EOK) {
|
||||
KPrintf("register testpin_2 %d irq failed!\n", testpin_2.pin);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
testpin_2.cmd = GPIO_IRQ_ENABLE;
|
||||
testpin_2.pin = GPIO_C2;
|
||||
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info_2);
|
||||
if (ret != EOK) {
|
||||
KPrintf("enable testpin_2 %d irq failed!\n", testpin_2.pin);
|
||||
return -ERROR;
|
||||
}
|
||||
KPrintf("%s irq test\n",__func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RealtimeTaskSwitchTest()
|
||||
{
|
||||
struct PinParam testpin_1;
|
||||
struct PinStat testpin_1_stat;
|
||||
int ret = 0;
|
||||
|
||||
struct BusConfigureInfo configure_info_1;
|
||||
struct BusBlockWriteParam write_param_1;
|
||||
|
||||
configure_info_1.configure_cmd = OPE_CFG;
|
||||
configure_info_1.private_data = (void *)&testpin_1;
|
||||
write_param_1.buffer = (void *)&testpin_1_stat;
|
||||
|
||||
/* config test pin 1 as output*/
|
||||
testpin_1.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_1.pin = GPIO_C13;
|
||||
testpin_1.mode = GPIO_CFG_OUTPUT;
|
||||
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info_1);
|
||||
if (ret != EOK) {
|
||||
KPrintf("config testpin_1 %d failed!\n", GPIO_C13);
|
||||
return ;
|
||||
}
|
||||
|
||||
/* set test pin 1 as low*/
|
||||
testpin_1_stat.pin = GPIO_C13;
|
||||
testpin_1_stat.val = GPIO_LOW;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param_1);
|
||||
|
||||
while (RET_TRUE) {
|
||||
DelayKTask(1);
|
||||
}
|
||||
}
|
||||
|
||||
void GpioSpeedTest()
|
||||
{
|
||||
struct PinParam testpin_1;
|
||||
struct PinStat testpin_1_stat;
|
||||
struct PinParam testpin_2;
|
||||
int ret = 0;
|
||||
|
||||
struct BusConfigureInfo configure_info_1;
|
||||
struct BusConfigureInfo configure_info_2;
|
||||
struct BusBlockWriteParam write_param_1;
|
||||
|
||||
configure_info_1.configure_cmd = OPE_CFG;
|
||||
configure_info_1.private_data = (void *)&testpin_1;
|
||||
write_param_1.buffer = (void *)&testpin_1_stat;
|
||||
|
||||
configure_info_2.configure_cmd = OPE_CFG;
|
||||
configure_info_2.private_data = (void *)&testpin_2;
|
||||
|
||||
/* config test pin 1 as output*/
|
||||
testpin_1.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_1.pin = GPIO_C13;
|
||||
testpin_1.mode = GPIO_CFG_OUTPUT;
|
||||
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info_1);
|
||||
if (ret != EOK) {
|
||||
KPrintf("config testpin_1 %d failed!\n", GPIO_C13);
|
||||
return ;
|
||||
}
|
||||
|
||||
testpin_2.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_2.pin = GPIO_C2;
|
||||
testpin_2.mode = GPIO_CFG_INPUT;
|
||||
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info_2);
|
||||
|
||||
/* set test pin 1 as low*/
|
||||
testpin_1_stat.pin = GPIO_C13;
|
||||
testpin_1_stat.val = GPIO_LOW;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param_1);
|
||||
|
||||
while (RET_TRUE) {
|
||||
*(volatile unsigned int *)0x40020818 = 0x2000;
|
||||
|
||||
*(volatile unsigned int*)0x4002081a = 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define GPIO_18 18
|
||||
#define GPIO_19 19
|
||||
|
||||
void PinIrqIsr(void *args)
|
||||
{
|
||||
*(volatile unsigned int *)0x3800100c |= 0x5;
|
||||
|
||||
*(volatile unsigned int *)0x3800100c &= ~0x5;
|
||||
}
|
||||
|
||||
int RealtimeIrqTest()
|
||||
{
|
||||
struct PinParam testpin_1;
|
||||
struct PinStat testpin_1_stat;
|
||||
struct PinParam testpin_2;
|
||||
|
||||
struct BusConfigureInfo configure_info_1;
|
||||
struct BusConfigureInfo configure_info_2;
|
||||
struct BusBlockWriteParam write_param_1;
|
||||
|
||||
configure_info_1.configure_cmd = OPE_CFG;
|
||||
configure_info_1.private_data = (void *)&testpin_1;
|
||||
write_param_1.buffer = (void *)&testpin_1_stat;
|
||||
|
||||
configure_info_2.configure_cmd = OPE_CFG;
|
||||
configure_info_2.private_data = (void *)&testpin_2;
|
||||
|
||||
KPrintf("%s irq test\n",__func__);
|
||||
/* config GPIO18 as output and set as low */
|
||||
testpin_1.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_1.pin = GPIO_18;
|
||||
testpin_1.mode = GPIO_CFG_OUTPUT;
|
||||
BusDrvConfigure(pin->owner_driver, &configure_info_1);
|
||||
|
||||
testpin_1_stat.pin = GPIO_18;
|
||||
testpin_1_stat.val = GPIO_LOW;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param_1);
|
||||
|
||||
/* config GPIO18 as input */
|
||||
testpin_2.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_2.pin = GPIO_19;
|
||||
testpin_2.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(pin->owner_driver, &configure_info_2);
|
||||
|
||||
testpin_2.cmd = GPIO_IRQ_REGISTER;
|
||||
testpin_2.pin = GPIO_19;
|
||||
testpin_2.irq_set.irq_mode = GPIO_IRQ_EDGE_RISING;
|
||||
testpin_2.irq_set.hdr = PinIrqIsr;
|
||||
testpin_2.irq_set.args = NONE;
|
||||
BusDrvConfigure(pin->owner_driver, &configure_info_2);
|
||||
|
||||
testpin_2.cmd = GPIO_IRQ_ENABLE;
|
||||
testpin_2.pin = GPIO_19;
|
||||
BusDrvConfigure(pin->owner_driver, &configure_info_2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RealtimeTaskSwitchTest()
|
||||
{
|
||||
struct PinParam testpin_1;
|
||||
struct PinStat testpin_1_stat;
|
||||
|
||||
struct BusConfigureInfo configure_info_1;
|
||||
struct BusBlockWriteParam write_param_1;
|
||||
|
||||
configure_info_1.configure_cmd = OPE_CFG;
|
||||
configure_info_1.private_data = (void *)&testpin_1;
|
||||
write_param_1.buffer = (void *)&testpin_1_stat;
|
||||
|
||||
testpin_1.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_1.pin = GPIO_18;
|
||||
testpin_1.mode = GPIO_CFG_OUTPUT;
|
||||
BusDrvConfigure(pin->owner_driver, &configure_info_1);
|
||||
|
||||
testpin_1_stat.pin = GPIO_18;
|
||||
testpin_1_stat.val = GPIO_LOW;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param_1);
|
||||
|
||||
while (RET_TRUE) {
|
||||
DelayKTask(10);
|
||||
}
|
||||
}
|
||||
|
||||
void GpioSpeedTest()
|
||||
{
|
||||
struct PinParam testpin_1;
|
||||
struct PinStat testpin_1_stat;
|
||||
|
||||
struct BusConfigureInfo configure_info_1;
|
||||
struct BusBlockWriteParam write_param_1;
|
||||
|
||||
configure_info_1.configure_cmd = OPE_CFG;
|
||||
configure_info_1.private_data = (void *)&testpin_1;
|
||||
write_param_1.buffer = (void *)&testpin_1_stat;
|
||||
|
||||
testpin_1.cmd = GPIO_CONFIG_MODE;
|
||||
testpin_1.pin = GPIO_18;
|
||||
testpin_1.mode = GPIO_CFG_OUTPUT;
|
||||
BusDrvConfigure(pin->owner_driver, &configure_info_1);
|
||||
|
||||
testpin_1_stat.pin = GPIO_18;
|
||||
testpin_1_stat.val = GPIO_LOW;
|
||||
BusDevWriteData(pin->owner_haldev, &write_param_1);
|
||||
|
||||
while (RET_TRUE) {
|
||||
*(volatile unsigned int *)0x3800100c |= 0x5;
|
||||
*(volatile unsigned int *)0x3800100c &= ~0x5;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************/
|
||||
static void UsageHelp(void)
|
||||
{
|
||||
KPrintf("TestRealtime.\n");
|
||||
}
|
||||
|
||||
int TestRealtime(int argc, char * argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
struct BusConfigureInfo configure_info;
|
||||
|
||||
if (NONE == argv || 0 == strncmp("-h", argv[0], strlen("-h")) || 0 == strncmp("usage", argv[0], strlen("usage"))) {
|
||||
UsageHelp();
|
||||
return -EINVALED;
|
||||
}
|
||||
|
||||
pin = BusFind(PIN_BUS_NAME);
|
||||
if (!pin) {
|
||||
KPrintf("find %s failed!\n", PIN_BUS_NAME);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
pin->owner_driver = BusFindDriver(pin, PIN_DRIVER_NAME);
|
||||
pin->owner_haldev = BusFindDevice(pin, PIN_DEVICE_NAME);
|
||||
|
||||
configure_info.configure_cmd = OPE_INT;
|
||||
ret = BusDrvConfigure(pin->owner_driver, &configure_info);
|
||||
if (ret != EOK) {
|
||||
KPrintf("initialize %s failed!\n", PIN_BUS_NAME);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
if (0 == strncmp("-irq",argv[0],strlen("-irq")) ) {
|
||||
RealtimeIrqTest(); ///< static creat single sem test
|
||||
}
|
||||
|
||||
if (0 == strncmp("-task",argv[0],strlen("-task")) ) {
|
||||
RealtimeTaskSwitchTest();
|
||||
}
|
||||
|
||||
if (0 == strncmp("-gpio",argv[0],strlen("-gpio")) ) {
|
||||
GpioSpeedTest();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
65
kernel/kernel_test/test_rtc.c
Normal file
65
kernel/kernel_test/test_rtc.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file TestRtc.c
|
||||
* @brief support to test rtc function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
|
||||
#ifdef RESOURCES_RTC
|
||||
|
||||
static int TestRtc(int argc, char *argv[])
|
||||
{
|
||||
time_t now;
|
||||
|
||||
struct RtcSetParam rtc_set_param;
|
||||
|
||||
KPrintf("TestRtc cmd %s\n", argv[1]);
|
||||
|
||||
if (0 == strcmp("-s", argv[1])) {
|
||||
rtc_set_param.rtc_set_cmd = OPER_RTC_SET_TIME;
|
||||
rtc_set_param.date_param.year = 2021;
|
||||
rtc_set_param.date_param.month = 4;
|
||||
rtc_set_param.date_param.day = 6;
|
||||
rtc_set_param.time_param.hour = 16;
|
||||
rtc_set_param.time_param.minute = 0;
|
||||
rtc_set_param.time_param.second = 0;
|
||||
|
||||
RtcDrvSetFunction(RTC_DRV_NAME, &rtc_set_param);
|
||||
|
||||
rtc_set_param.rtc_set_cmd = OPER_RTC_GET_TIME;
|
||||
rtc_set_param.time = &now;
|
||||
|
||||
RtcDrvSetFunction(RTC_DRV_NAME, &rtc_set_param);
|
||||
|
||||
KPrintf("%s\n", ctime(&now));
|
||||
} else if (0 == strcmp("-g", argv[1])) {
|
||||
rtc_set_param.rtc_set_cmd = OPER_RTC_GET_TIME;
|
||||
rtc_set_param.time = &now;
|
||||
|
||||
RtcDrvSetFunction(RTC_DRV_NAME, &rtc_set_param);
|
||||
|
||||
KPrintf("%s\n", ctime(&now));
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(4),
|
||||
TestRtc, TestRtc, Test the RTC Function);
|
||||
|
||||
#endif
|
||||
199
kernel/kernel_test/test_serial.c
Normal file
199
kernel/kernel_test/test_serial.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_serial.c
|
||||
* @brief support to test serial function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
#if defined (ARCH_RISCV)
|
||||
#include <connect_uart.h>
|
||||
#elif defined(ARCH_ARM)
|
||||
#include <connect_usart.h>
|
||||
#endif
|
||||
|
||||
//#define TEST_POSIX
|
||||
|
||||
#ifdef TEST_POSIX
|
||||
#include "user_api.h"
|
||||
#endif
|
||||
|
||||
#ifdef RESOURCES_SERIAL
|
||||
|
||||
static char test_str[] = "Hello AIIT!\r\n";
|
||||
|
||||
struct Bus *bus = NONE;
|
||||
struct Driver *bus_driver = NONE;
|
||||
struct HardwareDev *bus_device = NONE;
|
||||
|
||||
#ifdef TEST_POSIX
|
||||
static int uart3_fd = 0;
|
||||
#endif
|
||||
static int32 test_serial_task = 0;
|
||||
|
||||
static void TestSerialRecvTask(void *parameter)
|
||||
{
|
||||
int16 i = 0;
|
||||
char recv_data = 0;
|
||||
#ifdef TEST_POSIX
|
||||
char data_buffer[128] = {0};
|
||||
char data_size = 0;
|
||||
#endif
|
||||
struct BusBlockReadParam read_param;
|
||||
struct BusBlockWriteParam write_param;
|
||||
memset(&read_param, 0, sizeof(struct BusBlockReadParam));
|
||||
memset(&write_param, 0, sizeof(struct BusBlockWriteParam));
|
||||
|
||||
|
||||
|
||||
while(RET_TRUE) {
|
||||
#ifndef TEST_POSIX
|
||||
read_param.size = 1;
|
||||
read_param.buffer = &recv_data;
|
||||
read_param.read_length = 0;
|
||||
|
||||
BusDevReadData(bus_device, &read_param);
|
||||
for (i = 0; i < read_param.read_length; i ++) {
|
||||
KPrintf("TestSerialRecvTask i %d char 0x%x\n", i, recv_data);
|
||||
}
|
||||
|
||||
write_param.buffer = &recv_data;
|
||||
write_param.size = 1;
|
||||
BusDevWriteData(bus_device, &write_param);
|
||||
#else
|
||||
memset(data_buffer, 0, 128);
|
||||
data_size = read(uart3_fd, data_buffer, 128);
|
||||
KPrintf("uart 3 data size %d data %s\n", data_size, data_buffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int SerialBusCheck(const char *bus_name, const char *driver_name, const char *device_name)
|
||||
{
|
||||
int ret = EOK;
|
||||
#ifndef TEST_POSIX
|
||||
struct SerialBus *serial_bus = NONE;
|
||||
struct SerialDriver *serial_driver = NONE;
|
||||
struct SerialHardwareDevice *serial_device = NONE;
|
||||
struct SerialCfgParam *serial_cfg_default = NONE;
|
||||
struct SerialDevParam *serial_dev_param = NONE;
|
||||
|
||||
struct BusConfigureInfo configure_info;
|
||||
|
||||
if(bus_name)
|
||||
{
|
||||
KPrintf("####test find bus %s\n", bus_name);
|
||||
bus = BusFind(bus_name);
|
||||
serial_bus = (struct SerialBus *)bus;
|
||||
KPrintf("####test find bus %8p serial_bus %8p\n", bus, serial_bus);
|
||||
}
|
||||
|
||||
if(driver_name)
|
||||
{
|
||||
KPrintf("####test find driver %s\n", driver_name);
|
||||
bus_driver = BusFindDriver(bus, driver_name);
|
||||
serial_driver = (struct SerialDriver *)bus_driver;
|
||||
serial_cfg_default = (struct SerialCfgParam *)serial_driver->private_data;
|
||||
KPrintf("####test bus_driver %8p serial_driver %8p done %8p serial_cfg_default %8p####\n",
|
||||
bus_driver, serial_driver, serial_driver->drv_done, serial_cfg_default);
|
||||
KPrintf("####hw cfg base 0x%x irq %d####\n", serial_cfg_default->hw_cfg.serial_register_base, serial_cfg_default->hw_cfg.serial_irq_interrupt);
|
||||
KPrintf("####data cfg rate %u order %u size %u bits %u invert %u parity %u stop %u####\n", serial_cfg_default->data_cfg.serial_baud_rate, serial_cfg_default->data_cfg.serial_bit_order, serial_cfg_default->data_cfg.serial_buffer_size,
|
||||
serial_cfg_default->data_cfg.serial_data_bits, serial_cfg_default->data_cfg.serial_invert_mode, serial_cfg_default->data_cfg.serial_parity_mode, serial_cfg_default->data_cfg.serial_stop_bits);
|
||||
}
|
||||
|
||||
if(device_name)
|
||||
{
|
||||
KPrintf("####test find device0 %s\n", device_name);
|
||||
bus_device = BusFindDevice(bus, device_name);
|
||||
serial_device = (struct SerialHardwareDevice *)bus_device;
|
||||
serial_dev_param = (struct SerialDevParam *)bus_device->private_data;
|
||||
KPrintf("####test bus_device %8p serial_dev %8p hwdone %8p devdone %8p####\n",
|
||||
bus_device, serial_device, serial_device->hwdev_done, serial_device->haldev.dev_done);
|
||||
KPrintf("####dev_param %8p work mode 0x%x set mode 0x%x stream mode 0x%x\n",
|
||||
serial_dev_param, serial_dev_param->serial_work_mode, serial_dev_param->serial_set_mode, serial_dev_param->serial_stream_mode);
|
||||
}
|
||||
|
||||
//BusDevRecvCallback(bus_device, test_serial_callback);
|
||||
|
||||
/*step 1: init bus_driver, change struct SerialCfgParam if necessary*/
|
||||
struct SerialCfgParam serial_cfg;
|
||||
memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
|
||||
configure_info.configure_cmd = OPE_INT;
|
||||
configure_info.private_data = &serial_cfg;
|
||||
BusDrvConfigure(bus_driver, &configure_info);
|
||||
KPrintf("BusDrvConfigure OPE_INT done\n");
|
||||
|
||||
/*step 2: match bus_driver with bus_device*/
|
||||
bus->match(bus_driver, bus_device);
|
||||
|
||||
/*step 3: open bus_device, configure struct SerialDevParam if necessary*/
|
||||
serial_dev_param->serial_set_mode = SIGN_OPER_INT_RX;
|
||||
serial_dev_param->serial_stream_mode = SIGN_OPER_STREAM;
|
||||
BusDevOpen(bus_device);
|
||||
KPrintf("BusDevOpen done\n");
|
||||
|
||||
/*step 4: write serial data, configure struct BusBlockWriteParam*/
|
||||
struct BusBlockWriteParam write_param;
|
||||
write_param.pos = 0;
|
||||
write_param.buffer = (void *)test_str;
|
||||
write_param.size = sizeof(test_str) - 1;
|
||||
BusDevWriteData(bus_device, &write_param);
|
||||
|
||||
//BusDevClose(bus_device);
|
||||
//KPrintf("BusDevClose done\n");
|
||||
#else
|
||||
uart3_fd = open("/dev/uart3_dev3", O_RDWR);
|
||||
if (uart3_fd < 0) {
|
||||
KPrintf("open fd error %d\n", uart3_fd);
|
||||
}
|
||||
KPrintf("open fd %d\n", uart3_fd);
|
||||
|
||||
struct SerialDataCfg cfg;
|
||||
cfg.serial_baud_rate = BAUD_RATE_115200;
|
||||
cfg.serial_data_bits = DATA_BITS_8;
|
||||
cfg.serial_stop_bits = STOP_BITS_1;
|
||||
cfg.serial_buffer_size = 128;
|
||||
cfg.serial_parity_mode = PARITY_NONE;
|
||||
cfg.serial_bit_order = 0;
|
||||
cfg.serial_invert_mode = 0;
|
||||
cfg.ext_uart_no = 0;
|
||||
cfg.port_configure = 0;
|
||||
|
||||
if (ret != ioctl(uart3_fd, OPE_INT, &cfg)) {
|
||||
KPrintf("ioctl fd error %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int TestSerial(void)
|
||||
{
|
||||
/*use serial device 3 to test serial function*/
|
||||
SerialBusCheck(SERIAL_BUS_NAME_3, SERIAL_DRV_NAME_3, SERIAL_3_DEVICE_NAME_0);
|
||||
|
||||
test_serial_task = KTaskCreate("TestSerialRecvTask",
|
||||
TestSerialRecvTask,
|
||||
NONE,
|
||||
2048,
|
||||
18);
|
||||
StartupKTask(test_serial_task);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
TestSerial, TestSerial, TestSerial );
|
||||
|
||||
#endif
|
||||
199
kernel/kernel_test/test_threadsched.c
Normal file
199
kernel/kernel_test/test_threadsched.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_threadsched.c
|
||||
* @brief support to test thread sched function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <string.h>
|
||||
#include <xs_assign.h>
|
||||
|
||||
extern long ShowTask(void);
|
||||
extern unsigned int msleep(uint64_t msec);
|
||||
|
||||
static int32 tid1 = NONE;
|
||||
static int32 tid2 = NONE;
|
||||
static int32 tid3 = NONE;
|
||||
static int32 tid4 = NONE;
|
||||
static int32 tid5 = NONE;
|
||||
|
||||
#define DYNAMIC_TASK_STACK_SIZE 3072
|
||||
#define PRIORITY 15
|
||||
static void Task1Entry(void *parameter)
|
||||
{
|
||||
int cnt = 10;
|
||||
DoubleLinklistType* node = NONE;
|
||||
DoubleLinklistType* head = NONE;
|
||||
struct TaskDescriptor *obj = NONE;
|
||||
TaskDyncSchedMembeType *tmp = NONE;
|
||||
register x_base level;
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
if (0 == strncmp(parameter,"-b",strlen("-b"))) { ///< if tasks bind to cpu 0
|
||||
head = &(Assign.smp_os_assign_ready_rector[0].priority_ready_vector[PRIORITY]);
|
||||
} else {
|
||||
head = &(Assign.os_assign_read_vector.priority_ready_vector[PRIORITY]);
|
||||
}
|
||||
#else
|
||||
head = &(Assign.os_assign_read_vector.priority_ready_vector[PRIORITY]);
|
||||
#endif
|
||||
while(cnt--) {
|
||||
#ifdef TOOL_SHELL
|
||||
ShowTask();
|
||||
#endif
|
||||
KPrintf("\n");
|
||||
|
||||
DOUBLE_LINKLIST_FOR_EACH(node, head) {
|
||||
tmp = SYS_DOUBLE_LINKLIST_ENTRY(node, struct TaskDyncSchedMember, sched_link);
|
||||
obj =CONTAINER_OF(tmp,struct TaskDescriptor, task_dync_sched_member);
|
||||
KPrintf("task ready table node name = %s node remaining_tick= %d node advance_cnt =%d\n",obj->task_base_info.name,
|
||||
obj->task_dync_sched_member.rest_timeslice, obj->task_dync_sched_member.advance_cnt);
|
||||
}
|
||||
#ifdef ARCH_SMP
|
||||
#ifdef SCHED_POLICY_FIFO
|
||||
MdelayKTask(30);
|
||||
#else
|
||||
msleep(30);
|
||||
#endif
|
||||
#else
|
||||
#ifdef ARCH_ARM
|
||||
MdelayKTask(3);
|
||||
#else
|
||||
MdelayKTask(80);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
KTaskDelete(tid2);
|
||||
KTaskDelete(tid3);
|
||||
KTaskDelete(tid4);
|
||||
KTaskDelete(tid5);
|
||||
|
||||
}
|
||||
|
||||
static void Task2Entry(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
while(RET_TRUE) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
static void Task3Entry(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
while(RET_TRUE) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
static void Task4Entry(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
while(RET_TRUE) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
static void Task5Entry(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
while(RET_TRUE) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicTaskSchedTest(char* parm)
|
||||
{
|
||||
char t_parm[4];
|
||||
#ifdef ARCH_SMP
|
||||
if (0 == strncmp("-b", parm, strlen("-b")) || 0 == strncmp("-bind", parm, strlen("-bind"))){
|
||||
strncpy(t_parm,"-b", 4);
|
||||
}
|
||||
#endif
|
||||
tid1 = KTaskCreate("d_tid1",
|
||||
Task1Entry,
|
||||
t_parm,
|
||||
DYNAMIC_TASK_STACK_SIZE,
|
||||
16);
|
||||
if (tid1 >= 0)
|
||||
StartupKTask(tid1);
|
||||
|
||||
tid2 = KTaskCreate("d_tid2",
|
||||
Task2Entry,
|
||||
"d_tid2",
|
||||
1024,
|
||||
15);
|
||||
#ifdef ARCH_SMP
|
||||
if (0 == strncmp("-b", parm, strlen("-b")) || 0 == strncmp("-bind", parm, strlen("-bind"))){
|
||||
KTaskCoreCombine(tid2, 0);
|
||||
}
|
||||
#endif
|
||||
if (tid2 >= 0)
|
||||
StartupKTask(tid2);
|
||||
|
||||
tid3 = KTaskCreate("d_tid3",
|
||||
Task3Entry,
|
||||
"d_tid3",
|
||||
1024,
|
||||
15);
|
||||
#ifdef ARCH_SMP
|
||||
if (0 == strncmp("-b", parm, strlen("-b")) || 0 == strncmp("-bind", parm, strlen("-bind"))){
|
||||
KTaskCoreCombine(tid3, 0);
|
||||
}
|
||||
#endif
|
||||
if (tid3 >= 0)
|
||||
StartupKTask(tid3);
|
||||
|
||||
tid4 = KTaskCreate("d_tid4",
|
||||
Task4Entry,
|
||||
"d_tid4",
|
||||
1024,
|
||||
15);
|
||||
#ifdef ARCH_SMP
|
||||
if (0 == strncmp("-b", parm, strlen("-b")) || 0 == strncmp("-bind", parm, strlen("-bind"))){
|
||||
KTaskCoreCombine(tid4, 0);
|
||||
}
|
||||
#endif
|
||||
if (tid4 >= 0)
|
||||
StartupKTask(tid4);
|
||||
|
||||
tid5 = KTaskCreate("d_tid5",
|
||||
Task5Entry,
|
||||
"d_tid5",
|
||||
1024,
|
||||
15);
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
if (0 == strncmp("-b", parm, strlen("-b")) || 0 == strncmp("-bind", parm, strlen("-bind"))){
|
||||
KTaskCoreCombine(tid5, 0);
|
||||
}
|
||||
#endif
|
||||
if (tid5 >= 0)
|
||||
StartupKTask(tid5);
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
static void UsageHelp(void)
|
||||
{
|
||||
KPrintf("test_task_ready_usage.\n");
|
||||
}
|
||||
|
||||
int TestTaskReadyAndSched(int argc, char * argv[])
|
||||
{
|
||||
DynamicTaskSchedTest(argv[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
116
kernel/kernel_test/test_timer.c
Normal file
116
kernel/kernel_test/test_timer.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_timer.c
|
||||
* @brief support to test timer function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
extern long ShowTimer(void);
|
||||
/*****************************************************************************************************************/
|
||||
/***********************************test create timer with dynamic style *****************************************/
|
||||
|
||||
|
||||
static int32 dynamic_timer1;
|
||||
static int32 dynamic_timer2;
|
||||
static int dynamic_cnt = 0;
|
||||
|
||||
|
||||
static void DynamicTimeout1Entry(void *parameter)
|
||||
{
|
||||
KPrintf("periodic timer is timeout %d\n", dynamic_cnt);
|
||||
if (dynamic_cnt++>= 9){
|
||||
KTimerQuitRun(dynamic_timer1);
|
||||
KPrintf("periodic timer was stopped! \n");
|
||||
}
|
||||
}
|
||||
|
||||
static void DynamicTimeout2Entry(void *parameter)
|
||||
{
|
||||
KPrintf("one shot timer is timeout\n");
|
||||
}
|
||||
|
||||
int TestDynamicTimer(void)
|
||||
{
|
||||
dynamic_timer1 = KCreateTimer("d_tmr1", DynamicTimeout1Entry,
|
||||
NONE, 10,
|
||||
TIMER_TRIGGER_PERIODIC);
|
||||
|
||||
if (dynamic_timer1 != NONE) KTimerStartRun(dynamic_timer1);
|
||||
|
||||
dynamic_timer2 = KCreateTimer("d_tmr2", DynamicTimeout2Entry,
|
||||
NONE, 30,
|
||||
TIMER_TRIGGER_ONCE);
|
||||
|
||||
if (dynamic_timer2 != NONE) KTimerStartRun(dynamic_timer2);
|
||||
ShowTimer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestTmrD(void)
|
||||
{
|
||||
KPrintf("test dynamic timer\n");
|
||||
TestDynamicTimer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************test mixed timers with dynamic and static style **********************************/
|
||||
static int32 mixed_timer_d;
|
||||
static int32 test_delete_timer;
|
||||
|
||||
static int num = 0;
|
||||
|
||||
|
||||
static void MexedTimeout2Entry(void *parameter)
|
||||
{
|
||||
KPrintf("mixed\n");
|
||||
KTimerQuitRun(mixed_timer_d);
|
||||
}
|
||||
|
||||
int TimerMix(void)
|
||||
{
|
||||
mixed_timer_d = KCreateTimer("mix_t2", MexedTimeout2Entry, NONE, 30, TIMER_TRIGGER_ONCE);
|
||||
|
||||
if (mixed_timer_d != NONE) KTimerStartRun(mixed_timer_d);
|
||||
|
||||
test_delete_timer = KCreateTimer("del_t3", MexedTimeout2Entry, NONE, 30, TIMER_TRIGGER_ONCE);
|
||||
ShowTimer();
|
||||
if(test_delete_timer != NONE)
|
||||
KDeleteTimer(test_delete_timer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestTmrM(void)
|
||||
{
|
||||
KPrintf("test mixed timer\n");
|
||||
TimerMix();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestTmr(int argc, char*argv[]) {
|
||||
|
||||
KPrintf("/******************************************** START **************************************************/\n");
|
||||
TestTmrD();
|
||||
MdelayKTask(4000);
|
||||
KPrintf("/******************************************* boundary ************************************************/\n");
|
||||
TestTmrM();
|
||||
MdelayKTask(4000);
|
||||
KPrintf("/********************************************* END **************************************************/\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
81
kernel/kernel_test/test_touch.c
Normal file
81
kernel/kernel_test/test_touch.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_touch.c
|
||||
* @brief support to test touch function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#include "bus_touch.h"
|
||||
#include "dev_touch.h"
|
||||
|
||||
int TestTouch(const char *bus_name, const char *driver_name, const char *device_name0)
|
||||
{
|
||||
struct Bus *bus;
|
||||
struct Driver *driver, *bus_driver;
|
||||
struct HardwareDev *device0;
|
||||
struct HardwareDev *bus_device0;
|
||||
struct TouchDataStandard datacfg;
|
||||
|
||||
struct TouchDataStandard data ={0,0};
|
||||
|
||||
struct BusConfigureInfo configure_info = {0,&data};
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
memset(&read_param,0,sizeof(struct BusBlockReadParam ));
|
||||
|
||||
read_param.buffer = &data;
|
||||
|
||||
if(bus_name)
|
||||
{
|
||||
KPrintf("##test find bus %s\n", bus_name);
|
||||
bus = BusFind(bus_name);
|
||||
KPrintf("##test bus %p####\n", bus);
|
||||
}
|
||||
|
||||
if(driver_name)
|
||||
{
|
||||
KPrintf("##test find driver %s\n", driver_name);
|
||||
driver = TouchDriverFind(driver_name, TYPE_TOUCH_DRV);
|
||||
bus_driver = BusFindDriver(bus, driver_name);
|
||||
KPrintf("##test driver %p bus_driver %p##\n", driver, bus_driver);
|
||||
}
|
||||
|
||||
if(device_name0)
|
||||
{
|
||||
KPrintf("##test find device0 %s\n", device_name0);
|
||||
device0 = TouchDeviceFind(device_name0, TYPE_TOUCH_DEV);
|
||||
KPrintf("device0 :%p\n", device0);
|
||||
bus_device0 = BusFindDevice(bus, device_name0);
|
||||
KPrintf("bus_device0 :%p\n", bus_device0);
|
||||
}
|
||||
KPrintf("ttt\n");
|
||||
BusDrvConfigure(bus_driver, &configure_info);
|
||||
KPrintf("yyy\n");
|
||||
while(1)
|
||||
{
|
||||
BusDevReadData(bus_device0,&read_param);
|
||||
KPrintf("dev.x= %8d *** dev.y= %8d \r\n",data.x,data.y);
|
||||
MdelayKTask(100);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TouchTest(void)
|
||||
{
|
||||
TestTouch(TOUCH_BUS_NAME_1,TOUCH_DRV_NAME_1, TOUCH_1_DEVICE_NAME_0);
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),TouchTest, TouchTest, Close AC task );
|
||||
237
kernel/kernel_test/user_api.h
Normal file
237
kernel/kernel_test/user_api.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file user_api.h
|
||||
* @brief define user api function and struct
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef __XS_USER_API_H__
|
||||
#define __XS_USER_API_H__
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <iot-vfs_posix.h>
|
||||
|
||||
#ifdef SEPARATE_COMPILE
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kswitch.h>
|
||||
#if defined(FS_VFS)
|
||||
#include <iot-vfs.h>
|
||||
#ifndef TASK_ISOLATION
|
||||
#include <iot-vfs_posix.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <xs_service.h>
|
||||
|
||||
#define TASK_INFO 1
|
||||
#define MEM_INFO 2
|
||||
#define SEM_INFO 3
|
||||
#define EVENT_INFO 4
|
||||
#define MUTEX_INFO 5
|
||||
#define MEMPOOL_INFO 6
|
||||
#define MSGQUEUE_INFO 7
|
||||
#define DEVICE_INFO 8
|
||||
#define TIMER_INFO 9
|
||||
|
||||
int UserPrintInfo(unsigned long i);
|
||||
|
||||
struct utask
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
uint32 stack_size;
|
||||
uint8 prio;
|
||||
};
|
||||
typedef struct utask utask_x;
|
||||
|
||||
typedef void DIR;
|
||||
|
||||
int32 UserTaskCreate(utask_x utask);
|
||||
|
||||
x_err_t UserTaskStartup(int32 id);
|
||||
x_err_t UserTaskDelete(int32 id);
|
||||
void UserTaskQuit(void);
|
||||
x_err_t UserTaskDelay(int32 ms);
|
||||
x_err_t UserGetTaskName(int32 id ,char *name);
|
||||
int32 UserGetTaskID(void);
|
||||
uint8 UserGetTaskStat(int32 id);
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
x_err_t UserTaskCoreCombine(int32 id,uint8 core_id);
|
||||
x_err_t UserTaskCoreUnCombine(int32 id);
|
||||
uint8 UserGetTaskCombinedCore(int32 id);
|
||||
uint8 UserGetTaskRunningCore(int32 id);
|
||||
#endif
|
||||
|
||||
x_err_t UserGetTaskErrorstatus(int32 id);
|
||||
uint8 UserGetTaskPriority(int32 id);
|
||||
|
||||
|
||||
void *UserMalloc(x_size_t size);
|
||||
void *UserRealloc(void *pointer, x_size_t size);
|
||||
void *UserCalloc(x_size_t count, x_size_t size);
|
||||
void UserFree(void *pointer);
|
||||
|
||||
#ifdef KERNEL_MUTEX
|
||||
int32 UserMutexCreate();
|
||||
void UserMutexDelete(int32 mutex);
|
||||
int32 UserMutexObtain(int32 mutex, int32 wait_time);
|
||||
int32 UserMutexAbandon(int32 mutex);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_SEMAPHORE
|
||||
typedef int32 sem_t;
|
||||
sem_t UserSemaphoreCreate(uint16 val);
|
||||
x_err_t UserSemaphoreDelete(sem_t sem);
|
||||
x_err_t UserSemaphoreObtain(sem_t sem, int32 wait_time);
|
||||
x_err_t UserSemaphoreAbandon(sem_t sem);
|
||||
x_err_t UserSemaphoreSetValue(sem_t sem, uint16 val);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_EVENT
|
||||
EventIdType UserEventCreate(uint8 flag);
|
||||
void UserEventDelete(EventIdType event);
|
||||
x_err_t UserEventTrigger(EventIdType event, uint32 set);
|
||||
x_err_t UserEventProcess(EventIdType event, uint32 set, uint8 option,
|
||||
int32 wait_time, uint32 *Recved);
|
||||
x_err_t UserEventReinit(EventIdType event);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_MESSAGEQUEUE
|
||||
int32 UserMsgQueueCreate(x_size_t msg_size, x_size_t max_msgs);
|
||||
x_err_t UserMsgQueueDelete(int32 mq );
|
||||
x_err_t UserMsgQueueSendwait(int32 mq, const void *buffer,
|
||||
x_size_t size, int32 wait_time);
|
||||
x_err_t UserMsgQueueSend(int32 mq, const void *buffer, x_size_t size);
|
||||
x_err_t UserMsgQueueUrgentSend(int32 mq, const void *buffer, x_size_t size);
|
||||
x_err_t UserMsgQueueRecv(int32 mq, void *buffer, x_size_t size,int32 wait_time);
|
||||
x_err_t UserMsgQueueReinit(int32 mq);
|
||||
#endif
|
||||
|
||||
int open(const char *path, int flags, ...);
|
||||
int read(int fd, void *buf, size_t len);
|
||||
int write(int fd, const void *buf, size_t len);
|
||||
int close(int fd);
|
||||
off_t lseek(int fd, off_t offset, int whence);
|
||||
int rename(const char *from, const char *to);
|
||||
int unlink(const char *path);
|
||||
int stat(const char *path, struct stat *buf);
|
||||
int fstat(int fd, struct stat *buf);
|
||||
int fsync(int fd);
|
||||
int ftruncate(int fd, off_t length);
|
||||
|
||||
int mkdir(const char *path, mode_t mode);
|
||||
DIR *opendir(const char *path);
|
||||
int closedir(DIR *dirp);
|
||||
struct dirent *readdir(DIR *dirp);
|
||||
int rmdir(const char *path);
|
||||
int chdir(const char *path);
|
||||
char *getcwd(char *buf, size_t size);
|
||||
long telldir(DIR *dirp);
|
||||
void seekdir(DIR *dirp, off_t offset);
|
||||
void rewinddir(DIR *dirp);
|
||||
|
||||
#ifdef FS_VFS
|
||||
struct statfs {
|
||||
size_t f_bsize;
|
||||
size_t f_blocks;
|
||||
size_t f_bfree;
|
||||
};
|
||||
|
||||
int statfs(const char *path, struct statfs *buf);
|
||||
#endif
|
||||
|
||||
void UserPrintf(const char *fmt, ...);
|
||||
|
||||
#else
|
||||
struct utask
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
};
|
||||
typedef struct utask utask_x;
|
||||
int32_t UserTaskCreate(utask_x utask);
|
||||
|
||||
#define UserTaskStartup StartupKTask
|
||||
#define UserTaskDelete KTaskDelete
|
||||
#define UserTaskQuit KTaskQuit
|
||||
#define UserTaskDelay MdelayKTask
|
||||
|
||||
x_err_t UserGetTaskName(int32_t id ,char *name);
|
||||
int32_t UserGetTaskID(void);
|
||||
uint8_t UserGetTaskStat(int32_t id);
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
#define UserTaskCoreCombine KTaskCoreCombine
|
||||
#define UserTaskCoreUnCombine KTaskCoreUnCombine
|
||||
|
||||
uint8_t UserGetTaskCombinedCore(int32_t id);
|
||||
uint8_t UserGetTaskRunningCore(int32_t id);
|
||||
#endif
|
||||
|
||||
x_err_t UserGetTaskErrorstatus(int32_t id);
|
||||
uint8_t UserGetTaskPriority(int32_t id);
|
||||
|
||||
#define UserMalloc x_malloc
|
||||
#define UserRealloc x_realloc
|
||||
#define UserCalloc x_calloc
|
||||
#define UserFree x_free
|
||||
|
||||
#ifdef KERNEL_MUTEX
|
||||
#define UserMutexCreate KMutexCreate
|
||||
#define UserMutexDelete KMutexDelete
|
||||
#define UserMutexObtain KMutexObtain
|
||||
#define UserMutexAbandon KMutexAbandon
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef KERNEL_SEMAPHORE
|
||||
#define UserSemaphoreCreate KSemaphoreCreate
|
||||
#define UserSemaphoreDelete KSemaphoreDelete
|
||||
#define UserSemaphoreObtain KSemaphoreObtain
|
||||
#define UserSemaphoreAbandon KSemaphoreAbandon
|
||||
#define UserSemaphoreSetValue KSemaphoreSetValue
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_EVENT
|
||||
#define UserEventCreate KEventCreate
|
||||
#define UserEventDelete KEventDelete
|
||||
#define UserEventTrigger KEventTrigger
|
||||
#define UserEventProcess KEventProcess
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_MESSAGEQUEUE
|
||||
#define UserMsgQueueCreate KCreateMsgQueue
|
||||
#define UserMsgQueueDelete KDeleteMsgQueue
|
||||
#define UserMsgQueueSendwait KMsgQueueSendwait
|
||||
#define UserMsgQueueSend KMsgQueueSend
|
||||
#define UserMsgQueueUrgentSend KMsgQueueUrgentSend
|
||||
#define UserMsgQueueRecv KMsgQueueRecv
|
||||
#define UserMsgQueueReinit KMsgQueueReinit
|
||||
#endif
|
||||
|
||||
#define UserPrintf KPrintf
|
||||
#endif
|
||||
|
||||
#endif
|
||||
11
kernel/memory/Makefile
Normal file
11
kernel/memory/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
SRC_FILES := byte_manage.c
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_MEMBLOCK),y)
|
||||
SRC_FILES += gatherblock.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TASK_ISOLATION),y)
|
||||
SRC_FILES += isolation.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
1037
kernel/memory/byte_manage.c
Normal file
1037
kernel/memory/byte_manage.c
Normal file
File diff suppressed because it is too large
Load Diff
414
kernel/memory/gatherblock.c
Normal file
414
kernel/memory/gatherblock.c
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: gatherblock.c
|
||||
* @brief: block memory management file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/8
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_hook.h>
|
||||
|
||||
#ifdef KERNEL_MEMBLOCK
|
||||
|
||||
/* a global list, which record all the gatherblocks*/
|
||||
DoubleLinklistType xiaoshan_memgather_head = {&xiaoshan_memgather_head, &xiaoshan_memgather_head};
|
||||
|
||||
/**
|
||||
* This function initializes a gather block memory structure.
|
||||
*
|
||||
* @param gm_handler the gatherblock structure
|
||||
* @param gm_name the name of gatherblock
|
||||
* @param begin_address the start address of gatherblock
|
||||
* @param gm_size the total size of gatherblock
|
||||
* @param one_block_size one block size in gatherblock
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *begin_address, x_size_t gm_size, x_size_t one_block_size)
|
||||
{
|
||||
x_base lock = 0;
|
||||
register x_size_t off_block = 0;
|
||||
register x_base critical_value = 0;
|
||||
uint8 *block_ptr = NONE;
|
||||
struct SysDoubleLinklistNode *list_entry = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
NULL_PARAM_CHECK(gm_name);
|
||||
NULL_PARAM_CHECK(begin_address);
|
||||
|
||||
CHECK(gm_size >= 1 && one_block_size >= 1);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
/* try to find gatherblock object */
|
||||
for (list_entry = xiaoshan_memgather_head.node_next;
|
||||
list_entry != &(xiaoshan_memgather_head);
|
||||
list_entry = list_entry->node_next) {
|
||||
GatherMemType gm;
|
||||
|
||||
gm = SYS_DOUBLE_LINKLIST_ENTRY(list_entry, struct MemGather, m_link);
|
||||
if (gm) {
|
||||
CHECK(gm != gm_handler);
|
||||
}
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
/* set the type attribute of gatherblock object */
|
||||
gm_handler->m_kind = Cmpt_KindN_Static;
|
||||
/* set the name of gatherblock object */
|
||||
strncpy(gm_handler->m_name, gm_name, NAME_NUM_MAX);
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* insert gatherblock object into the global list */
|
||||
DoubleLinkListInsertNodeAfter(&xiaoshan_memgather_head, &(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* initialize the other attributes of gatherblock object */
|
||||
gm_handler->m_start_address = begin_address;
|
||||
gm_handler->m_size = ALIGN_MEN_DOWN(gm_size, MEM_ALIGN_SIZE);
|
||||
one_block_size = ALIGN_MEN_UP(one_block_size, MEM_ALIGN_SIZE);
|
||||
gm_handler->one_block_size = one_block_size;
|
||||
gm_handler->block_total_number = gm_handler->m_size / (gm_handler->one_block_size + sizeof(uint8 *));
|
||||
gm_handler->block_free_number = gm_handler->block_total_number;
|
||||
|
||||
InitDoubleLinkList(&(gm_handler->wait_task));
|
||||
|
||||
/* links all the blocks in gatherblock object */
|
||||
block_ptr = (uint8 *)gm_handler->m_start_address;
|
||||
for (off_block = 0; off_block < gm_handler->block_total_number; off_block ++) {
|
||||
*(uint8 **)(block_ptr + off_block * (one_block_size + sizeof(uint8 *))) =
|
||||
(uint8 *)(block_ptr + (off_block + 1) * (one_block_size + sizeof(uint8 *)));
|
||||
}
|
||||
|
||||
*(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) =
|
||||
NONE;
|
||||
|
||||
gm_handler->m_block_link = block_ptr;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function will remove the gatherblock from the global list, which is created by MemGatherInit function
|
||||
*
|
||||
* @param gm_handler the gatherblock to be removed
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t RemoveMemGather(struct MemGather *gm_handler)
|
||||
{
|
||||
register x_ubase critical_value = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
|
||||
CHECK((gm_handler->m_kind & Cmpt_KindN_Static)!=0);
|
||||
|
||||
/* resume all the suspend tasks on gatherblock object */
|
||||
while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(gm_handler->wait_task.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
task->exstatus = -ERROR;
|
||||
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
}
|
||||
|
||||
/* set the type attribute */
|
||||
gm_handler->m_kind = 0;
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* remove the gatherblock object from the global links */
|
||||
DoubleLinkListRmNode(&(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will create a gatherblock object.
|
||||
*
|
||||
* @param gm_name the name of gatherblock
|
||||
* @param block_number the number of blocks in gatherblock
|
||||
* @param one_block_size one block size
|
||||
*
|
||||
* @return EOK on success; NONE on failure
|
||||
*/
|
||||
GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size_t one_block_size)
|
||||
{
|
||||
|
||||
register x_size_t off_block = 0;
|
||||
register x_base critical_value = 0;
|
||||
uint8 *block_ptr = NONE;
|
||||
struct MemGather *gm_handler = NONE;
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_name);
|
||||
CHECK(block_number >= 1 && one_block_size >= 1);
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* allocate memory for gatherblock object */
|
||||
gm_handler = (struct MemGather *)KERNEL_MALLOC(sizeof(struct MemGather));
|
||||
|
||||
if (NONE == gm_handler)
|
||||
return NONE;
|
||||
/* clear the gatherblock object */
|
||||
memset(gm_handler, 0x0, sizeof(struct MemGather));
|
||||
/* set the name attribute */
|
||||
strncpy(gm_handler->m_name, gm_name, NAME_NUM_MAX);
|
||||
/* set the flag attribute */
|
||||
gm_handler->m_sign = 0;
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* insert gatherblock object into the global list */
|
||||
DoubleLinkListInsertNodeAfter(&xiaoshan_memgather_head, &(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* set the other attributes of gatherblock object */
|
||||
one_block_size = ALIGN_MEN_UP(one_block_size, MEM_ALIGN_SIZE);
|
||||
gm_handler->one_block_size = one_block_size;
|
||||
gm_handler->m_size = (one_block_size + sizeof(uint8 *)) * block_number;
|
||||
|
||||
/* allocate memory for gather blocks */
|
||||
gm_handler->m_start_address = x_malloc((one_block_size + sizeof(uint8 *)) * block_number);
|
||||
if (NONE == gm_handler->m_start_address) {
|
||||
gm_handler->m_kind = 0;
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* remove the gatherblock object from the global links */
|
||||
DoubleLinkListRmNode(&(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* release the memory for gather block structure */
|
||||
KERNEL_FREE(gm_handler);
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
gm_handler->block_total_number = block_number;
|
||||
gm_handler->block_free_number = gm_handler->block_total_number;
|
||||
|
||||
InitDoubleLinkList(&(gm_handler->wait_task));
|
||||
|
||||
/* links all the gather blocks */
|
||||
block_ptr = (uint8 *)gm_handler->m_start_address;
|
||||
for (off_block = 0; off_block < gm_handler->block_total_number; off_block ++) {
|
||||
*(uint8 **)(block_ptr + off_block * (one_block_size + sizeof(uint8 *)))
|
||||
= block_ptr + (off_block + 1) * (one_block_size + sizeof(uint8 *));
|
||||
}
|
||||
|
||||
*(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *)))
|
||||
= NONE;
|
||||
|
||||
gm_handler->m_block_link = block_ptr;
|
||||
|
||||
return gm_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will delete a gatherblock object, which is created by MemGatherCreate function.
|
||||
*
|
||||
* @param gm_handler the gatherblock object to be deleted
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t DeleteMemGather(GatherMemType gm_handler)
|
||||
{
|
||||
register x_ubase critical_value = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
CHECK(((gm_handler->m_kind & Cmpt_KindN_Static)==0));
|
||||
|
||||
/* resume all the suspend tasks on gatherblock object */
|
||||
while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(gm_handler->wait_task.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
task->exstatus = -ERROR;
|
||||
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
}
|
||||
|
||||
/* release the memory for gather blocks */
|
||||
x_free(gm_handler->m_start_address);
|
||||
|
||||
gm_handler->m_kind = 0;
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* remove the gatherblock object from the global links */
|
||||
DoubleLinkListRmNode(&(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* release the memory for gather block structure */
|
||||
KERNEL_FREE(gm_handler);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will allocate a data block from gatherblock object
|
||||
*
|
||||
* @param gm_handler the gatherblock object to get data block
|
||||
* @param msec waiting time ,millisecond
|
||||
*
|
||||
* @return block pointer on success; NONE on failure
|
||||
*/
|
||||
void *AllocBlockMemGather(GatherMemType gm_handler, int32 msec)
|
||||
{
|
||||
int32 wait_time = 0;
|
||||
uint32 before_sleep = 0;
|
||||
register x_base critical_value = 0;
|
||||
uint8 *block_ptr = NONE;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
|
||||
/* get descriptor of task */
|
||||
task = GetKTaskDescriptor();
|
||||
wait_time = CalculteTickFromTimeMs(msec);
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
/* no free gatherblock*/
|
||||
while (0 == gm_handler->block_free_number) {
|
||||
if (wait_time == 0) {
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
KUpdateExstatus(ETIMEOUT);
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
task->exstatus = EOK;
|
||||
|
||||
/* suspend current task */
|
||||
SuspendKTask(task->id.id);
|
||||
DoubleLinkListInsertNodeAfter(&(gm_handler->wait_task), &(task->task_dync_sched_member.sched_link));
|
||||
|
||||
if (wait_time > 0) {
|
||||
before_sleep = CurrentTicksGain();
|
||||
/* start the timer */
|
||||
KTaskSetDelay(task,wait_time);
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* schedule */
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
if (EOK != task->exstatus)
|
||||
return NONE;
|
||||
|
||||
if (wait_time > 0) {
|
||||
wait_time -= CurrentTicksGain() - before_sleep;
|
||||
if (wait_time < 0)
|
||||
wait_time = 0;
|
||||
}
|
||||
critical_value = CriticalAreaLock();
|
||||
}
|
||||
/* decrease the number of free gatherblocks */
|
||||
gm_handler->block_free_number--;
|
||||
|
||||
block_ptr = gm_handler->m_block_link;
|
||||
NULL_PARAM_CHECK(block_ptr);
|
||||
|
||||
/* set the block_list attribute of gather_block structure */
|
||||
gm_handler->m_block_link = *(uint8 **)block_ptr;
|
||||
|
||||
*(uint8 **)block_ptr = (uint8 *)gm_handler;
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
HOOK(hook.mem.hook_GmAlloc, (gm_handler, (uint8 *)(block_ptr + sizeof(uint8 *))));
|
||||
|
||||
return (uint8 *)(block_ptr + sizeof(uint8 *));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will release a data block to gatherblock object
|
||||
*
|
||||
* @param data_block the data block to be released
|
||||
*/
|
||||
void FreeBlockMemGather(void *data_block)
|
||||
{
|
||||
uint8 **block_ptr;
|
||||
register x_base critical_value = 0;
|
||||
struct MemGather *gm_handler = NONE;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(data_block);
|
||||
|
||||
/* get gatherblock structure */
|
||||
block_ptr = (uint8 **)((uint8 *)data_block - sizeof(uint8 *));
|
||||
gm_handler = (struct MemGather *)*block_ptr;
|
||||
|
||||
HOOK(hook.mem.hook_GmFree, (gm_handler, data_block));
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* increase the number of gatherblocks */
|
||||
gm_handler->block_free_number ++;
|
||||
|
||||
*block_ptr = gm_handler->m_block_link;
|
||||
/* set the block_list attribute of gather_block object */
|
||||
gm_handler->m_block_link = (uint8 *)block_ptr;
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(gm_handler->wait_task.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
task->exstatus = EOK;
|
||||
|
||||
/* resume a suspend task */
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
59
kernel/memory/isolation.c
Normal file
59
kernel/memory/isolation.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: isolation.c
|
||||
* @brief: memory access structure definitions of ARM/RISCV
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_isolation.h>
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
|
||||
#if defined(ARCH_ARM) && defined(SURPORT_MPU)
|
||||
|
||||
struct Mpu *isolation = NONE;
|
||||
struct MemoryAccessLimit mem_access = {
|
||||
.Enable = MpuEnable ,
|
||||
.Disable = MpuDisable ,
|
||||
.Init = MpuInit ,
|
||||
.InitIsolation = NONE,
|
||||
.AddRegion = NONE,
|
||||
.ClearRegion = NONE ,
|
||||
.Free = NONE,
|
||||
.Load = MpuLoad,
|
||||
.FaultHandle = NONE,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_RISCV) && defined(SURPORT_PMP)
|
||||
|
||||
struct Pmp *isolation = NONE;
|
||||
struct MemoryAccessLimit mem_access = {
|
||||
.Enable = NONE ,
|
||||
.Disable = NONE ,
|
||||
.Init = NONE ,
|
||||
.InitIsolation = PmpInitIsolation,
|
||||
.AddRegion = PmpAddTorRegion,
|
||||
.ClearRegion = PmpClearRegion ,
|
||||
.Free = PmpFree,
|
||||
.Load = PmpLoad,
|
||||
.FaultHandle = PmpAccessFaultHandle,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
147
kernel/thread/CriticalArea.c
Normal file
147
kernel/thread/CriticalArea.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: critical area.c
|
||||
* @brief: the critical area lock functions definitions
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CRITICAL__AREA__
|
||||
#define __CRITICAL__AREA__
|
||||
|
||||
#include <xs_isr.h>
|
||||
#include <xs_ktask_stat.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_spinlock.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
HwSpinlock _CriticalLock;
|
||||
|
||||
/**
|
||||
* This function will do OsAssign lock.
|
||||
*
|
||||
* @return lock
|
||||
*/
|
||||
x_base CriticalAreaLock(void)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
lock = DisableLocalInterrupt();
|
||||
|
||||
if (Assign.smp_os_running_task[GetCpuId()]) {
|
||||
if (Assign.smp_os_running_task[GetCpuId()]->task_smp_info.critical_lock_cnt == 0) {
|
||||
Assign.assign_lock[GetCpuId()] ++;
|
||||
HwLockSpinlock(&_CriticalLock);
|
||||
}
|
||||
|
||||
Assign.smp_os_running_task[GetCpuId()]->task_smp_info.critical_lock_cnt ++;
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function will do OsAssign unlock.
|
||||
*
|
||||
* @return lock
|
||||
*/
|
||||
void CriticalAreaUnLock(x_base lock)
|
||||
{
|
||||
if (Assign.smp_os_running_task[GetCpuId()]) {
|
||||
if (Assign.smp_os_running_task[GetCpuId()]->task_smp_info.critical_lock_cnt > 0) {
|
||||
Assign.smp_os_running_task[GetCpuId()]->task_smp_info.critical_lock_cnt --;
|
||||
}
|
||||
|
||||
if (Assign.smp_os_running_task[GetCpuId()]->task_smp_info.critical_lock_cnt == 0) {
|
||||
if(Assign.assign_lock[GetCpuId()] > 0)
|
||||
Assign.assign_lock[GetCpuId()]--;
|
||||
HwUnlockSpinlock(&_CriticalLock);
|
||||
}
|
||||
}
|
||||
|
||||
EnableLocalInterrupt(lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get critical lock level.
|
||||
*
|
||||
* @return critical lock level
|
||||
*/
|
||||
uint16 GetOsAssignLockLevel(void)
|
||||
{
|
||||
return Assign.smp_os_running_task[GetCpuId()]->task_smp_info.critical_lock_cnt;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <xs_hook.h>
|
||||
|
||||
static int16 KTaskOsAssignLockNest;
|
||||
|
||||
/**
|
||||
* This function will get critical lock level.
|
||||
*
|
||||
* @return critical lock level
|
||||
*/
|
||||
uint16 GetOsAssignLockLevel(void) {
|
||||
return KTaskOsAssignLockNest;
|
||||
}
|
||||
|
||||
inline void ResetCriticalAreaLock(void ) {
|
||||
KTaskOsAssignLockNest = 0;
|
||||
}
|
||||
/**
|
||||
* This function will do OsAssign lock.
|
||||
*
|
||||
* @return lock
|
||||
*/
|
||||
x_base CriticalAreaLock(void) {
|
||||
x_base lock;
|
||||
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
KTaskOsAssignLockNest ++;
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will do OsAssign unlock.
|
||||
*
|
||||
* @return lock
|
||||
*/
|
||||
void CriticalAreaUnLock(x_base lock) {
|
||||
if (KTaskOsAssignLockNest >= 1) {
|
||||
KTaskOsAssignLockNest --;
|
||||
}
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
78
kernel/thread/Makefile
Normal file
78
kernel/thread/Makefile
Normal file
@@ -0,0 +1,78 @@
|
||||
SRC_FILES := tick.c kservicetask.c zombierecycle.c init.c lock.c idle.c linklist.c isr.c console.c ktask.c id.c CriticalArea.c bitmap.c delay.c double_link.c single_link.c assignstat.c ktask_stat.c
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_SEMAPHORE),y)
|
||||
SRC_FILES += semaphore.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_MUTEX),y)
|
||||
SRC_FILES += mutex.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_EVENT),y)
|
||||
SRC_FILES += event.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_MESSAGEQUEUE),y)
|
||||
SRC_FILES += msgqueue.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_SOFTTIMER),y)
|
||||
SRC_FILES += softtimer.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_BANNER),y)
|
||||
SRC_FILES += banner.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_HOOK),y)
|
||||
SRC_FILES += hook.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_QUEUEMANAGE),y)
|
||||
SRC_FILES += queue_manager.c
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_WORKQUEUE),y)
|
||||
SRC_FILES += workqueue.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_WAITQUEUE),y)
|
||||
SRC_FILES += waitqueue.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_DATAQUEUE),y)
|
||||
SRC_FILES += data_queue.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_CIRCULAR_AREA),y)
|
||||
SRC_FILES += circular_area.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_AVL_TREE),y)
|
||||
SRC_FILES += avl_tree.c
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(CONFIG_ARCH_SMP),y)
|
||||
SRC_FILES += smp_assign.c
|
||||
else
|
||||
SRC_FILES += assign.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_POLICY_RR),y)
|
||||
SRC_FILES += assign_roundrobin.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_POLICY_FIFO),y)
|
||||
SRC_FILES += assign_fifo.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_POLICY_RR_REMAINSLICE),y)
|
||||
SRC_FILES += assign_roundrobinremain.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_APPLICATION),y)
|
||||
SRC_FILES += appstartup.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
177
kernel/thread/appstartup.c
Normal file
177
kernel/thread/appstartup.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: appstartup.c
|
||||
* @brief: init application userspace and create main task
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <board.h>
|
||||
#ifdef TASK_ISOLATION
|
||||
#include <xs_isolation.h>
|
||||
#endif
|
||||
|
||||
#ifdef APP_STARTUP_FROM_SDCARD
|
||||
#include <iot-vfs_posix.h>
|
||||
#endif
|
||||
|
||||
extern int main(void);
|
||||
#ifdef USER_APPLICATION
|
||||
#ifndef SEPARATE_COMPILE
|
||||
void MainKTaskFunction(void *parameter)
|
||||
{
|
||||
#if defined(__ICCARM__) || defined(__GNUC__)
|
||||
main();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will create main application
|
||||
*
|
||||
*
|
||||
*/
|
||||
void CreateMainTask(void)
|
||||
{
|
||||
int32 main = 0;
|
||||
|
||||
#ifdef SEPARATE_COMPILE
|
||||
KPrintf("Tip!!! Kernel is separated with application. main entry : 0x%08x \n",USERSPACE->us_entrypoint);
|
||||
|
||||
main = UTaskCreate("main", (void*)USERSPACE->us_entrypoint, NONE,
|
||||
MAIN_KTASK_STACK_SIZE, MAIN_KTASK_PRIORITY);
|
||||
|
||||
#else
|
||||
main = KTaskCreate("main", MainKTaskFunction, NONE,
|
||||
MAIN_KTASK_STACK_SIZE, MAIN_KTASK_PRIORITY);
|
||||
|
||||
#endif
|
||||
|
||||
if(main < 0) {
|
||||
KPrintf("main create failed ...%s %d.\n",__FUNCTION__,__LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
StartupKTask(main);
|
||||
}
|
||||
|
||||
#ifdef SEPARATE_COMPILE
|
||||
int InitUserspace(void)
|
||||
{
|
||||
#ifdef APP_STARTUP_FROM_FLASH
|
||||
uint8_t *src = NONE;
|
||||
uint8_t *dest = NONE;
|
||||
uint8_t *end = NONE;
|
||||
|
||||
dest = (uint8_t *)USERSPACE->us_bssstart;
|
||||
end = (uint8_t *)USERSPACE->us_bssend;
|
||||
while (dest != end) {
|
||||
*dest++ = 0;
|
||||
}
|
||||
|
||||
/* Initialize all of user-space .data */
|
||||
|
||||
src = (uint8_t *)USERSPACE->us_datasource;
|
||||
dest = (uint8_t *)USERSPACE->us_datastart;
|
||||
end = (uint8_t *)USERSPACE->us_dataend;
|
||||
while (dest != end) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
#ifndef TASK_ISOLATION
|
||||
src = (uint8_t *)&g_service_table_start;
|
||||
dest = (uint8_t *)SERVICE_TABLE_ADDRESS;
|
||||
end = (uint8_t *)&g_service_table_end;
|
||||
while (src != end) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
#endif
|
||||
|
||||
UserInitBoardMemory((void*)USER_MEMORY_START_ADDRESS, (void*)USER_MEMORY_END_ADDRESS);
|
||||
|
||||
#ifdef MOMERY_PROTECT_ENABLE
|
||||
if ( mem_access.Init != NONE){
|
||||
if(mem_access.Init( (void **)(&isolation)) == EOK)
|
||||
mem_access.Load(isolation);
|
||||
}
|
||||
#endif
|
||||
return EOK;
|
||||
#endif
|
||||
|
||||
#ifdef APP_STARTUP_FROM_SDCARD
|
||||
int fd = 0;
|
||||
char buf[1024] = {0};
|
||||
int len = 0;
|
||||
int len_check = 0;
|
||||
uint8_t *src = NONE;
|
||||
uint8_t *dest = NONE;
|
||||
uint8_t *end = NONE;
|
||||
#ifndef FS_VFS
|
||||
KPrintf("fs not enable!%s %d\n",__func__,__LINE__);
|
||||
CHECK(0);
|
||||
#endif
|
||||
|
||||
fd = open(BOARD_APP_NAME,O_RDONLY );
|
||||
if(fd > 0) {
|
||||
KPrintf("open app bin %s success.\n",BOARD_APP_NAME);
|
||||
|
||||
dest = (uint8_t *)USERSPACE;
|
||||
/* copy app to USERSPACE */
|
||||
while(RET_TRUE) {
|
||||
memset(buf, 0 , 1024);
|
||||
len = read(fd, buf, 1024);
|
||||
KPrintf("read app bin len %d\n",len);
|
||||
if(len > 0) {
|
||||
memcpy(dest, buf, len);
|
||||
dest = dest + len;
|
||||
len_check = len_check + len;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(len_check <= 0){
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
dest = (uint8_t *)USERSPACE->us_bssstart;
|
||||
end = (uint8_t *)USERSPACE->us_bssend;
|
||||
while (dest != end) {
|
||||
*dest++ = 0;
|
||||
}
|
||||
|
||||
src = (uint8_t *)&g_service_table_start;
|
||||
dest = (uint8_t *)SERVICE_TABLE_ADDRESS;
|
||||
end = (uint8_t *)&g_service_table_end;
|
||||
|
||||
while (src != end) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
UserInitBoardMemory((void*)USER_MEMORY_START_ADDRESS, (void*)USER_MEMORY_END_ADDRESS);
|
||||
|
||||
return EOK;
|
||||
|
||||
} else {
|
||||
KPrintf("open app bin %s failed.\n",BOARD_APP_NAME);
|
||||
return -EEMPTY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
389
kernel/thread/assign.c
Normal file
389
kernel/thread/assign.c
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: assign.c
|
||||
* @brief: system scheduler of single cpu
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_ktask_stat.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_hook.h>
|
||||
|
||||
struct Assign Assign;
|
||||
|
||||
static struct PriorityReadyVectorDone SingleReadyVectorDone =
|
||||
{
|
||||
OsAssignReadyVectorInit,
|
||||
KTaskInsertToReadyVector,
|
||||
KTaskOsAssignRemoveKTask,
|
||||
};
|
||||
|
||||
/**
|
||||
* task schedule function.getting the highest priority task then switching to it
|
||||
*/
|
||||
void KTaskOsAssign(void)
|
||||
{
|
||||
|
||||
x_ubase highest_prio = 0;
|
||||
int need_insert_from_task = 0;
|
||||
struct TaskDescriptor *new_task = NONE;
|
||||
struct TaskDescriptor *from_task = NONE;
|
||||
|
||||
if(GetOsAssignLockLevel() >= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( isrManager.done->isInIsr() ){
|
||||
isrManager.done->setSwitchTrigerFlag();
|
||||
return;
|
||||
}
|
||||
|
||||
/* if the bitmap is empty then do not switch */
|
||||
if(RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.os_assign_read_vector)) {
|
||||
return;
|
||||
}
|
||||
|
||||
highest_prio = Assign.os_assign_read_vector.highest_prio;
|
||||
new_task = ChooseTaskWithHighestPrio(&Assign.os_assign_read_vector);
|
||||
|
||||
if(RET_TRUE != JudgeKTaskStatIsRunning(Assign.os_running_task)) {
|
||||
CHECK(NONE != new_task);
|
||||
goto SWITCH;
|
||||
}
|
||||
|
||||
/* if the running task’ priority is the highest and this task is not be yield then do not switch */
|
||||
if(highest_prio < Assign.os_running_task->task_dync_sched_member.cur_prio) {
|
||||
return;
|
||||
} else {
|
||||
need_insert_from_task = 1;
|
||||
}
|
||||
|
||||
SWITCH:
|
||||
if (new_task != Assign.os_running_task) {
|
||||
Assign.current_priority = (uint8)highest_prio;
|
||||
from_task = Assign.os_running_task;
|
||||
|
||||
HOOK(hook.assign.hook_Assign, (from_task, new_task));
|
||||
|
||||
if (need_insert_from_task) {
|
||||
Assign.ready_vector_done->insert(from_task);
|
||||
}
|
||||
|
||||
Assign.ready_vector_done->remove(new_task);
|
||||
KTaskStatSetAsRunning(new_task);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED,
|
||||
("[%d]switch to priority#%d "
|
||||
"task:%.*s(sp:0x%08x), "
|
||||
"from task:%.*s(sp: 0x%08x)\n",
|
||||
isrManager.done->getCounter(), highest_prio,
|
||||
NAME_NUM_MAX, new_task->task_base_info.name, new_task->stack_point,
|
||||
NAME_NUM_MAX, from_task->task_base_info.name, from_task->stack_point));
|
||||
|
||||
#ifdef KERNEL_STACK_OVERFLOW_CHECK
|
||||
_KTaskOsAssignStackCheck(new_task);
|
||||
#endif
|
||||
|
||||
|
||||
SwitchKtaskContext((x_ubase)&from_task->stack_point,
|
||||
(x_ubase)&new_task->stack_point, new_task);
|
||||
|
||||
} else {
|
||||
Assign.ready_vector_done->remove(Assign.os_running_task);
|
||||
KTaskStatSetAsRunning(Assign.os_running_task);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void KTaskOsAssignDoIrqSwitch(void *context)
|
||||
{
|
||||
|
||||
x_ubase highest_prio = 0;
|
||||
int need_insert_from_task = 0;
|
||||
struct TaskDescriptor *new_task = NONE;
|
||||
struct TaskDescriptor *from_task = NONE;
|
||||
|
||||
if(GetOsAssignLockLevel() >= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( isrManager.done->getSwitchTrigerFlag() == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
isrManager.done->clearSwitchTrigerFlag();
|
||||
/* if the bitmap is empty then do not switch */
|
||||
if(RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.os_assign_read_vector)) {
|
||||
return;
|
||||
}
|
||||
|
||||
highest_prio = Assign.os_assign_read_vector.highest_prio;
|
||||
new_task = ChooseTaskWithHighestPrio(&Assign.os_assign_read_vector);
|
||||
|
||||
if(RET_TRUE != JudgeKTaskStatIsRunning(Assign.os_running_task)) {
|
||||
CHECK(NONE != new_task);
|
||||
goto SWITCH;
|
||||
}
|
||||
|
||||
/* if the running task’ priority is the highest and this task is not be yield then do not switch */
|
||||
if(highest_prio < Assign.os_running_task->task_dync_sched_member.cur_prio) {
|
||||
return;
|
||||
} else {
|
||||
need_insert_from_task = 1;
|
||||
}
|
||||
|
||||
SWITCH:
|
||||
|
||||
if (new_task != Assign.os_running_task) {
|
||||
Assign.current_priority = (uint8)highest_prio;
|
||||
from_task = Assign.os_running_task;
|
||||
|
||||
HOOK(hook.assign.hook_Assign, (from_task, new_task));
|
||||
|
||||
if (need_insert_from_task) {
|
||||
Assign.ready_vector_done->insert(from_task);
|
||||
}
|
||||
|
||||
Assign.ready_vector_done->remove(new_task);
|
||||
KTaskStatSetAsRunning(new_task);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED,
|
||||
("[%d]switch to priority#%d "
|
||||
"task:%.*s(sp:0x%08x), "
|
||||
"from task:%.*s(sp: 0x%08x)\n",
|
||||
isrManager.done->getCounter(), highest_prio,
|
||||
NAME_NUM_MAX, new_task->task_base_info.name, new_task->stack_point,
|
||||
NAME_NUM_MAX, from_task->task_base_info.name, from_task->stack_point));
|
||||
|
||||
#ifdef KERNEL_STACK_OVERFLOW_CHECK
|
||||
_KTaskOsAssignStackCheck(new_task);
|
||||
#endif
|
||||
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("switch in interrupt\n"));
|
||||
HwInterruptcontextSwitch((x_ubase)&from_task->stack_point,
|
||||
(x_ubase)&new_task->stack_point, new_task, context);
|
||||
|
||||
} else {
|
||||
Assign.ready_vector_done->remove(Assign.os_running_task);
|
||||
KTaskStatSetAsRunning(Assign.os_running_task);
|
||||
}
|
||||
}
|
||||
|
||||
void KTaskOsAssignAfterIrq(void *context)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
KTaskOsAssignDoIrqSwitch(context);
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
/*
|
||||
* insert a ready task to system ready table with READY state and remove it from suspend list
|
||||
*
|
||||
* @param task the task descriptor
|
||||
*
|
||||
*/
|
||||
void KTaskInsertToReadyVector(struct TaskDescriptor *task)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
KTaskStatSetAsReady(task);
|
||||
AssignPolicyInsert(task, &Assign.os_assign_read_vector);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("insert task[%.*s], the priority: %d\n",
|
||||
NAME_NUM_MAX, task->task_base_info.name, task->task_dync_sched_member.cur_prio));
|
||||
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
MERGE_FLAG(&Assign.os_assign_read_vector.ready_vector[task->task_dync_sched_member.bitmap_offset], task->task_dync_sched_member.bitmap_row);
|
||||
#endif
|
||||
MERGE_FLAG(&Assign.os_assign_read_vector.priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* a task will be removed from ready table.
|
||||
*
|
||||
* @param task task descriptor
|
||||
*
|
||||
*/
|
||||
void KTaskOsAssignRemoveKTask(struct TaskDescriptor *task)
|
||||
{
|
||||
x_base lock = 0;
|
||||
x_ubase number = 0;
|
||||
x_ubase highest_priority = 0;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("remove task[%.*s], the priority: %d\n",
|
||||
NAME_NUM_MAX, task->task_base_info.name,
|
||||
task->task_dync_sched_member.cur_prio));
|
||||
|
||||
DoubleLinkListRmNode(&(task->task_dync_sched_member.sched_link));
|
||||
|
||||
if (IsDoubleLinkListEmpty(&(Assign.os_assign_read_vector.priority_ready_vector[task->task_dync_sched_member.cur_prio]))) {
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
CLEAR_FLAG(&Assign.os_assign_read_vector.ready_vector[task->task_dync_sched_member.bitmap_offset], task->task_dync_sched_member.bitmap_row);
|
||||
if (Assign.os_assign_read_vector.ready_vector[task->task_dync_sched_member.bitmap_offset] == 0) {
|
||||
CLEAR_FLAG(&Assign.os_assign_read_vector.priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
}
|
||||
number = PrioCaculate(Assign.os_assign_read_vector.priority_ready_group);
|
||||
highest_priority = (number * 8) + PrioCaculate(Assign.os_assign_read_vector.ready_vector[number]);
|
||||
#else
|
||||
CLEAR_FLAG(&Assign.os_assign_read_vector.priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
highest_priority = PrioCaculate(Assign.os_assign_read_vector.priority_ready_group);
|
||||
#endif
|
||||
Assign.os_assign_read_vector.highest_prio = highest_priority;
|
||||
}
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
|
||||
|
||||
static inline void SwitchToFirstRunningTask(struct TaskDescriptor* task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
Assign.ready_vector_done->remove(task);
|
||||
KTaskStatSetAsRunning(task);
|
||||
SwitchKtaskContextTo((x_ubase)&task->stack_point, task);
|
||||
}
|
||||
|
||||
static inline void SetSystemRunningTask(struct TaskDescriptor* task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
Assign.os_running_task = task;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will yield current task.
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
|
||||
x_err_t YieldOsAssign(void)
|
||||
{
|
||||
x_base lock = 0;
|
||||
x_ubase highest_prio = 0;
|
||||
struct TaskDescriptor *new_task = NONE;
|
||||
struct TaskDescriptor *from_task = NONE;
|
||||
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
if(GetOsAssignLockLevel() >= 1) {
|
||||
ENABLE_INTERRUPT(lock);
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (isrManager.done->isInIsr()) {
|
||||
ENABLE_INTERRUPT(lock);
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* if the bitmap is empty then do not switch */
|
||||
if(RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.os_assign_read_vector)) {
|
||||
ENABLE_INTERRUPT(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
highest_prio = Assign.os_assign_read_vector.highest_prio;
|
||||
new_task = ChooseTaskWithHighestPrio(&Assign.os_assign_read_vector);
|
||||
|
||||
from_task = Assign.os_running_task;
|
||||
|
||||
if(RET_TRUE != JudgeKTaskStatIsRunning(from_task)) {
|
||||
CHECK(NONE != new_task);
|
||||
} else {
|
||||
Assign.ready_vector_done->insert(from_task);
|
||||
}
|
||||
|
||||
if (new_task != from_task) {
|
||||
Assign.current_priority = (uint8)highest_prio;
|
||||
|
||||
HOOK(hook.assign.hook_Assign, (from_task, new_task));
|
||||
|
||||
Assign.ready_vector_done->remove(new_task);
|
||||
KTaskStatSetAsRunning(new_task);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED,
|
||||
("[%d]switch to priority#%d "
|
||||
"task:%.*s(sp:0x%08x), "
|
||||
"from task:%.*s(sp: 0x%08x)\n",
|
||||
isrManager.done->getCounter(), highest_prio,
|
||||
NAME_NUM_MAX, new_task->task_base_info.name, new_task->stack_point,
|
||||
NAME_NUM_MAX, from_task->task_base_info.name, from_task->stack_point));
|
||||
|
||||
#ifdef KERNEL_STACK_OVERFLOW_CHECK
|
||||
_KTaskOsAssignStackCheck(new_task);
|
||||
#endif
|
||||
|
||||
|
||||
SwitchKtaskContext((x_ubase)&from_task->stack_point,
|
||||
(x_ubase)&new_task->stack_point, new_task);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
goto __exit;
|
||||
} else {
|
||||
Assign.ready_vector_done->remove(Assign.os_running_task);
|
||||
KTaskStatSetAsRunning(Assign.os_running_task);
|
||||
}
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
|
||||
__exit:
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* OsAssign startup function
|
||||
* .
|
||||
*/
|
||||
void StartupOsAssign(void)
|
||||
{
|
||||
struct TaskDescriptor *FirstRunningTask = NONE;
|
||||
|
||||
FirstRunningTask = ChooseTaskWithHighestPrio(&Assign.os_assign_read_vector);
|
||||
|
||||
SetSystemRunningTask(FirstRunningTask);
|
||||
|
||||
SwitchToFirstRunningTask(FirstRunningTask);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* system OsAssign init function
|
||||
*/
|
||||
void SysInitOsAssign(void)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("start Os Assign: max priority 0x%02x\n",
|
||||
KTASK_PRIORITY_MAX));
|
||||
|
||||
Assign.ready_vector_done = &SingleReadyVectorDone;
|
||||
Assign.ready_vector_done->init(&Assign.os_assign_read_vector);
|
||||
|
||||
ResetCriticalAreaLock();
|
||||
}
|
||||
51
kernel/thread/assign_fifo.c
Normal file
51
kernel/thread/assign_fifo.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: assign_roundrobin.c
|
||||
* @brief: ready table and timeslice functions definitions of fifo scheduler algorithm
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
#define NO_TIMESLICE (0)
|
||||
|
||||
void FifoTaskTimesliceInit(struct TaskDescriptor *task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
task->task_dync_sched_member.origin_timeslice = NO_TIMESLICE;
|
||||
task->task_dync_sched_member.rest_timeslice = NO_TIMESLICE;
|
||||
}
|
||||
|
||||
|
||||
void FifoReadyVectorInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table)
|
||||
{
|
||||
DoubleLinklistType* tail = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
NULL_PARAM_CHECK(ready_table);
|
||||
|
||||
tail = ready_table->priority_ready_vector[task->task_dync_sched_member.cur_prio].node_prev;
|
||||
DoubleLinkListInsertNodeAfter(tail, &(task->task_dync_sched_member.sched_link));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FifoTaskTimesliceUpdate()
|
||||
{
|
||||
return;
|
||||
}
|
||||
56
kernel/thread/assign_roundrobin.c
Normal file
56
kernel/thread/assign_roundrobin.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: assign_roundrobin.c
|
||||
* @brief: ready table and timeslice functions definitions of roundrobin scheduler algorithm
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
void RoundRobinTaskTimesliceInit(struct TaskDescriptor *task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
task->task_dync_sched_member.origin_timeslice = 10;
|
||||
task->task_dync_sched_member.rest_timeslice = 10;
|
||||
}
|
||||
|
||||
void RoundRobinReadyVectorInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table)
|
||||
{
|
||||
DoubleLinklistType* tail = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
NULL_PARAM_CHECK(ready_table);
|
||||
|
||||
tail = ready_table->priority_ready_vector[task->task_dync_sched_member.cur_prio].node_prev;
|
||||
DoubleLinkListInsertNodeAfter(tail, &(task->task_dync_sched_member.sched_link));
|
||||
|
||||
}
|
||||
|
||||
void RoundRobinTaskTimesliceUpdate(struct TaskDescriptor *task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
-- task->task_dync_sched_member.rest_timeslice;
|
||||
if (task->task_dync_sched_member.rest_timeslice == 0)
|
||||
{
|
||||
task->task_dync_sched_member.rest_timeslice = task->task_dync_sched_member.origin_timeslice;
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
}
|
||||
|
||||
79
kernel/thread/assign_roundrobinremain.c
Normal file
79
kernel/thread/assign_roundrobinremain.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: assign_roundrobin.c
|
||||
* @brief: ready table and timeslice functions definitions of remain ticks first scheduler algorithm
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
void RoundRobinRemainTaskTimesliceInit(struct TaskDescriptor *task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
task->task_dync_sched_member.origin_timeslice = 10;
|
||||
task->task_dync_sched_member.rest_timeslice = 10;
|
||||
}
|
||||
|
||||
|
||||
void RoundRobinRemainReadyVectorInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table)
|
||||
{
|
||||
DoubleLinklistType* node = NONE;
|
||||
DoubleLinklistType* tail = NONE;
|
||||
struct TaskDescriptor *tmp = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
NULL_PARAM_CHECK(ready_table);
|
||||
|
||||
if ( task->task_dync_sched_member.advance_cnt < KTASK_MAX_ADVANCE_PROCESS_TIME ) {
|
||||
DOUBLE_LINKLIST_FOR_EACH(node, &ready_table->priority_ready_vector[task->task_dync_sched_member.cur_prio]) {
|
||||
tmp = SYS_DOUBLE_LINKLIST_ENTRY(node, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
if (task->task_dync_sched_member.rest_timeslice < tmp->task_dync_sched_member.rest_timeslice) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( node != &ready_table->priority_ready_vector[task->task_dync_sched_member.cur_prio]) {
|
||||
DoubleLinkListInsertNodeBefore(node, &(task->task_dync_sched_member.sched_link));
|
||||
} else {
|
||||
tail = ready_table->priority_ready_vector[task->task_dync_sched_member.cur_prio].node_prev;
|
||||
DoubleLinkListInsertNodeAfter(tail, &(task->task_dync_sched_member.sched_link));
|
||||
}
|
||||
} else {
|
||||
tail = ready_table->priority_ready_vector[task->task_dync_sched_member.cur_prio].node_prev;
|
||||
DoubleLinkListInsertNodeAfter(tail, &(task->task_dync_sched_member.sched_link));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RoundRobinRemainTaskTimesliceUpdate(struct TaskDescriptor *task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
-- task->task_dync_sched_member.rest_timeslice;
|
||||
if (task->task_dync_sched_member.rest_timeslice == 0)
|
||||
{
|
||||
if ( task->task_dync_sched_member.advance_cnt < KTASK_MAX_ADVANCE_PROCESS_TIME ) {
|
||||
task->task_dync_sched_member.advance_cnt++;
|
||||
}
|
||||
|
||||
task->task_dync_sched_member.rest_timeslice = task->task_dync_sched_member.origin_timeslice;
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
}
|
||||
|
||||
112
kernel/thread/assignstat.c
Normal file
112
kernel/thread/assignstat.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: assignstat.c
|
||||
* @brief: check system read ready and task stack
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_assign.h>
|
||||
|
||||
#ifdef KERNEL_STACK_OVERFLOW_CHECK
|
||||
/**
|
||||
* a task stack check function
|
||||
*
|
||||
* @param task task descriptor
|
||||
*/
|
||||
void _KTaskOsAssignStackCheck(struct TaskDescriptor *task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
if ((x_ubase)task->stack_point<= (x_ubase)task->task_base_info.stack_start ||
|
||||
(x_ubase)task->stack_point >
|
||||
(x_ubase)task->task_base_info.stack_start + (x_ubase)task->task_base_info.stack_depth) {
|
||||
|
||||
KPrintf("task name:%s id:%d stack overflow,sp %p stacktop %p stack depth 0x%x\n", task->task_base_info.name,task->id.id,task->stack_point,(uint32*)task->task_base_info.stack_start + task->task_base_info.stack_depth,task->task_base_info.stack_depth);
|
||||
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int32 JudgeAssignReadyBitmapIsEmpty(struct OsAssignReadyVector *ready_vector)
|
||||
{
|
||||
NULL_PARAM_CHECK(ready_vector);
|
||||
return ((ready_vector->priority_ready_group == 0) ? RET_TRUE: 0);
|
||||
}
|
||||
|
||||
struct TaskDescriptor * ChooseTaskWithHighestPrio(struct OsAssignReadyVector *ready_vector)
|
||||
{
|
||||
struct TaskDescriptor *TargetTask = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(ready_vector);
|
||||
|
||||
TargetTask = SYS_DOUBLE_LINKLIST_ENTRY(ready_vector->priority_ready_vector[ready_vector->highest_prio].node_next,
|
||||
struct TaskDescriptor,
|
||||
task_dync_sched_member.sched_link);
|
||||
|
||||
return TargetTask;
|
||||
}
|
||||
|
||||
void OsAssignReadyVectorInit(struct OsAssignReadyVector *ready_vector)
|
||||
{
|
||||
register x_base prio = 0;
|
||||
NULL_PARAM_CHECK(ready_vector);
|
||||
|
||||
while(prio < KTASK_PRIORITY_MAX)
|
||||
{
|
||||
InitDoubleLinkList(&ready_vector->priority_ready_vector[prio]);
|
||||
prio++;
|
||||
}
|
||||
ready_vector->highest_prio = 0;
|
||||
ready_vector->priority_ready_group = 0;
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
memset(ready_vector->ready_vector, 0, sizeof(ready_vector->ready_vector));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will insert a task to system ready table according to sched policy(FIFO/RR/RR+remain timeslice)
|
||||
*
|
||||
* @param task task descriptor
|
||||
* @param ready_table task ready_table
|
||||
*/
|
||||
void AssignPolicyInsert(struct TaskDescriptor *task, struct OsAssignReadyVector* ready_table)
|
||||
{
|
||||
DoubleLinklistType* node = NONE;
|
||||
DoubleLinklistType* tail = NONE;
|
||||
struct TaskDescriptor *tmp = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
NULL_PARAM_CHECK(ready_table);
|
||||
|
||||
#if defined (SCHED_POLICY_FIFO)
|
||||
FifoReadyVectorInsert(task, ready_table);
|
||||
#elif defined (SCHED_POLICY_RR)
|
||||
RoundRobinReadyVectorInsert(task, ready_table);
|
||||
#elif defined (SCHED_POLICY_RR_REMAINSLICE)
|
||||
RoundRobinRemainReadyVectorInsert(task, ready_table);
|
||||
#endif
|
||||
|
||||
if(NONE == task || NONE == ready_table) {
|
||||
KPrintf("PARAM CHECK FAILED ...%s %d param is NULL.\n",__FUNCTION__,__LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
if(task->task_dync_sched_member.cur_prio > ready_table->highest_prio) {
|
||||
ready_table->highest_prio = task->task_dync_sched_member.cur_prio;
|
||||
}
|
||||
}
|
||||
369
kernel/thread/avl_tree.c
Normal file
369
kernel/thread/avl_tree.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: avl_tree.c
|
||||
* @brief: avl_tree file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xs_avltree.h"
|
||||
#include <string.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_memory.h>
|
||||
|
||||
/**
|
||||
* This function will return the node height of the avl tree
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @return 0
|
||||
*/
|
||||
static uint32 AvlTreeGetNodeHeight(AvlNodeType avl_node)
|
||||
{
|
||||
if(avl_node) {
|
||||
return AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return the node balance factor of the avl tree
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
*/
|
||||
static int32 AvlTreeGetNodeBalanceFactor(AvlNodeType avl_node)
|
||||
{
|
||||
if(avl_node) {
|
||||
return AvlTreeGetNodeHeight(avl_node->left) - AvlTreeGetNodeHeight(avl_node->right);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will support right rotate to balance the avl tree(eg. LL case)
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @return avl tree node
|
||||
*/
|
||||
static AvlNodeType AvlTreeSetRightRotate(AvlNodeType avl_node)
|
||||
{
|
||||
NULL_PARAM_CHECK(avl_node);
|
||||
|
||||
AvlNodeType new_node = avl_node->left;
|
||||
|
||||
avl_node->left = new_node->right;
|
||||
new_node->right = avl_node;
|
||||
|
||||
new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1;
|
||||
avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1;
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will support left rotate to balance the avl tree(eg. RR case)
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @return avl tree node
|
||||
*/
|
||||
static AvlNodeType AvlTreeSetLeftRotate(AvlNodeType avl_node)
|
||||
{
|
||||
NULL_PARAM_CHECK(avl_node);
|
||||
|
||||
AvlNodeType new_node = avl_node->right;
|
||||
|
||||
avl_node->right = new_node->left;
|
||||
new_node->left = avl_node;
|
||||
|
||||
new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1;
|
||||
avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1;
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will support left and right rotate to balance the avl tree(eg. LR case)
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @return avl tree node
|
||||
*/
|
||||
static AvlNodeType AvlTreeSetLRRotate(AvlNodeType avl_node)
|
||||
{
|
||||
NULL_PARAM_CHECK(avl_node);
|
||||
|
||||
AvlNodeType new_node = NONE;
|
||||
AvlNodeType left_node = avl_node->left;
|
||||
|
||||
/*step1 : Left rotate*/
|
||||
avl_node->left = AvlTreeSetLeftRotate(left_node);
|
||||
|
||||
/*step2 : Right rotate*/
|
||||
new_node = AvlTreeSetRightRotate(avl_node);
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will support right and left rotate to balance the avl tree(eg. RL case)
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @return avl tree node
|
||||
*/
|
||||
static AvlNodeType AvlTreeSetRLRotate(AvlNodeType avl_node)
|
||||
{
|
||||
NULL_PARAM_CHECK(avl_node);
|
||||
|
||||
AvlNodeType new_node = NONE;
|
||||
AvlNodeType right_node = avl_node->right;
|
||||
|
||||
/*step1 : Right rotate*/
|
||||
avl_node->right = AvlTreeSetRightRotate(right_node);
|
||||
|
||||
/*step2 : Left rotate*/
|
||||
new_node = AvlTreeSetLeftRotate(avl_node);
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will balance the avl tree when inserting or deleting node
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @return avl tree node
|
||||
*/
|
||||
static AvlNodeType AvlTreeBalance(AvlNodeType avl_node)
|
||||
{
|
||||
if(avl_node)
|
||||
{
|
||||
AvlNodeType new_node = NONE;
|
||||
uint32 avlnode_BF = AVL_ABS(AvlTreeGetNodeBalanceFactor(avl_node));
|
||||
|
||||
if(avlnode_BF > 1) {
|
||||
if(AvlTreeGetNodeBalanceFactor(avl_node->left) > 0) {
|
||||
/*LL case*/
|
||||
new_node = AvlTreeSetRightRotate(avl_node);
|
||||
} else if(AvlTreeGetNodeBalanceFactor(avl_node->left) < 0) {
|
||||
/*LR case*/
|
||||
new_node = AvlTreeSetLRRotate(avl_node);
|
||||
} else if(AvlTreeGetNodeBalanceFactor(avl_node->right) < 0) {
|
||||
/*RR case*/
|
||||
new_node = AvlTreeSetLeftRotate(avl_node);
|
||||
} else if(AvlTreeGetNodeBalanceFactor(avl_node->right) > 0) {
|
||||
/*RL case*/
|
||||
new_node = AvlTreeSetRLRotate(avl_node);
|
||||
}
|
||||
} else {
|
||||
/*the avl tree is balanced, no need to rebalance*/
|
||||
new_node = avl_node;
|
||||
}
|
||||
|
||||
return new_node;
|
||||
|
||||
} else {
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will insert data to the avl tree
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @param data input data
|
||||
*/
|
||||
AvlNodeType AvlTreeInsertNode(AvlNodeType avl_node, int32 data)
|
||||
{
|
||||
AvlNodeType new_node = NONE;
|
||||
|
||||
if(NONE == avl_node) {
|
||||
new_node = x_malloc(sizeof(struct AvlNode));
|
||||
if(NONE == new_node) {
|
||||
KPrintf("AvlTreeInsertNode malloc AvlNode failed\n");
|
||||
x_free(new_node);
|
||||
return NONE;
|
||||
}
|
||||
new_node->data = data;
|
||||
new_node->left = NONE;
|
||||
new_node->right = NONE;
|
||||
new_node->height = 1;
|
||||
avl_node = new_node;
|
||||
} else if(data == avl_node->data) {
|
||||
/*input data is already existed*/
|
||||
KPrintf("the input data is already existed. just return\n");
|
||||
return avl_node;
|
||||
} else {
|
||||
if(avl_node->data < data) {
|
||||
avl_node->right = AvlTreeInsertNode(avl_node->right, data);
|
||||
if(NONE == avl_node->right) {
|
||||
KPrintf("AvlTreeInsertNode find right avl_node data failed\n");
|
||||
return NONE;
|
||||
}
|
||||
} else {
|
||||
avl_node->left = AvlTreeInsertNode(avl_node->left, data);
|
||||
if(NONE == avl_node->left) {
|
||||
KPrintf("AvlTreeInsertNode find left avl_node data failed\n");
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AvlTreeBalance(avl_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will find the pre node of the avl_node
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @return avl tree node
|
||||
*/
|
||||
static AvlNodeType AvlTreeFindPreNode(AvlNodeType avl_node)
|
||||
{
|
||||
NULL_PARAM_CHECK(avl_node);
|
||||
|
||||
AvlNodeType pre_node = NONE;
|
||||
|
||||
if(avl_node->left) {
|
||||
if(avl_node->left->right) {
|
||||
pre_node = avl_node->left->right;
|
||||
while(pre_node->right) {
|
||||
pre_node = pre_node->right;
|
||||
}
|
||||
} else {
|
||||
pre_node = avl_node->left;
|
||||
}
|
||||
} else {
|
||||
pre_node = avl_node;
|
||||
}
|
||||
|
||||
return pre_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will delete a certain node, ultimate target is to find the leaf node
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @param data delete data
|
||||
* @return avl tree node
|
||||
*/
|
||||
static AvlNodeType AvlTreeDeleteLeafNode(AvlNodeType avl_node)
|
||||
{
|
||||
AvlNodeType pre_node = NONE;
|
||||
|
||||
if((NONE == avl_node->left) && (NONE == avl_node->right)) {
|
||||
/*Leaf Node*/
|
||||
avl_node = NONE;
|
||||
x_free(avl_node);
|
||||
} else if(NONE == avl_node->left) {
|
||||
/*Right child is Leaf Node*/
|
||||
avl_node->data = avl_node->right->data;
|
||||
avl_node->right = NONE;
|
||||
x_free(avl_node->right);
|
||||
} else if(NONE == avl_node->right) {
|
||||
/*Left child is Leaf Node*/
|
||||
avl_node->data = avl_node->left->data;
|
||||
avl_node->left = NONE;
|
||||
x_free(avl_node->left);
|
||||
} else {
|
||||
/*Find the pre node to replace the avl node, then delete the pre node*/
|
||||
pre_node = AvlTreeFindPreNode(avl_node);
|
||||
if(pre_node) {
|
||||
avl_node->data = pre_node->data;
|
||||
avl_node->left = AvlTreeDeleteNode(avl_node->left, pre_node->data);
|
||||
}
|
||||
}
|
||||
|
||||
return avl_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will delete data from the avl tree
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @param data delete data
|
||||
*/
|
||||
AvlNodeType AvlTreeDeleteNode(AvlNodeType avl_node, int32 data)
|
||||
{
|
||||
if(avl_node) {
|
||||
if(data == avl_node->data) {
|
||||
avl_node = AvlTreeDeleteLeafNode(avl_node);
|
||||
} else {
|
||||
if(avl_node->data < data) {
|
||||
avl_node->right = AvlTreeDeleteNode(avl_node->right, data);
|
||||
} else {
|
||||
avl_node->left = AvlTreeDeleteNode(avl_node->left, data);
|
||||
}
|
||||
}
|
||||
|
||||
return AvlTreeBalance(avl_node);
|
||||
} else {
|
||||
KPrintf("AvlTreeDeleteNode cannot find the delete data\n");
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will modify certain data of the avl tree
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @param src_data src data
|
||||
* @param dst_data dst data
|
||||
*/
|
||||
AvlNodeType AvlNodeModifyNode(AvlNodeType avl_node, int32 src_data, int32 dst_data)
|
||||
{
|
||||
AvlNodeType dst_node = NONE;
|
||||
|
||||
if(avl_node) {
|
||||
/*Step1 : delete the src data node*/
|
||||
avl_node = AvlTreeDeleteNode(avl_node, src_data);
|
||||
|
||||
/*Step2 : insert the dst data node*/
|
||||
dst_node = AvlTreeInsertNode(avl_node, dst_data);
|
||||
|
||||
} else {
|
||||
KPrintf("AvlNodeModifyNode cannot find the src data node\n");
|
||||
return NONE;
|
||||
}
|
||||
|
||||
return dst_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return the avl node which has the data
|
||||
*
|
||||
* @param avl_node avl tree node descriptor
|
||||
* @param data data
|
||||
*/
|
||||
AvlNodeType AvlNodeSearchNode(AvlNodeType avl_node, int32 data)
|
||||
{
|
||||
AvlNodeType dst_node = NONE;
|
||||
|
||||
if(avl_node) {
|
||||
if(data == avl_node->data) {
|
||||
dst_node = avl_node;
|
||||
KPrintf("AvlNodeSearchNode %d is existed return the node\n", avl_node->data);
|
||||
} else if(avl_node->data < data) {
|
||||
dst_node = AvlNodeSearchNode(avl_node->right, data);
|
||||
} else {
|
||||
dst_node = AvlNodeSearchNode(avl_node->left, data);
|
||||
}
|
||||
} else {
|
||||
KPrintf("AvlNodeSearchNode avl_node is NONE.\n");
|
||||
return NONE;
|
||||
}
|
||||
|
||||
return dst_node;
|
||||
}
|
||||
50
kernel/thread/banner.c
Normal file
50
kernel/thread/banner.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: banner.c
|
||||
* @brief: system banner
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_banner.h>
|
||||
|
||||
/**
|
||||
* This function will show the version of XiUOS
|
||||
*/
|
||||
void ShowBanner(void)
|
||||
{
|
||||
KPrintf("*********************************************************************************************\n");
|
||||
KPrintf("AAAAAAA AAAAAAA IIIIIIII IIIIIIII IIIIIIIII TTTTTTTTTTTTTTT \n");
|
||||
KPrintf("A:::::A A:::::A I::::::I I::::::I II:::::::::II TT:::::::::::::::T \n");
|
||||
KPrintf("A:::::A A:::::A iiii I::::::I I::::::I II:::::::::::::II T:::::TTTTTT::::::T \n");
|
||||
KPrintf("A::::::A A::::::A i::::i II:::::I I:::::III:::::::III:::::::IT:::::T TTTTTTT\n");
|
||||
KPrintf("AAA:::::A A:::::AAA iiii I:::::I I:::::I I::::::I I::::::IT:::::T \n");
|
||||
KPrintf(" A:::::A A:::::A I:::::I I:::::I I:::::I I:::::IT:::::T \n");
|
||||
KPrintf(" A:::::A:::::A iiiiiii I:::::I I:::::I I:::::I I:::::I T::::TTTT \n");
|
||||
KPrintf(" A:::::::::A i:::::i I:::::I I:::::I I:::::I I:::::I TT::::::TTTTT \n");
|
||||
KPrintf(" A:::::::::A i::::i I:::::I I:::::I I:::::I I:::::I TTT::::::::TT \n");
|
||||
KPrintf(" A:::::A:::::A i::::i I:::::I I:::::I I:::::I I:::::I TTTTTT::::T \n");
|
||||
KPrintf(" A:::::A A:::::A i::::i I:::::I I:::::I I:::::I I:::::I T:::::T\n");
|
||||
KPrintf("AAA:::::A A:::::AAA i::::i I::::::I I::::::I I::::::I I::::::I T:::::T\n");
|
||||
KPrintf("A::::::A A::::::A i::::i I:::::::III:::::::I I:::::::III:::::::ITTTTTTT T:::::T\n");
|
||||
KPrintf("A:::::A A:::::A i::::i II:::::::::::::II II:::::::::::::II T::::::TTTTTT:::::T \n");
|
||||
KPrintf("A:::::A A:::::A i::::::i II:::::::::II II:::::::::II T:::::::::::::::TT \n");
|
||||
KPrintf("AAAAAAA AAAAAAA iiiiiiii IIIIIIIII IIIIIIIII TTTTTTTTTTTTTTT \n");
|
||||
KPrintf("*********************************************************************************************\n");
|
||||
KPrintf("*********************-----X Industrial Ubiquitous Operating System-----**********************\n");
|
||||
KPrintf("***************************2021 Copyright AIIT Ubiquitous-OS Team****************************\n");
|
||||
KPrintf("*********************************************************************************************\n");
|
||||
}
|
||||
66
kernel/thread/bitmap.c
Normal file
66
kernel/thread/bitmap.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: bitmap.c
|
||||
* @brief: calculate the highest priority
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_assign.h>
|
||||
|
||||
const uint8 LeaderZeroCount[] =
|
||||
{
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
int PrioCaculate(uint32 bitmap)
|
||||
{
|
||||
if (bitmap & 0xff000000)
|
||||
{
|
||||
return 31 - LeaderZeroCount[(bitmap & 0xff000000) >> 24];
|
||||
}
|
||||
else if (bitmap & 0xff0000)
|
||||
{
|
||||
return 23 - LeaderZeroCount[(bitmap & 0xff0000) >> 16];
|
||||
}
|
||||
else if (bitmap & 0xff00)
|
||||
{
|
||||
return 15 - LeaderZeroCount[(bitmap & 0xff00) >> 8];
|
||||
}
|
||||
else if (bitmap & 0xff)
|
||||
{
|
||||
return 7 - LeaderZeroCount[bitmap & 0xff];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
279
kernel/thread/circular_area.c
Normal file
279
kernel/thread/circular_area.c
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: circular_area.c
|
||||
* @brief: circular area file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xs_circular_area.h"
|
||||
#include <string.h>
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_memory.h>
|
||||
|
||||
/**
|
||||
* This function will return whether the circular_area is full or not
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
*/
|
||||
x_bool CircularAreaIsFull(CircularAreaType circular_area)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
|
||||
if((circular_area->readidx == circular_area->writeidx) && (circular_area->b_status)) {
|
||||
KPrintf("the circular area is full\n");
|
||||
return RET_TRUE;
|
||||
} else {
|
||||
return RET_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether the circular_area is empty or not
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
*/
|
||||
x_bool CircularAreaIsEmpty(CircularAreaType circular_area)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
|
||||
if((circular_area->readidx == circular_area->writeidx) && (!circular_area->b_status)) {
|
||||
KPrintf("the circular area is empty\n");
|
||||
return RET_TRUE;
|
||||
} else {
|
||||
return RET_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will reset the circular_area and set the descriptor to default
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
*/
|
||||
void CircularAreaReset(CircularAreaType circular_area)
|
||||
{
|
||||
circular_area->writeidx = 0;
|
||||
circular_area->readidx = 0;
|
||||
circular_area->b_status = RET_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will release the circular_area descriptor and free the memory
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
*/
|
||||
void CircularAreaRelease(CircularAreaType circular_area)
|
||||
{
|
||||
circular_area->readidx = 0;
|
||||
circular_area->writeidx = 0;
|
||||
circular_area->p_head = NONE;
|
||||
circular_area->p_tail = NONE;
|
||||
circular_area->b_status = RET_FALSE;
|
||||
circular_area->area_length = 0;
|
||||
|
||||
x_free(circular_area->data_buffer);
|
||||
x_free(circular_area);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the circual_area max length
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
*/
|
||||
uint32 CircularAreaGetMaxLength(CircularAreaType circular_area)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
|
||||
return circular_area->area_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the data length of the circular_area
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
*/
|
||||
uint32 CircularAreaGetDataLength(CircularAreaType circular_area)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
|
||||
if(CircularAreaIsFull(circular_area)) {
|
||||
return circular_area->area_length;
|
||||
} else {
|
||||
return (circular_area->writeidx - circular_area->readidx + circular_area->area_length) % circular_area->area_length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether it is need to divide the read data into two parts or not
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
* @param data_length output data length
|
||||
*/
|
||||
static uint32 CircularAreaDivideRdData(CircularAreaType circular_area, uint32 data_length)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
|
||||
if(circular_area->readidx + data_length <= circular_area->area_length) {
|
||||
return RET_FALSE;
|
||||
} else {
|
||||
return RET_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether it is need to divide the write data into two parts or not
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
* @param data_length input data length
|
||||
*/
|
||||
static uint32 CircularAreaDivideWrData(CircularAreaType circular_area, uint32 data_length)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
|
||||
if(circular_area->writeidx + data_length <= circular_area->area_length) {
|
||||
return RET_FALSE;
|
||||
} else {
|
||||
return RET_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will read data from the circular_area
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
* @param output_buffer output data buffer poniter
|
||||
* @param data_length output data length
|
||||
*/
|
||||
uint32 CircularAreaRead(CircularAreaType circular_area, uint8 *output_buffer, uint32 data_length)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
NULL_PARAM_CHECK(output_buffer);
|
||||
CHECK(data_length > 0);
|
||||
|
||||
if(CircularAreaIsEmpty(circular_area)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
data_length = (data_length > CircularAreaGetDataLength(circular_area)) ? CircularAreaGetDataLength(circular_area) : data_length;
|
||||
|
||||
if(CircularAreaDivideRdData(circular_area, data_length)) {
|
||||
uint32 read_len_up = circular_area->area_length - circular_area->readidx;
|
||||
uint32 read_len_down = data_length - read_len_up;
|
||||
|
||||
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_len_up);
|
||||
memcpy(output_buffer + read_len_up, circular_area->p_head, read_len_down);
|
||||
|
||||
circular_area->readidx = read_len_down;
|
||||
} else {
|
||||
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], data_length);
|
||||
circular_area->readidx = (circular_area->readidx + data_length) % circular_area->area_length;
|
||||
}
|
||||
|
||||
circular_area->b_status = RET_FALSE;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will write data to the circular_area
|
||||
*
|
||||
* @param circular_area CircularArea descriptor
|
||||
* @param input_buffer input data buffer poniter
|
||||
* @param data_length input data length
|
||||
* @param b_force whether to force to write data disregard the length limit
|
||||
*/
|
||||
uint32 CircularAreaWrite(CircularAreaType circular_area, uint8 *input_buffer, uint32 data_length, x_bool b_force)
|
||||
{
|
||||
NULL_PARAM_CHECK(circular_area);
|
||||
NULL_PARAM_CHECK(input_buffer);
|
||||
CHECK(data_length > 0);
|
||||
|
||||
if(CircularAreaIsFull(circular_area) && (!b_force)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
uint32 write_data_length = circular_area->area_length - CircularAreaGetDataLength(circular_area);
|
||||
data_length = (data_length > write_data_length) ? write_data_length : data_length;
|
||||
|
||||
if(CircularAreaDivideWrData(circular_area, data_length)) {
|
||||
uint32 write_len_up = circular_area->area_length - circular_area->writeidx;
|
||||
uint32 write_len_down = data_length - write_len_up;
|
||||
|
||||
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, write_len_up);
|
||||
memcpy(circular_area->p_head, input_buffer + write_len_up, write_len_down);
|
||||
|
||||
circular_area->writeidx = write_len_down;
|
||||
} else {
|
||||
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, data_length);
|
||||
circular_area->writeidx = (circular_area->writeidx + data_length) % circular_area->area_length;
|
||||
}
|
||||
|
||||
circular_area->b_status = RET_TRUE;
|
||||
|
||||
if(b_force) {
|
||||
circular_area->readidx = circular_area->writeidx;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static struct CircularAreaOps CircularAreaOperations =
|
||||
{
|
||||
CircularAreaRead,
|
||||
CircularAreaWrite,
|
||||
CircularAreaRelease,
|
||||
CircularAreaReset,
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will initialize the circular_area
|
||||
*
|
||||
* @param circular_area_length circular_area length
|
||||
*/
|
||||
CircularAreaType CircularAreaInit(uint32 circular_area_length)
|
||||
{
|
||||
CHECK(circular_area_length > 0);
|
||||
|
||||
circular_area_length = ALIGN_MEN_DOWN(circular_area_length, MEM_ALIGN_SIZE);
|
||||
|
||||
CircularAreaType circular_area = x_malloc(sizeof(struct CircularArea));
|
||||
if(NONE == circular_area) {
|
||||
KPrintf("CircularAreaInit malloc struct circular_area failed\n");
|
||||
x_free(circular_area);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
CircularAreaReset(circular_area);
|
||||
|
||||
circular_area->data_buffer = x_malloc(circular_area_length);
|
||||
if(NONE == circular_area->data_buffer) {
|
||||
KPrintf("CircularAreaInit malloc circular_area data_buffer failed\n");
|
||||
x_free(circular_area->data_buffer);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
circular_area->p_head = circular_area->data_buffer;
|
||||
circular_area->p_tail = circular_area->data_buffer + circular_area_length;
|
||||
circular_area->area_length = circular_area_length;
|
||||
|
||||
KPrintf("CircularAreaInit done p_head %8p p_tail %8p length %u\n",
|
||||
circular_area->p_head, circular_area->p_tail, circular_area->area_length);
|
||||
|
||||
circular_area->CircularAreaOperations = &CircularAreaOperations;
|
||||
|
||||
return circular_area;
|
||||
}
|
||||
685
kernel/thread/console.c
Normal file
685
kernel/thread/console.c
Normal file
@@ -0,0 +1,685 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: console.c
|
||||
* @brief: console file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
|
||||
#if defined(KERNEL_CONSOLE)
|
||||
static HardwareDevType _console = NONE;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Obtain the console
|
||||
*
|
||||
*/
|
||||
HardwareDevType ObtainConsole(void)
|
||||
{
|
||||
#if defined(KERNEL_CONSOLE)
|
||||
return _console;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a console
|
||||
*
|
||||
*
|
||||
* @param name console device name
|
||||
*
|
||||
*/
|
||||
HardwareDevType InstallConsole(const char *bus_name, const char *drv_name, const char *dev_name)
|
||||
{
|
||||
#if defined(KERNEL_CONSOLE)
|
||||
BusType console_bus;
|
||||
DriverType console_drv = NONE;
|
||||
HardwareDevType console = NONE;
|
||||
struct SerialDevParam *serial_dev_param = NONE;
|
||||
struct SerialCfgParam serial_cfg;
|
||||
struct BusConfigureInfo configure_info;
|
||||
|
||||
NULL_PARAM_CHECK(bus_name);
|
||||
NULL_PARAM_CHECK(drv_name);
|
||||
NULL_PARAM_CHECK(dev_name);
|
||||
|
||||
console_bus = BusFind(bus_name);
|
||||
console_drv = BusFindDriver(console_bus, drv_name);
|
||||
console = BusFindDevice(console_bus, dev_name);
|
||||
|
||||
if (console != NONE) {
|
||||
if (_console != NONE) {
|
||||
BusDevClose(_console);
|
||||
}
|
||||
|
||||
configure_info.configure_cmd = OPE_INT;
|
||||
memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
|
||||
configure_info.private_data = &serial_cfg;
|
||||
BusDrvConfigure(console_drv, &configure_info);
|
||||
console_bus->match(console_drv, console);
|
||||
|
||||
serial_dev_param = (struct SerialDevParam *)console->private_data;
|
||||
serial_dev_param->serial_set_mode = 0;
|
||||
serial_dev_param->serial_stream_mode = SIGN_OPER_STREAM;
|
||||
BusDevOpen(console);
|
||||
_console = console;
|
||||
} else {
|
||||
console = _console;
|
||||
}
|
||||
|
||||
return console;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(KERNEL_CONSOLE)
|
||||
|
||||
static __inline x_bool IsDigit(char c)
|
||||
{
|
||||
return ((unsigned)((c) - '0') < 10);
|
||||
}
|
||||
|
||||
static __inline unsigned int CharToNum(const char **s)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
while (IsDigit(**s)) {
|
||||
i = i * 10 + **s - '0';
|
||||
++ *s;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#define ZEROPAD (1 << 0)
|
||||
#define LEFT (1 << 1)
|
||||
#define SIGN (1 << 2)
|
||||
#define SPACE (1 << 3)
|
||||
#define HASH (1 << 4)
|
||||
|
||||
#define PRINTLONG (1 << 5)
|
||||
#define PRINTLONGLONG (1 << 6)
|
||||
#define PRINTSHORT (1 << 7)
|
||||
#define PRINTCHAR (1 << 8)
|
||||
|
||||
#define CAPITAL (1 << 9)
|
||||
|
||||
static size_t LongToChar(char* str, unsigned long value, uint32 flags, int32 precision, uint8 base, int32 width, x_bool minus, int32 pointer, int32 size)
|
||||
{
|
||||
char buff[KERNEL_CONSOLEBUF_SIZE/4] = {0};
|
||||
int32 length = 0;
|
||||
|
||||
if(!value)
|
||||
flags &= ~HASH;
|
||||
|
||||
if(!(precision > 0) || value) {
|
||||
do {
|
||||
const char number = (char)(value % base);
|
||||
if(number < 10) {
|
||||
buff[length] = number + '0';
|
||||
} else {
|
||||
if(flags & CAPITAL)
|
||||
buff[length] = 'A' + number - 10;
|
||||
else
|
||||
buff[length] = 'a' + number - 10;
|
||||
}
|
||||
++ length;
|
||||
value /= base;
|
||||
} while (value && (length < KERNEL_CONSOLEBUF_SIZE/4));
|
||||
}
|
||||
|
||||
if(!(flags & LEFT)) {
|
||||
if(width && (minus || (flags & (SIGN | SPACE | ZEROPAD))))
|
||||
-- width;
|
||||
while((length < precision) && (length < KERNEL_CONSOLEBUF_SIZE/4))
|
||||
buff[length++] = '0';
|
||||
while((length < width) && (flags & ZEROPAD) && (length < KERNEL_CONSOLEBUF_SIZE/4))
|
||||
buff[length++] = '0';
|
||||
}
|
||||
|
||||
if((flags & HASH) && ((base == 8) || (base == 16))) {
|
||||
if(!(precision > 0) && length && ((length == precision) || (length == width))) {
|
||||
-- length;
|
||||
if(length && (base == 16))
|
||||
-- length;
|
||||
}
|
||||
switch (base) {
|
||||
case 8:
|
||||
buff[length++] = '0';
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if(flags & CAPITAL)
|
||||
{
|
||||
buff[length++] = 'X';
|
||||
buff[length++] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
buff[length++] = 'x';
|
||||
buff[length++] = '0';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(length < KERNEL_CONSOLEBUF_SIZE/4) {
|
||||
if(minus)
|
||||
buff[length++] = '-';
|
||||
else if(flags & SIGN)
|
||||
buff[length++] = '+';
|
||||
else if(flags & SPACE)
|
||||
buff[length++] = ' ';
|
||||
}
|
||||
|
||||
const int32 index = pointer;
|
||||
|
||||
if(!(flags & LEFT) && !(flags & ZEROPAD) && (length < width)) {
|
||||
for(int32 i = length; i < width; i++) {
|
||||
str[pointer++] = ' ';
|
||||
if(pointer >= size) {
|
||||
str[size - 1] = '\0';
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (length) {
|
||||
str[pointer++] = buff[--length];
|
||||
if(pointer >= size) {
|
||||
str[size - 1] = '\0';
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
if(flags & LEFT) {
|
||||
while (pointer - index < width) {
|
||||
str[pointer++] = ' ';
|
||||
if(pointer >= size) {
|
||||
str[size - 1] = '\0';
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
static size_t LonglongToChar(char* str, unsigned long long value, uint32 flags, int32 precision, uint8 base, int32 width, x_bool minus, int32 pointer, int32 size)
|
||||
{
|
||||
char buff[KERNEL_CONSOLEBUF_SIZE/4] = {0};
|
||||
int32 length = 0;
|
||||
|
||||
if(!value)
|
||||
flags &= ~HASH;
|
||||
|
||||
if(!(precision > 0) || value){
|
||||
do {
|
||||
const char number = (char)(value % base);
|
||||
if(number < 10) {
|
||||
buff[length] = number + '0';
|
||||
} else {
|
||||
if(flags & CAPITAL)
|
||||
buff[length] = 'A' + number - 10;
|
||||
else
|
||||
buff[length] = 'a' + number - 10;
|
||||
}
|
||||
++ length;
|
||||
value /= base;
|
||||
} while (value && (length < KERNEL_CONSOLEBUF_SIZE/4));
|
||||
}
|
||||
|
||||
if(!(flags & LEFT)) {
|
||||
if(width && (minus || (flags & (SIGN | SPACE | ZEROPAD))))
|
||||
-- width;
|
||||
while((length < precision) && (length < KERNEL_CONSOLEBUF_SIZE/4))
|
||||
buff[length++] = '0';
|
||||
while((length < width) && (flags & ZEROPAD) && (length < KERNEL_CONSOLEBUF_SIZE/4))
|
||||
buff[length++] = '0';
|
||||
}
|
||||
|
||||
if((flags & HASH) && ((base == 8) || (base == 16))) {
|
||||
if(!(precision > 0) && length && ((length == precision) || (length == width))) {
|
||||
-- length;
|
||||
if(length && (base == 16))
|
||||
-- length;
|
||||
}
|
||||
switch (base) {
|
||||
case 8:
|
||||
buff[length++] = '0';
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if(flags & CAPITAL) {
|
||||
buff[length++] = 'X';
|
||||
buff[length++] = '0';
|
||||
} else {
|
||||
buff[length++] = 'x';
|
||||
buff[length++] = '0';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(length < KERNEL_CONSOLEBUF_SIZE/4) {
|
||||
if(minus)
|
||||
buff[length++] = '-';
|
||||
else if(flags & SIGN)
|
||||
buff[length++] = '+';
|
||||
else if(flags & SPACE)
|
||||
buff[length++] = ' ';
|
||||
}
|
||||
|
||||
const int32 index = pointer;
|
||||
|
||||
if(!(flags & LEFT) && !(flags & ZEROPAD) && (length < width)) {
|
||||
for(int32 i = length; i < width; i++) {
|
||||
str[pointer++] = ' ';
|
||||
if(pointer >= size) {
|
||||
str[size - 1] = '\0';
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (length) {
|
||||
str[pointer++] = buff[--length];
|
||||
if(pointer >= size) {
|
||||
str[size - 1] = '\0';
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
if(flags & LEFT) {
|
||||
while (pointer - index < width) {
|
||||
str[pointer++] = ' ';
|
||||
if(pointer >= size) {
|
||||
str[size - 1] = '\0';
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
int VsnPrintf(char *buf, int32 size, const char *fmt, va_list args)
|
||||
{
|
||||
NULL_PARAM_CHECK(buf);
|
||||
|
||||
int32 pointer = 0;
|
||||
int32 len = 0;
|
||||
int32 i = 0;
|
||||
int32 width = 0;
|
||||
int32 precision = 0;
|
||||
uint32 flags = 0;
|
||||
uint8 base = 0;
|
||||
char c = 0;
|
||||
char *str = NONE;
|
||||
char *s = NONE;
|
||||
|
||||
pointer = 0;
|
||||
str = buf;
|
||||
|
||||
while(*fmt) {
|
||||
if (*fmt != '%') {
|
||||
buf[pointer++] = *fmt;
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
++ fmt;
|
||||
continue;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
uint8 CheckFlags = 1;
|
||||
|
||||
while (CheckFlags) {
|
||||
++ fmt;
|
||||
switch (*fmt) {
|
||||
case '0':
|
||||
flags |= ZEROPAD;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
flags |= LEFT;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
flags |= SIGN;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
flags |= SPACE;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
flags |= HASH;
|
||||
break;
|
||||
|
||||
default:
|
||||
CheckFlags = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
width = -1;
|
||||
if (IsDigit(*fmt))
|
||||
width = CharToNum(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
width = va_arg(args, int);
|
||||
if (width < 0) {
|
||||
width = -width;
|
||||
flags |= LEFT;
|
||||
}
|
||||
++ fmt;
|
||||
}
|
||||
|
||||
precision = -1;
|
||||
if (*fmt == '.') {
|
||||
++ fmt;
|
||||
if (IsDigit(*fmt))
|
||||
precision = CharToNum(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
precision = va_arg(args, int);
|
||||
++ fmt;
|
||||
}
|
||||
if (precision < 0)
|
||||
precision = 0;
|
||||
}
|
||||
|
||||
if (*fmt == 'l') {
|
||||
++ fmt;
|
||||
if (*fmt == 'l') {
|
||||
flags |= PRINTLONGLONG;
|
||||
++ fmt;
|
||||
}
|
||||
else
|
||||
flags |= PRINTLONG;
|
||||
}
|
||||
else if(*fmt == 'h') {
|
||||
++ fmt;
|
||||
if (*fmt == 'h') {
|
||||
flags |= PRINTCHAR;
|
||||
++ fmt;
|
||||
}
|
||||
else
|
||||
flags |= PRINTSHORT;
|
||||
}
|
||||
|
||||
base = 10;
|
||||
|
||||
switch (*fmt) {
|
||||
case 'c':
|
||||
if (!(flags & LEFT)) {
|
||||
while (--width > 0) {
|
||||
buf[pointer++] = ' ';
|
||||
if(pointer >= size)
|
||||
{
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c = (char)va_arg(args, int);
|
||||
buf[pointer++] = c;
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
while (--width > 0) {
|
||||
buf[pointer++] = ' ';
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
s = "(NULL)";
|
||||
|
||||
len = strlen(s);
|
||||
if (precision > 0 && len > precision)
|
||||
len = precision;
|
||||
|
||||
if (!(flags & LEFT)) {
|
||||
while (len < width--) {
|
||||
buf[pointer++] = ' ';
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len; ++ i) {
|
||||
buf[pointer++] = *s;
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
++ s;
|
||||
}
|
||||
|
||||
while (len < width--) {
|
||||
buf[pointer++] = ' ';
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
width = sizeof(void *) * 2;
|
||||
flags |= ZEROPAD | CAPITAL;
|
||||
/* Determine the machine word length */
|
||||
if(sizeof(long) == sizeof(long long))
|
||||
pointer = LonglongToChar(buf, (unsigned long long)va_arg(args, void*), flags, precision, 16, width, 0, pointer, size);
|
||||
else
|
||||
pointer = LongToChar(buf, (unsigned long)va_arg(args, void*), flags, precision, 16, width, 0, pointer, size);
|
||||
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '%':
|
||||
buf[pointer] = '%';
|
||||
++ pointer;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
flags &= ~SIGN;
|
||||
base = 8;
|
||||
if(flags & PRINTLONGLONG)
|
||||
pointer = LonglongToChar(buf, va_arg(args, unsigned long long), flags, precision, base, width, 0, pointer, size);
|
||||
else if(flags & PRINTLONG)
|
||||
pointer = LongToChar(buf, va_arg(args, unsigned long), flags, precision, base, width, 0, pointer, size);
|
||||
else {
|
||||
if(flags & PRINTSHORT) {
|
||||
const unsigned int value = (unsigned short int)va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
} else if(flags & PRINTCHAR) {
|
||||
const unsigned int value = (unsigned char)va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
} else {
|
||||
const unsigned int value = va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
}
|
||||
}
|
||||
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
flags |= CAPITAL;
|
||||
case 'x':
|
||||
flags &= ~SIGN;
|
||||
base = 16;
|
||||
|
||||
if(flags & PRINTLONGLONG)
|
||||
pointer = LonglongToChar(buf, va_arg(args, unsigned long long), flags, precision, base, width, 0, pointer, size);
|
||||
else if(flags & PRINTLONG)
|
||||
pointer = LongToChar(buf, va_arg(args, unsigned long), flags, precision, base, width, 0, pointer, size);
|
||||
else {
|
||||
if(flags & PRINTSHORT) {
|
||||
const unsigned int value = (unsigned short int)va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
} else if(flags & PRINTCHAR) {
|
||||
const unsigned int value = (unsigned char)va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
} else {
|
||||
const unsigned int value = va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
}
|
||||
}
|
||||
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
flags &= ~SIGN;
|
||||
base = 10;
|
||||
flags &= ~HASH;
|
||||
if(flags & PRINTLONGLONG)
|
||||
pointer = LonglongToChar(buf, va_arg(args, unsigned long long), flags, precision, base, width, 0, pointer, size);
|
||||
else if(flags & PRINTLONG)
|
||||
pointer = LongToChar(buf, va_arg(args, unsigned long), flags, precision, base, width, 0, pointer, size);
|
||||
else {
|
||||
if(flags & PRINTSHORT) {
|
||||
const unsigned int value = (unsigned short int)va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
} else if(flags & PRINTCHAR) {
|
||||
const unsigned int value = (unsigned char)va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
} else {
|
||||
const unsigned int value = va_arg(args, unsigned int);
|
||||
pointer = LongToChar(buf, value, flags, precision, base, width, 0, pointer, size);
|
||||
}
|
||||
}
|
||||
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
base = 10;
|
||||
flags &= ~HASH;
|
||||
if(flags & PRINTLONGLONG) {
|
||||
const long long value = va_arg(args, long long);
|
||||
pointer = LonglongToChar(buf, (unsigned long long)(value > 0 ? value : 0 - value), flags, precision, base, width, (value < 0 ? 1 : 0), pointer, size);
|
||||
} else if(flags & PRINTLONG) {
|
||||
const long value = va_arg(args, long);
|
||||
pointer = LongToChar(buf, (unsigned long)(value > 0 ? value : 0 - value), flags, precision, base, width, (value < 0 ? 1 : 0), pointer, size);
|
||||
} else {
|
||||
if(flags & PRINTSHORT) {
|
||||
const int value = (short int)va_arg(args, int);
|
||||
pointer = LongToChar(buf, (unsigned int)(value > 0 ? value : 0 - value), flags, precision, base, width, (value < 0 ? 1 : 0), pointer, size);
|
||||
} else if(flags & PRINTCHAR) {
|
||||
const int value = (char)va_arg(args, int);
|
||||
pointer = LongToChar(buf, (unsigned int)(value > 0 ? value : 0 - value), flags, precision, base, width, (value < 0 ? 1 : 0), pointer, size);
|
||||
} else {
|
||||
const int value = va_arg(args, int);
|
||||
pointer = LongToChar(buf, (unsigned int)(value > 0 ? value : 0 - value), flags, precision, base, width, (value < 0 ? 1 : 0), pointer, size);
|
||||
}
|
||||
}
|
||||
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
buf[pointer++] = '%';
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
if (*fmt) {
|
||||
buf[pointer++] = *fmt;
|
||||
if(pointer >= size) {
|
||||
buf[size - 1] = '\0';
|
||||
return size - 1;
|
||||
}
|
||||
} else {
|
||||
-- fmt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
++ fmt;
|
||||
}
|
||||
|
||||
if(pointer > size)
|
||||
pointer = size - 1;
|
||||
buf[pointer] = '\0';
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void KPrintf(const char *fmt, ...)
|
||||
{
|
||||
#ifdef KERNEL_CONSOLE
|
||||
if(_console != NONE) {
|
||||
va_list args;
|
||||
x_size_t length = 0;
|
||||
static char logbuf[KERNEL_CONSOLEBUF_SIZE] = {0};
|
||||
|
||||
va_start(args, fmt);
|
||||
|
||||
length = VsnPrintf(logbuf, sizeof(logbuf) - 1, fmt, args);
|
||||
if (length > KERNEL_CONSOLEBUF_SIZE - 1)
|
||||
length = KERNEL_CONSOLEBUF_SIZE - 1;
|
||||
|
||||
struct BusBlockWriteParam write_param;
|
||||
write_param.pos = 0;
|
||||
write_param.buffer = (void *)logbuf;
|
||||
write_param.size = length;
|
||||
BusDevWriteData(_console, (void *)&write_param);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
233
kernel/thread/data_queue.c
Normal file
233
kernel/thread/data_queue.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: data_queue.c
|
||||
* @brief: data queue file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
|
||||
/**
|
||||
* This function allocates dynamic memory from dynamic buddy memory.
|
||||
*
|
||||
* @param p_queue dataqueue structure
|
||||
* @param NodeNumber the number of dataqueue
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
x_err_t InitDataqueue(DataQueueType *p_queue, uint16 NodeNumber)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(p_queue);
|
||||
|
||||
KPrintf("InitDataqueue\n");
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
do {
|
||||
memset(p_queue, 0, sizeof(DataQueueType));
|
||||
p_queue->front = p_queue->rear = 0;
|
||||
p_queue->max_len = NodeNumber;
|
||||
p_queue->base = (DataElemType *)x_malloc(p_queue->max_len * sizeof(DataElemType));
|
||||
if (!p_queue->base) {
|
||||
break;
|
||||
}
|
||||
|
||||
// The semaphore is initialized to len-1, because the full condition of the loop queue is real + 1 = = front,
|
||||
// a vacancy is always wasted
|
||||
p_queue->sem_blank = KSemaphoreCreate( p_queue->max_len - 1);
|
||||
if (!p_queue->sem_blank) {
|
||||
break;
|
||||
}
|
||||
|
||||
p_queue->sem_data = KSemaphoreCreate( 0);
|
||||
if (!p_queue->sem_data) {
|
||||
break;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
return EOK;
|
||||
} while (0);
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
DeInitDataqueue(p_queue);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function realses all dataqueue resource.
|
||||
*
|
||||
* @param p_queue dataqueue structure
|
||||
*
|
||||
*/
|
||||
|
||||
void DeInitDataqueue(DataQueueType *p_queue)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(p_queue);
|
||||
|
||||
KPrintf("DeInitDataqueue\n");
|
||||
|
||||
lock = DISABLE_INTERRUPT();
|
||||
|
||||
if (p_queue->base) {
|
||||
x_free(p_queue->base);
|
||||
p_queue->base = NONE;
|
||||
}
|
||||
|
||||
if (p_queue->sem_blank) {
|
||||
KSemaphoreDelete(p_queue->sem_blank);
|
||||
p_queue->sem_blank = NONE;
|
||||
}
|
||||
|
||||
if (p_queue->sem_data) {
|
||||
KSemaphoreDelete(p_queue->sem_data);
|
||||
p_queue->sem_data = NONE;
|
||||
}
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will push a data into dataqueue .
|
||||
*
|
||||
* @param p_queue dataqueue structure
|
||||
* @param StartAddr the data needed to be pushed
|
||||
* @param DataSize data size
|
||||
* @param timeout timeout
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
x_err_t PushDataqueue(DataQueueType *p_queue, const void *StartAddr, x_size_t DataSize, int32 timeout)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(p_queue);
|
||||
NULL_PARAM_CHECK(StartAddr);
|
||||
|
||||
KPrintf("PushDataqueue\n");
|
||||
|
||||
do {
|
||||
if (WAITING_FOREVER == timeout) {
|
||||
// block
|
||||
KSemaphoreObtain(p_queue->sem_blank, WAITING_FOREVER);
|
||||
break;
|
||||
} else if (0 == timeout) {
|
||||
// Nonblocking
|
||||
if (EOK == KSemaphoreObtain(p_queue->sem_blank, 0)) {
|
||||
break;
|
||||
} else {
|
||||
return -ERROR;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
if ((p_queue->rear + 1) % p_queue->max_len != p_queue->front) {
|
||||
DataElemType *pElem = &(p_queue->base[p_queue->rear]);
|
||||
pElem->data = StartAddr;
|
||||
pElem->length = DataSize;
|
||||
p_queue->rear = (p_queue->rear + 1) % p_queue->max_len;
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
KSemaphoreAbandon(p_queue->sem_data);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will pop a data from dataqueue .
|
||||
*
|
||||
* @param p_queue dataqueue structure
|
||||
* @param StartAddr the data needed to be popped
|
||||
* @param DataSize data size
|
||||
* @param timeout timeout
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
x_err_t PopDataqueue(DataQueueType *p_queue, const void **StartAddr, x_size_t *size, int32 timeout)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(p_queue);
|
||||
|
||||
KPrintf("PopDataqueue\n");
|
||||
|
||||
do {
|
||||
if (WAITING_FOREVER == timeout) {
|
||||
// block
|
||||
KSemaphoreObtain(p_queue->sem_data, WAITING_FOREVER);
|
||||
break;
|
||||
} else if (0 == timeout) {
|
||||
// Nonblocking
|
||||
if (EOK == KSemaphoreObtain(p_queue->sem_data, 0)) {
|
||||
// Get success
|
||||
break;
|
||||
} else {
|
||||
// Get failed, exit directly
|
||||
return -ERROR;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
// Semaphore surplus, read data directly
|
||||
if (p_queue->front != p_queue->rear) {
|
||||
DataElemType *pElem = &(p_queue->base[p_queue->front]);
|
||||
*StartAddr = pElem->data;
|
||||
*size = pElem->length;
|
||||
p_queue->front = (p_queue->front + 1) % p_queue->max_len;
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
// Release data semaphore
|
||||
KSemaphoreAbandon(p_queue->sem_blank);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the first data of dataqueue .
|
||||
*
|
||||
* @param p_queue dataqueue structure
|
||||
* @param StartAddr the data needed to be popped
|
||||
* @param size data size
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
x_err_t DataqueuePeak(DataQueueType *p_queue, const void **StartAddr, x_size_t *size)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(p_queue);
|
||||
|
||||
KPrintf("DataqueuePeak\n");
|
||||
|
||||
if (p_queue->front != p_queue->rear) {
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
DataElemType *pElem = &(p_queue->base[p_queue->front]);
|
||||
*StartAddr = pElem->data;
|
||||
*size = pElem->length;
|
||||
CriticalAreaUnLock(lock);
|
||||
return EOK;
|
||||
} else {
|
||||
return -ERROR;
|
||||
}
|
||||
}
|
||||
150
kernel/thread/delay.c
Normal file
150
kernel/thread/delay.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: delay.c
|
||||
* @brief: set task delay and check the timeout
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_klist.h>
|
||||
#include<string.h>
|
||||
#include<xs_isr.h>
|
||||
#include <xs_ktask.h>
|
||||
#include <xs_memory.h>
|
||||
#include<xs_ktick.h>
|
||||
#include<xiuos.h>
|
||||
|
||||
DoubleLinklistType xiaoshan_delay_head = {&xiaoshan_delay_head, &xiaoshan_delay_head};
|
||||
|
||||
/**
|
||||
* This function will delay a task with sone ticks.
|
||||
*
|
||||
* @param task the task needed to be delayed
|
||||
* @param ticks delay timeout
|
||||
*
|
||||
* @return EOK on success; ENOMEMORY on failure
|
||||
*/
|
||||
x_err_t KTaskSetDelay(KTaskDescriptorType task, x_ticks_t ticks)
|
||||
{
|
||||
x_base lock = 0;
|
||||
struct Delay *delay = NONE;
|
||||
struct Delay *dnode = NONE;
|
||||
DoubleLinklistType *nodelink = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
if (task->task_dync_sched_member.delay == NONE) {
|
||||
delay = (struct Delay *)x_malloc(sizeof(struct Delay));
|
||||
if (delay == NONE)
|
||||
{
|
||||
return -ENOMEMORY;
|
||||
}
|
||||
memset(delay, 0x0, sizeof(struct Delay));
|
||||
task->task_dync_sched_member.delay = delay;
|
||||
} else {
|
||||
delay = task->task_dync_sched_member.delay;
|
||||
lock = CriticalAreaLock();
|
||||
if(delay->status == TASK_DELAY_ACTIVE){
|
||||
delay->status = TASK_DELAY_INACTIVE;
|
||||
DoubleLinkListRmNode(&(delay->link));
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
}
|
||||
|
||||
delay->ticks = CurrentTicksGain() + ticks;
|
||||
delay->task = task;
|
||||
delay->status = TASK_DELAY_ACTIVE;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
DOUBLE_LINKLIST_FOR_EACH(nodelink, &xiaoshan_delay_head) {
|
||||
dnode =CONTAINER_OF(nodelink, struct Delay, link);
|
||||
if (delay->ticks < dnode->ticks) {
|
||||
DoubleLinkListInsertNodeBefore(nodelink, &delay->link);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodelink == &xiaoshan_delay_head) {
|
||||
DoubleLinkListInsertNodeBefore(&xiaoshan_delay_head, &(delay->link));
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will wakeup a task from delay list.
|
||||
*
|
||||
* @param task the task needed to be wakeup
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t KTaskUnSetDelay(KTaskDescriptorType task)
|
||||
{
|
||||
x_base lock = 0;
|
||||
struct Delay *delay = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
delay = task->task_dync_sched_member.delay;
|
||||
|
||||
if( delay != NONE && delay->status == TASK_DELAY_ACTIVE) {
|
||||
lock = CriticalAreaLock();
|
||||
delay->status = TASK_DELAY_INACTIVE;
|
||||
DoubleLinkListRmNode(&(delay->link));
|
||||
CriticalAreaUnLock(lock);
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
void CheckTaskDelay(void)
|
||||
{
|
||||
x_base level = 0;
|
||||
x_ticks_t current_tick = 0;
|
||||
struct Delay *node = NONE;
|
||||
|
||||
SYS_KDEBUG_LOG(0, ("delay check enter\n"));
|
||||
|
||||
current_tick = CurrentTicksGain();
|
||||
|
||||
level = CriticalAreaLock();
|
||||
|
||||
while (!IsDoubleLinkListEmpty(&xiaoshan_delay_head))
|
||||
{
|
||||
node = SYS_DOUBLE_LINKLIST_ENTRY(xiaoshan_delay_head.node_next,
|
||||
struct Delay, link);
|
||||
|
||||
if ((current_tick - node->ticks) < TICK_SIZE_MAX / 2)
|
||||
{
|
||||
current_tick = CurrentTicksGain();
|
||||
SYS_KDEBUG_LOG(KDBG_SOFTTIMER, ("current tick: %d\n", current_tick));
|
||||
KTaskUnSetDelay(node->task);
|
||||
CriticalAreaUnLock(level);
|
||||
KTaskTimeout(node->task);
|
||||
level = CriticalAreaLock();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
SYS_KDEBUG_LOG(0, ("delay check leave\n"));
|
||||
}
|
||||
132
kernel/thread/double_link.c
Normal file
132
kernel/thread/double_link.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: double_link.c
|
||||
* @brief: functions definition of double linklist
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <xs_klist.h>
|
||||
|
||||
/**
|
||||
* This function will init a linklist.
|
||||
*
|
||||
* @param linklist_head linklist node
|
||||
*/
|
||||
void InitDoubleLinkList(DoubleLinklistType *linklist_head)
|
||||
{
|
||||
linklist_head->node_next = linklist_head;
|
||||
linklist_head->node_prev = linklist_head;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will insert a node into list after the node.
|
||||
*
|
||||
* @param linklist linklist node
|
||||
* @param linklist_node the node needed to inserted
|
||||
*/
|
||||
void DoubleLinkListInsertNodeAfter(DoubleLinklistType *linklist, DoubleLinklistType *linklist_node)
|
||||
{
|
||||
linklist->node_next->node_prev = linklist_node;
|
||||
linklist_node->node_next = linklist->node_next;
|
||||
|
||||
linklist->node_next = linklist_node;
|
||||
linklist_node->node_prev = linklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will insert a node into list after the node.
|
||||
*
|
||||
* @param linklist linklist node
|
||||
* @param linklist_node the node needed to inserted
|
||||
*/
|
||||
void DoubleLinkListInsertNodeBefore(DoubleLinklistType *linklist, DoubleLinklistType *linklist_node)
|
||||
{
|
||||
linklist->node_prev->node_next = linklist_node;
|
||||
linklist_node->node_prev = linklist->node_prev;
|
||||
|
||||
linklist->node_prev = linklist_node;
|
||||
linklist_node->node_next = linklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will remove a node from the list.
|
||||
*
|
||||
* @param linklist_node the node needed to removed
|
||||
*/
|
||||
void DoubleLinkListRmNode(DoubleLinklistType *linklist_node)
|
||||
{
|
||||
linklist_node->node_next->node_prev = linklist_node->node_prev;
|
||||
linklist_node->node_prev->node_next = linklist_node->node_next;
|
||||
|
||||
linklist_node->node_next = linklist_node;
|
||||
linklist_node->node_prev = linklist_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will judge the list is empty.
|
||||
*
|
||||
* @param linklist the list head
|
||||
* @return true
|
||||
*/
|
||||
int IsDoubleLinkListEmpty(const DoubleLinklistType *linklist)
|
||||
{
|
||||
return linklist->node_next == linklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the head of the list.
|
||||
*
|
||||
* @param linklist list head
|
||||
* @return list head
|
||||
*/
|
||||
struct SysDoubleLinklistNode *DoubleLinkListGetHead(const DoubleLinklistType *linklist)
|
||||
{
|
||||
return IsDoubleLinkListEmpty(linklist) ? NONE : linklist->node_next;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the next node of the list head.
|
||||
*
|
||||
* @param linklist list head
|
||||
* @param linklist_node list head
|
||||
* @return next node of the list head
|
||||
*/
|
||||
struct SysDoubleLinklistNode *DoubleLinkListGetNext(const DoubleLinklistType *linklist,
|
||||
const struct SysDoubleLinklistNode *linklist_node)
|
||||
{
|
||||
return linklist_node->node_next == linklist ? NONE : linklist_node->node_next;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get length of the list.
|
||||
*
|
||||
* @param linklist list head
|
||||
* @return length
|
||||
*/
|
||||
unsigned int DoubleLinkListLenGet(const DoubleLinklistType *linklist)
|
||||
{
|
||||
unsigned int linklist_length = 0;
|
||||
const DoubleLinklistType *tmp_node = linklist;
|
||||
while (tmp_node->node_next != linklist)
|
||||
{
|
||||
tmp_node = tmp_node->node_next;
|
||||
linklist_length ++;
|
||||
}
|
||||
|
||||
return linklist_length;
|
||||
}
|
||||
302
kernel/thread/event.c
Normal file
302
kernel/thread/event.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: event.c
|
||||
* @brief: event file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
DECLARE_ID_MANAGER(k_event_id_manager, ID_NUM_MAX);
|
||||
DoubleLinklistType k_event_list ={&k_event_list, &k_event_list};
|
||||
|
||||
static int32 _EventCreate(uint32 options)
|
||||
{
|
||||
int32 id = 0;
|
||||
x_base lock = 0;
|
||||
struct Event *event = NONE;
|
||||
|
||||
event = (struct Event *)x_malloc(sizeof(struct Event));
|
||||
if (event == NONE)
|
||||
return -ENOMEMORY;
|
||||
|
||||
memset(event, 0, sizeof(struct Event));
|
||||
lock = CriticalAreaLock();
|
||||
id = IdInsertObj(&k_event_id_manager, &event->id);
|
||||
if (id < 0) {
|
||||
CriticalAreaUnLock(lock);
|
||||
x_free(event);
|
||||
return -ENOMEMORY;
|
||||
}
|
||||
|
||||
event->options = options;
|
||||
InitDoubleLinkList(&event->pend_list);
|
||||
|
||||
DoubleLinkListInsertNodeAfter(&k_event_list, &event->link);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static void _EventDelete(struct Event *event)
|
||||
{
|
||||
int resched = 0;
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(event);
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&event->pend_list)) {
|
||||
resched = 1;
|
||||
LinklistResumeAll(&event->pend_list);
|
||||
}
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
IdRemoveObj(&k_event_id_manager, event->id.id);
|
||||
|
||||
DoubleLinkListRmNode(&event->link);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
x_free(event);
|
||||
|
||||
if (resched)
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
|
||||
static int32 _EventTrigger(struct Event *event, uint32 events)
|
||||
{
|
||||
x_bool resched;
|
||||
x_ubase lock = 0;
|
||||
x_base status = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
struct SysDoubleLinklistNode *n = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(event);
|
||||
|
||||
if (events == 0)
|
||||
return -ERROR;
|
||||
|
||||
resched = RET_FALSE;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
event->events |= events;
|
||||
|
||||
if (IsDoubleLinkListEmpty(&event->pend_list)) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
n = event->pend_list.node_next;
|
||||
while (n != &(event->pend_list)) {
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(n, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
status = -ERROR;
|
||||
if (task->event_mode & EVENT_AND) {
|
||||
if ((task->event_id_trigger & (event->events & EVENT_EVENTS_MASK)) == task->event_id_trigger)
|
||||
status = EOK;
|
||||
} else if (task->event_mode & EVENT_OR) {
|
||||
if (task->event_id_trigger & (event->events & EVENT_EVENTS_MASK)) {
|
||||
task->event_id_trigger = task->event_id_trigger & (event->events & EVENT_EVENTS_MASK);
|
||||
status = EOK;
|
||||
}
|
||||
}
|
||||
|
||||
n = n->node_next;
|
||||
|
||||
if (status == EOK) {
|
||||
if (task->event_mode & EVENT_AUTOCLEAN)
|
||||
event->events &= ~task->event_id_trigger;
|
||||
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
resched = RET_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
if (resched == RET_TRUE)
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static int32 _EventProcess(struct Event *event, uint32 events, uint32 options, int32 msec, uint32 *processed)
|
||||
{
|
||||
|
||||
x_ubase lock = 0;
|
||||
x_base status = 0;
|
||||
int32 timeout = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
KDEBUG_IN_KTASK_CONTEXT;
|
||||
|
||||
NULL_PARAM_CHECK(event);
|
||||
|
||||
if (events == 0)
|
||||
return -ERROR;
|
||||
|
||||
status = -ERROR;
|
||||
task = GetKTaskDescriptor();
|
||||
task->exstatus = EOK;
|
||||
|
||||
timeout = CalculteTickFromTimeMs(msec);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
if (options & EVENT_AND) {
|
||||
if ((event->events & events) == events)
|
||||
status = EOK;
|
||||
} else if (options & EVENT_OR) {
|
||||
if (event->events & events)
|
||||
status = EOK;
|
||||
} else {
|
||||
CHECK(0);
|
||||
}
|
||||
|
||||
if (status == EOK) {
|
||||
if (processed)
|
||||
*processed = (event->events & events);
|
||||
|
||||
if (options & EVENT_AUTOCLEAN)
|
||||
event->events &= ~events;
|
||||
} else if (timeout == 0) {
|
||||
task->exstatus = -ETIMEOUT;
|
||||
} else {
|
||||
task->event_id_trigger = (events & EVENT_EVENTS_MASK);
|
||||
task->event_mode = (options & EVENT_OPTIONS_MASK);
|
||||
|
||||
LinklistSuspend(&(event->pend_list), task, event->options);
|
||||
|
||||
if (timeout > 0)
|
||||
KTaskSetDelay(task,timeout);
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
if (task->exstatus != EOK)
|
||||
return task->exstatus;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
if (processed)
|
||||
*processed = task->event_id_trigger;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return task->exstatus;
|
||||
}
|
||||
|
||||
static EventDoneType done = {
|
||||
.EventCreate = _EventCreate,
|
||||
.EventDelete = _EventDelete,
|
||||
.EventTrigger = _EventTrigger,
|
||||
.EventProcess = _EventProcess,
|
||||
};
|
||||
|
||||
static struct Event *FindEventById(int32 id)
|
||||
{
|
||||
x_base lock = 0;
|
||||
struct IdNode *idnode = NONE;
|
||||
struct Event *event = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return NONE;
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_event_id_manager, id);
|
||||
if (idnode == NONE) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
event = CONTAINER_OF(idnode, struct Event, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will create a event.
|
||||
*
|
||||
* @param options the trigger way of event.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
int32 KEventCreate(uint32 options)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
return done.EventCreate(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will delete a event.
|
||||
*
|
||||
* @param id the id number of event.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
void KEventDelete(int32 id)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
struct Event *event = FindEventById(id);
|
||||
|
||||
if (event == NONE)
|
||||
return;
|
||||
|
||||
done.EventDelete(event);
|
||||
}
|
||||
/**
|
||||
* This function will trigger the event
|
||||
*
|
||||
* @param id the id number of event
|
||||
* @param events trigger way & events flag
|
||||
*
|
||||
* @return EOK on success.
|
||||
*/
|
||||
int32 KEventTrigger(int32 id, uint32 events)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
struct Event *event = FindEventById(id);
|
||||
|
||||
if (event == NONE)
|
||||
return -ERROR;
|
||||
|
||||
return done.EventTrigger(event, events);
|
||||
}
|
||||
/**
|
||||
* This function will get the event and process this event
|
||||
*
|
||||
* @param id the id number of event
|
||||
* @param events events flag
|
||||
* @param options trigger way
|
||||
* @param msec timeout
|
||||
* @processed event processed flag
|
||||
*
|
||||
* @return EOK on success.
|
||||
*/
|
||||
int32 KEventProcess(int32 id, uint32 events, uint32 options, int32 msec, uint32 *processed)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
struct Event *event = FindEventById(id);
|
||||
|
||||
return done.EventProcess(event, events, options, msec, processed);
|
||||
}
|
||||
216
kernel/thread/hook.c
Normal file
216
kernel/thread/hook.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: hook.c
|
||||
* @brief: the general interface functions of hook
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/20
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_hook.h>
|
||||
|
||||
struct KernelHook hook;
|
||||
|
||||
/**
|
||||
* a hook function, it will run when switch task
|
||||
*
|
||||
* @param from task descriptor
|
||||
* @param to task descriptor
|
||||
*/
|
||||
void AssignHook(KTaskDescriptorType from, KTaskDescriptorType to)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], from task: %s, to task:%s\n",__func__,from->task_base_info.name,to->task_base_info.name));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This hook function will be run after task inited .
|
||||
*
|
||||
* @param task task descripter
|
||||
*
|
||||
* @note no blocked or suspend function.
|
||||
*/
|
||||
void TaskCreatehook(KTaskDescriptorType task)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Create task: %s\n",__func__,task->task_base_info.name));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This hook function will be run after task suspended .
|
||||
*
|
||||
* @param task descripter
|
||||
*
|
||||
* @note no blocked or suspend function.
|
||||
*/
|
||||
void TaskSuspendhook(KTaskDescriptorType task)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Suspend task: %s\n",__func__,task->task_base_info.name));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This hook function will be run after task resumed .
|
||||
*
|
||||
* @param task descripter
|
||||
*
|
||||
* @note no blocked or suspend function.
|
||||
*/
|
||||
void TaskResumehook(KTaskDescriptorType task)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Resume task: %s\n",__func__,task->task_base_info.name));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
/**
|
||||
* a MallocHook function. The MallocHook function will be run before a memory block is allocated from buddy-memory.
|
||||
*
|
||||
* @param ptr alloc mem point
|
||||
* @param size alloc mem size
|
||||
*/
|
||||
void MemMallochook(void *ptr, x_size_t size)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Malloc memory: ptr:%p, size: %d\n",__func__,ptr,size));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
/**
|
||||
* a FreeHook function. The FreeHook function will be run after a memory block is freed to buddy-memory.
|
||||
*
|
||||
* @param ptr free mem point
|
||||
*/
|
||||
void MemFreehook(void *ptr)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Free memory: ptr:%p\n",__func__,ptr));
|
||||
/* add your code */
|
||||
}
|
||||
#ifdef KERNEL_MEMBLOCK
|
||||
/**
|
||||
* a allocation hook function before a gatherblock allocation.
|
||||
*
|
||||
* @param gm the alloc hook function
|
||||
* @param date_ptr mem point
|
||||
*/
|
||||
void GmAllocHook(struct MemGather *gm, void *date_ptr)
|
||||
{
|
||||
/* add your code */
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* a free hook function after a gatherblock release.
|
||||
*
|
||||
* @param gm the free hook function
|
||||
* @param date_ptr mem point
|
||||
*/
|
||||
void GmFreeHook(struct MemGather *gm, void *date_ptr)
|
||||
{
|
||||
/* add your code */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* this hook function will run when the system interrupt
|
||||
*
|
||||
* @note no blocked or suspend.
|
||||
*/
|
||||
void IsrEnterHook(void)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Enter Isr\n",__func__));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
/**
|
||||
* this hook function will run when the system leave interrupt
|
||||
*
|
||||
* @note no blocked or suspend.
|
||||
*/
|
||||
void IsrLeaveHook(void)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Leave Isr\n",__func__));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
void TimerEnterHook(struct Timer *timer)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Timer Enter\n",__func__));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
void TimerExitHook(struct Timer *timer)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Timer Exit\n",__func__));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
void IdleTaskHook(void)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s], Idle0 \n",__func__));
|
||||
/* add your code */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void testhook(const char *str)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_HOOK,
|
||||
("HOOK: Function[%s],Test: %s\n",__func__,str));
|
||||
/* add your code */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int hook_init(void)
|
||||
{
|
||||
REGISTER_HOOK(hook.assign.hook_Assign,AssignHook);
|
||||
|
||||
REGISTER_HOOK(hook.task.hook_TaskCreate,TaskCreatehook);
|
||||
REGISTER_HOOK(hook.task.hook_TaskSuspend,TaskSuspendhook);
|
||||
REGISTER_HOOK(hook.task.hook_TaskResume,TaskResumehook);
|
||||
|
||||
REGISTER_HOOK(hook.mem.hook_Malloc,MemMallochook);
|
||||
REGISTER_HOOK(hook.mem.hook_Free,MemFreehook);
|
||||
|
||||
#ifdef KERNEL_MEMBLOCK
|
||||
REGISTER_HOOK(hook.mem.hook_GmAlloc,GmAllocHook);
|
||||
REGISTER_HOOK(hook.mem.hook_GmFree,GmFreeHook);
|
||||
#endif
|
||||
|
||||
REGISTER_HOOK(hook.timer.hook_TimerEnter,TimerEnterHook);
|
||||
REGISTER_HOOK(hook.timer.hook_TimerExit,TimerExitHook);
|
||||
|
||||
REGISTER_HOOK(hook.idle.hook_Idle,IdleTaskHook);
|
||||
//REGISTER_HOOK(hook.idle[1].hook_Idle,IdleTask1Hook);
|
||||
|
||||
REGISTER_HOOK(hook.isr.hook_IsrEnter,IsrEnterHook);
|
||||
REGISTER_HOOK(hook.isr.hook_IsrLeave,IsrLeaveHook);
|
||||
REGISTER_HOOK(hook.test.hook_test,testhook);
|
||||
return EOK;
|
||||
}
|
||||
142
kernel/thread/id.c
Normal file
142
kernel/thread/id.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: id.c
|
||||
* @brief: the management with id for all kernel object
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/4/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
static int AllocId(struct IdManager *manager)
|
||||
{
|
||||
int index = 0;
|
||||
int end = 0;
|
||||
int id = 0;
|
||||
uint8 entry = 0;
|
||||
|
||||
NULL_PARAM_CHECK(manager);
|
||||
|
||||
end = (manager->id_max + 7) / 8;
|
||||
|
||||
for (index = 0; index < end; index++)
|
||||
if (manager->id_map[index] != 0xff)
|
||||
break;
|
||||
if (index == end)
|
||||
return -1;
|
||||
|
||||
id = index * 8;
|
||||
entry = manager->id_map[index];
|
||||
while (entry & 0x1) {
|
||||
id++;
|
||||
entry >>= 1;
|
||||
}
|
||||
if (id >= manager->id_max)
|
||||
return -1;
|
||||
|
||||
manager->id_map[index] |= (0x1 << (id % 8));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static void FreeId(struct IdManager *manager, uint16 id)
|
||||
{
|
||||
NULL_PARAM_CHECK(manager);
|
||||
|
||||
manager->id_map[id / 8] &= ~(0x1 << (id % 8));
|
||||
}
|
||||
|
||||
static void InsertObj(struct IdManager *manager, struct IdNode *idnode)
|
||||
{
|
||||
NULL_PARAM_CHECK(manager);
|
||||
NULL_PARAM_CHECK(idnode);
|
||||
|
||||
DoubleLinklistType *head = &manager->htable[idnode->id % manager->hoffset];
|
||||
|
||||
if (head->node_prev == NONE)
|
||||
InitDoubleLinkList(head);
|
||||
|
||||
DoubleLinkListInsertNodeAfter(head, &idnode->link);
|
||||
}
|
||||
|
||||
static struct IdNode *GetObj(struct IdManager *manager, uint16 id)
|
||||
{
|
||||
NULL_PARAM_CHECK(manager);
|
||||
|
||||
DoubleLinklistType *head = &manager->htable[id % manager->hoffset];
|
||||
DoubleLinklistType *node = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (head->node_prev == NONE) {
|
||||
InitDoubleLinkList(head);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
DOUBLE_LINKLIST_FOR_EACH(node, head) {
|
||||
idnode =CONTAINER_OF(node, struct IdNode, link);
|
||||
if (idnode->id == id)
|
||||
break;
|
||||
idnode = NONE;
|
||||
}
|
||||
|
||||
return idnode;
|
||||
}
|
||||
|
||||
static struct IdNode *RemoveObj(struct IdManager *manager, struct IdNode *idnode)
|
||||
{
|
||||
NULL_PARAM_CHECK(manager);
|
||||
NULL_PARAM_CHECK(idnode);
|
||||
|
||||
DoubleLinkListRmNode(&idnode->link);
|
||||
}
|
||||
|
||||
int IdInsertObj(struct IdManager *manager, struct IdNode *idnode)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
NULL_PARAM_CHECK(manager);
|
||||
NULL_PARAM_CHECK(idnode);
|
||||
|
||||
if ((id = AllocId(manager)) < 0)
|
||||
return -1;
|
||||
|
||||
idnode->id = id;
|
||||
InsertObj(manager, idnode);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
struct IdNode *IdGetObj(struct IdManager *manager, uint16 id)
|
||||
{
|
||||
if (manager == NONE || id >= manager->id_max)
|
||||
return NONE;
|
||||
|
||||
return GetObj(manager, id);
|
||||
}
|
||||
|
||||
void IdRemoveObj(struct IdManager *manager, uint16 id)
|
||||
{
|
||||
NULL_PARAM_CHECK(manager);
|
||||
|
||||
struct IdNode *idnode = IdGetObj(manager, id);
|
||||
|
||||
if (idnode == NONE)
|
||||
return;
|
||||
|
||||
FreeId(manager, idnode->id);
|
||||
RemoveObj(manager, idnode);
|
||||
idnode->id = -1;
|
||||
}
|
||||
105
kernel/thread/idle.c
Normal file
105
kernel/thread/idle.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: idle.c
|
||||
* @brief: idle file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_hook.h>
|
||||
#include <xs_spinlock.h>
|
||||
|
||||
#if defined (KERNEL_HOOK)
|
||||
#ifndef KERNEL_IDLE_HOOK
|
||||
#define KERNEL_IDLE_HOOK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef IDLE_KTASK_STACKSIZE
|
||||
#define IDLE_KTASK_STACKSIZE 256
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
#define CORE_NUM CPU_NUMBERS
|
||||
#else
|
||||
#define CORE_NUM 1
|
||||
#endif
|
||||
|
||||
|
||||
static int32 idle[CORE_NUM];
|
||||
__attribute__((aligned(MEM_ALIGN_SIZE)))
|
||||
|
||||
void RunningIntoLowPowerMode()
|
||||
{
|
||||
#ifdef ARCH_ARM
|
||||
__asm volatile("WFI");
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_RISCV
|
||||
asm volatile ("wfi");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IdleKTaskEntry(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
#ifdef KERNEL_IDLE_HOOK
|
||||
HOOK(hook.idle.hook_Idle,());
|
||||
#endif
|
||||
RunningIntoLowPowerMode();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* init system idle task,then startup the idle task
|
||||
*
|
||||
*/
|
||||
void InitIdleKTask(void)
|
||||
{
|
||||
uint8 coreid = 0;
|
||||
char ktaskidle[NAME_NUM_MAX] = {0};
|
||||
|
||||
for (coreid = 0; coreid < CORE_NUM; coreid++) {
|
||||
sprintf(ktaskidle, "ktaskidle%d", coreid);
|
||||
|
||||
idle[coreid] = KTaskCreate(ktaskidle,IdleKTaskEntry,NONE,IDLE_KTASK_STACKSIZE,KTASK_LOWEST_PRIORITY);
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
KTaskCoreCombine(idle[coreid], coreid);
|
||||
#endif
|
||||
StartupKTask(idle[coreid]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This function will return the idle task descriptor
|
||||
*
|
||||
*/
|
||||
KTaskDescriptorType GetIdleKTaskDescripter(void)
|
||||
{
|
||||
KTaskDescriptorType idle_p = NONE;
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
register int id = GetCpuId();
|
||||
#else
|
||||
register int id = 0;
|
||||
#endif
|
||||
|
||||
idle_p = CONTAINER_OF(&idle[id], struct TaskDescriptor, id);
|
||||
return idle_p;
|
||||
}
|
||||
260
kernel/thread/init.c
Normal file
260
kernel/thread/init.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: init.c
|
||||
* @brief: init file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_init.h>
|
||||
#include <xs_spinlock.h>
|
||||
#include <xs_workqueue.h>
|
||||
#include <stdlib.h>
|
||||
#include <board.h>
|
||||
|
||||
#ifdef BSP_USING_USBH
|
||||
#include "connect_usb.h"
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_USER_MAIN
|
||||
#ifndef MAIN_KTASK_STACK_SIZE
|
||||
#define MAIN_KTASK_STACK_SIZE 2048
|
||||
#endif
|
||||
#ifndef MAIN_KTASK_PRIORITY
|
||||
#define MAIN_KTASK_PRIORITY (KTASK_PRIORITY_MAX / 3)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern void CreateKServiceKTask(void);
|
||||
extern int main(void);
|
||||
void InitBoardHardware(void);
|
||||
extern int hook_init(void);
|
||||
int cplusplus_system_init(void);
|
||||
|
||||
#ifdef KERNEL_COMPONENTS_INIT
|
||||
#ifdef USER_APPLICATION
|
||||
extern void CreateMainTask(void);
|
||||
#ifdef SEPARATE_COMPILE
|
||||
int InitUserspace(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENV_INIT_KTASK_STACK_SIZE
|
||||
#define ENV_INIT_KTASK_STACK_SIZE 8192
|
||||
#endif
|
||||
|
||||
struct InitSequenceDesc prev_cmpts_init[] =
|
||||
{
|
||||
#ifdef FS_VFS
|
||||
{ "vfs", VfsInit },
|
||||
#endif
|
||||
#ifdef LIB_CPLUSPLUS
|
||||
{ "cplusplus_system", cplusplus_system_init },
|
||||
#endif
|
||||
#ifdef KERNEL_HOOK
|
||||
{ "hook", hook_init },
|
||||
#endif
|
||||
{ " NONE ", NONE },
|
||||
};
|
||||
struct InitSequenceDesc device_init[] =
|
||||
{
|
||||
#ifdef KERNEL_WORKQUEUE
|
||||
{ "work sys workqueue", WorkSysWorkQueueInit },
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_ARM
|
||||
#ifdef RESOURCES_SPI_SFUD
|
||||
{ "W25Qxx_spi", FlashW25qxxSpiDeviceInit},
|
||||
#endif
|
||||
#endif
|
||||
{ " NONE ", NONE },
|
||||
};
|
||||
struct InitSequenceDesc components_init[] =
|
||||
{
|
||||
#ifdef CONNECTION_AT_SAL_USING_TLS
|
||||
{"sal_mbedtls_proto", sal_mbedtls_proto_init},
|
||||
#endif
|
||||
#ifdef FS_VFS_FATFS
|
||||
{ "fatfs", FatfsInit },
|
||||
#endif
|
||||
#ifdef FS_CH376
|
||||
{ "ch376", Ch376fsInit },
|
||||
#endif
|
||||
{ "libc_system", LibcSystemInit },
|
||||
#ifdef CONNECTION_AT_OS_USING_SAL
|
||||
// { "sal_init", sal_init },
|
||||
#endif
|
||||
#ifdef RTC_SYNC_USING_NTP
|
||||
{ "rtc_ntp_sync",RtcNtpSyncInit},
|
||||
#endif
|
||||
{ " NONE ", NONE },
|
||||
};
|
||||
struct InitSequenceDesc env_init[] =
|
||||
{
|
||||
#ifdef ARCH_RISCV
|
||||
#if defined (RESOURCES_SPI_SD)|| defined(RESOURCES_SDIO )
|
||||
{ "MountSDCard", MountSDCard },
|
||||
#endif
|
||||
#endif
|
||||
#ifdef FS_VFS_MNTTABLE
|
||||
{ "dfs_mount_table", dfs_mount_table },
|
||||
#endif
|
||||
#ifdef TOOL_SHELL
|
||||
{ "letter-shell system", userShellInit },
|
||||
#endif
|
||||
{ " NONE ", NONE },
|
||||
};
|
||||
struct InitSequenceDesc communication_init[] =
|
||||
{
|
||||
// #ifdef BSP_USING_SDIO
|
||||
// { "stm32_sdcard_mount",stm32_sdcard_mount },
|
||||
// #endif
|
||||
#ifdef BSP_USING_USBH
|
||||
{ "STM32USBHostRegister", STM32USBHostRegister },
|
||||
{ "hw usb", Stm32HwUsbInit },
|
||||
#endif
|
||||
{ " NONE ", NONE },
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will init sub components
|
||||
* @parm sub_components components type
|
||||
*
|
||||
*/
|
||||
void _InitSubCmpts(struct InitSequenceDesc sub_cmpts[])
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
for( i = 0; sub_cmpts[i].fn != NONE; i++ ) {
|
||||
ret = sub_cmpts[i].fn();
|
||||
KPrintf("initialize %s %s\n",sub_cmpts[i].fn_name, ret == 0 ? "success" : "failed");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KERNEL_COMPONENTS_INIT
|
||||
void EnvInitKTask(void *parameter)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
_InitSubCmpts(prev_cmpts_init);
|
||||
_InitSubCmpts(device_init);
|
||||
_InitSubCmpts(components_init);
|
||||
_InitSubCmpts(env_init);
|
||||
ENABLE_INTERRUPT(lock);
|
||||
|
||||
_InitSubCmpts(communication_init);
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
StartupSecondaryCpu();
|
||||
#endif
|
||||
|
||||
#ifdef USER_APPLICATION
|
||||
#ifdef SEPARATE_COMPILE
|
||||
if(InitUserspace() == EOK) {
|
||||
CreateMainTask();
|
||||
}
|
||||
#else
|
||||
CreateMainTask();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void CreateEnvInitTask(void)
|
||||
{
|
||||
int32 env_init = 0;
|
||||
|
||||
env_init = KTaskCreate("env_init", EnvInitKTask, NONE,
|
||||
ENV_INIT_KTASK_STACK_SIZE, KTASK_PRIORITY_MAX - 1);
|
||||
if(env_init < 0) {
|
||||
KPrintf("env_init create failed ...%s %d.\n",__FUNCTION__,__LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
StartupKTask(env_init);
|
||||
}
|
||||
#endif /* KERNEL_COMPONENTS_INIT */
|
||||
|
||||
|
||||
/**
|
||||
* kernel startup function
|
||||
*
|
||||
*
|
||||
*/
|
||||
int XiUOSStartup(void)
|
||||
{
|
||||
DISABLE_INTERRUPT();
|
||||
|
||||
#ifdef KERNEL_QUEUEMANAGE
|
||||
queuemanager_done_register();
|
||||
#endif
|
||||
|
||||
#ifdef KERNEL_BANNER
|
||||
ShowBanner();
|
||||
#endif
|
||||
|
||||
SysInitOsAssign();
|
||||
|
||||
CreateKServiceKTask();
|
||||
|
||||
#ifdef KERNEL_COMPONENTS_INIT
|
||||
CreateEnvInitTask();
|
||||
#else
|
||||
|
||||
#ifdef TOOL_SHELL
|
||||
extern int userShellInit(void);
|
||||
userShellInit();
|
||||
#endif
|
||||
|
||||
#ifdef USER_APPLICATION
|
||||
extern void CreateMainTask(void);
|
||||
#ifdef SEPARATE_COMPILE
|
||||
extern int InitUserspace(void);
|
||||
|
||||
if(InitUserspace() == EOK) {
|
||||
CreateMainTask();
|
||||
}
|
||||
#else
|
||||
CreateMainTask();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
HwLockSpinlock(&AssignSpinLock);
|
||||
#endif
|
||||
|
||||
StartupOsAssign();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* system entry */
|
||||
int entry(void)
|
||||
{
|
||||
DISABLE_INTERRUPT();
|
||||
|
||||
/* system irq table must be inited before initialization of Hardware irq */
|
||||
SysInitIsrManager();
|
||||
|
||||
InitBoardHardware();
|
||||
XiUOSStartup();
|
||||
return 0;
|
||||
}
|
||||
218
kernel/thread/isr.c
Normal file
218
kernel/thread/isr.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: isr.c
|
||||
* @brief: the general management of system isr
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_hook.h>
|
||||
|
||||
struct InterruptServiceRoutines isrManager = { 0} ;
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
extern int GetCpuId(void);
|
||||
#endif
|
||||
/**
|
||||
* This functionwill get the isr nest level.
|
||||
*
|
||||
* @return isr nest level
|
||||
*/
|
||||
uint16 GetIsrCounter()
|
||||
{
|
||||
uint16 ret = 0;
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
ret = isrManager.isr_count[GetCpuId()];
|
||||
#else
|
||||
ret = isrManager.isr_count;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
void incIsrCounter()
|
||||
{
|
||||
#ifdef ARCH_SMP
|
||||
isrManager.isr_count[GetCpuId()] ++ ;
|
||||
#else
|
||||
isrManager.isr_count ++;
|
||||
#endif
|
||||
return ;
|
||||
}
|
||||
|
||||
void decIsrCounter()
|
||||
{
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
isrManager.isr_count[GetCpuId()] -- ;
|
||||
#else
|
||||
isrManager.isr_count --;
|
||||
#endif
|
||||
return ;
|
||||
}
|
||||
|
||||
x_bool Is_InIsr()
|
||||
{
|
||||
#ifdef ARCH_SMP
|
||||
return ( isrManager.isr_count[GetCpuId()] != 0 ? RET_TRUE : RET_FALSE ) ;
|
||||
#else
|
||||
return ( isrManager.isr_count != 0 ? RET_TRUE : RET_FALSE ) ;
|
||||
#endif
|
||||
|
||||
}
|
||||
/**
|
||||
* This function will register a new irq.
|
||||
*
|
||||
* @param irq_num the number of the irq
|
||||
* @param handler the callback of the interrupt
|
||||
* @param arg param of thge callback
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
int32 RegisterHwIrq(uint32 irq_num, IsrHandlerType handler, void *arg)
|
||||
{
|
||||
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||
return -ERROR;
|
||||
|
||||
struct IrqDesc *desc = &isrManager.irq_table[irq_num];
|
||||
|
||||
desc->handler = handler;
|
||||
desc->param = arg;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
/**
|
||||
* This function will free a irq.
|
||||
*
|
||||
* @param irq_num the number of the irq
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
int32 FreeHwIrq(uint32 irq_num)
|
||||
{
|
||||
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||
return -ERROR;
|
||||
|
||||
memset(&isrManager.irq_table[irq_num], 0, sizeof(struct IrqDesc));
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will enable a irq.
|
||||
*
|
||||
* @param irq_num the number of the irq
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
int32 EnableHwIrq(uint32 irq_num)
|
||||
{
|
||||
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||
return -ERROR;
|
||||
|
||||
return ArchEnableHwIrq(irq_num);
|
||||
}
|
||||
/**
|
||||
* This function will disable a irq.
|
||||
*
|
||||
* @param irq_num the number of the irq
|
||||
*
|
||||
* @return EOK on success; ERROR on failure
|
||||
*/
|
||||
|
||||
int32 DisableHwIrq(uint32 irq_num)
|
||||
{
|
||||
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||
return -ERROR;
|
||||
|
||||
return ArchDisableHwIrq(irq_num);
|
||||
}
|
||||
|
||||
/* called from arch-specific ISR wrapper */
|
||||
void IsrCommon(uint32 irq_num)
|
||||
{
|
||||
struct IrqDesc *desc = &isrManager.irq_table[irq_num];
|
||||
|
||||
if (desc->handler == NONE) {
|
||||
SYS_KDEBUG_LOG(KDBG_IRQ, ("Spurious interrupt: IRQ No. %d\n", irq_num));
|
||||
while (1) {}
|
||||
}
|
||||
desc->handler(irq_num, desc->param);
|
||||
|
||||
}
|
||||
|
||||
void setIsrSwitchTrigerFlag()
|
||||
{
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
isrManager.isr_switch_trigger_flag[GetCpuId()] = 1;
|
||||
#else
|
||||
isrManager.isr_switch_trigger_flag = 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void clearIsrSwitchTrigerFlag()
|
||||
{
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
isrManager.isr_switch_trigger_flag[GetCpuId()] = 0;
|
||||
#else
|
||||
isrManager.isr_switch_trigger_flag = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8 getIsrSwitchTrigerFlag()
|
||||
{
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
return isrManager.isr_switch_trigger_flag[GetCpuId()];
|
||||
#else
|
||||
return isrManager.isr_switch_trigger_flag ;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
struct IsrDone isrDone = {
|
||||
Is_InIsr,
|
||||
RegisterHwIrq ,
|
||||
FreeHwIrq,
|
||||
EnableHwIrq,
|
||||
DisableHwIrq,
|
||||
IsrCommon,
|
||||
GetIsrCounter,
|
||||
incIsrCounter,
|
||||
decIsrCounter,
|
||||
getIsrSwitchTrigerFlag,
|
||||
setIsrSwitchTrigerFlag,
|
||||
clearIsrSwitchTrigerFlag
|
||||
} ;
|
||||
|
||||
void SysInitIsrManager()
|
||||
{
|
||||
extern int __isrtbl_idx_start;
|
||||
extern int __isrtbl_start;
|
||||
extern int __isrtbl_end;
|
||||
memset(&isrManager,0,sizeof(struct InterruptServiceRoutines));
|
||||
isrManager.done = &isrDone;
|
||||
|
||||
uint32 *index = (uint32 *)&__isrtbl_idx_start;
|
||||
struct IrqDesc *desc = (struct IrqDesc *)&__isrtbl_start;
|
||||
|
||||
while (desc != (struct IrqDesc *)&__isrtbl_end)
|
||||
isrManager.irq_table[*index++] = *desc++;
|
||||
}
|
||||
46
kernel/thread/kservicetask.c
Normal file
46
kernel/thread/kservicetask.c
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: kservicetask.c
|
||||
* @brief: create service task for system
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
extern void ZombieTaskRecycleInit(void);
|
||||
extern void InitIdleKTask(void);
|
||||
void KSerciveKTaskIdle(void)
|
||||
{
|
||||
InitIdleKTask();
|
||||
}
|
||||
|
||||
void xz_KServiceKTaskRecycle()
|
||||
{
|
||||
ZombieTaskRecycleInit();
|
||||
}
|
||||
|
||||
void CreateKServiceKTask(void)
|
||||
{
|
||||
/* create zombie recycle task */
|
||||
xz_KServiceKTaskRecycle();
|
||||
|
||||
/* create idle task */
|
||||
KSerciveKTaskIdle();
|
||||
|
||||
}
|
||||
|
||||
1125
kernel/thread/ktask.c
Normal file
1125
kernel/thread/ktask.c
Normal file
File diff suppressed because it is too large
Load Diff
105
kernel/thread/ktask_stat.c
Normal file
105
kernel/thread/ktask_stat.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: ktask_stat.c
|
||||
* @brief: the stat function definition of task
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XS_KTASK_STAT_H
|
||||
#define XS_KTASK_STAT_H
|
||||
|
||||
#include <xs_kdbg.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_ktask.h>
|
||||
#include <stdbool.h>
|
||||
#include <xs_ktask_stat.h>
|
||||
|
||||
void KTaskStateSet(KTaskDescriptorType task, uint8 stat)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
task->task_dync_sched_member.stat = stat | (task->task_dync_sched_member.stat & ~KTASK_STAT_MASK);
|
||||
}
|
||||
|
||||
void KTaskStatSetAsInit(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
KTaskStateSet(task, KTASK_INIT);
|
||||
}
|
||||
|
||||
void KTaskStatSetAsReady(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
KTaskStateSet(task, KTASK_READY);
|
||||
}
|
||||
|
||||
void KTaskStatSetAsSuspend(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
KTaskStateSet(task, KTASK_SUSPEND);
|
||||
}
|
||||
|
||||
void KTaskStatSetAsRunning(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
KTaskStateSet(task, KTASK_RUNNING);
|
||||
}
|
||||
|
||||
void KTaskStatSetAsClose(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
KTaskStateSet(task, KTASK_CLOSE);
|
||||
}
|
||||
|
||||
uint8 KTaskStatGet(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
return task->task_dync_sched_member.stat & KTASK_STAT_MASK;
|
||||
}
|
||||
|
||||
bool JudgeKTaskStatIsInit(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
return ((task->task_dync_sched_member.stat & KTASK_STAT_MASK) == KTASK_INIT);
|
||||
}
|
||||
|
||||
bool JudgeKTaskStatIsReady(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
return ((task->task_dync_sched_member.stat & KTASK_STAT_MASK) == KTASK_READY);
|
||||
}
|
||||
|
||||
bool JudgeKTaskStatIsSuspend(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
return ((task->task_dync_sched_member.stat & KTASK_STAT_MASK) == KTASK_SUSPEND);
|
||||
}
|
||||
|
||||
bool JudgeKTaskStatIsRunning(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
return ((task->task_dync_sched_member.stat & KTASK_STAT_MASK) == KTASK_RUNNING);
|
||||
}
|
||||
|
||||
bool JudgeKTaskStatIsClose(KTaskDescriptorType task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
return ((task->task_dync_sched_member.stat & KTASK_STAT_MASK) == KTASK_CLOSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
132
kernel/thread/linklist.c
Normal file
132
kernel/thread/linklist.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: linklist.c
|
||||
* @brief: suspend and wakeup function of task
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
/**
|
||||
* a task will be suspended to a pend list
|
||||
*
|
||||
* @param list suspend task list
|
||||
* @param task the task descriptor need to be suspended
|
||||
* @param flag suspend flag
|
||||
*
|
||||
*/
|
||||
x_err_t LinklistSuspend(DoubleLinklistType *list,
|
||||
struct TaskDescriptor *task,
|
||||
uint8 flag)
|
||||
{
|
||||
int32 ret = EOK;
|
||||
x_ubase lock = 0;
|
||||
DoubleLinklistType *node = NONE;
|
||||
DoubleLinklistType *tail = NONE;
|
||||
struct TaskDescriptor *tmp_task = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(list);
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
SuspendKTask(task->id.id);
|
||||
switch (flag)
|
||||
{
|
||||
case LINKLIST_FLAG_FIFO:
|
||||
DoubleLinkListInsertNodeBefore(list, &(task->task_dync_sched_member.sched_link));
|
||||
break;
|
||||
|
||||
case LINKLIST_FLAG_PRIO:
|
||||
DOUBLE_LINKLIST_FOR_EACH(node,list)
|
||||
{
|
||||
tmp_task = SYS_DOUBLE_LINKLIST_ENTRY(node, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
if (task->task_dync_sched_member.cur_prio < tmp_task->task_dync_sched_member.cur_prio)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(node != list) {
|
||||
DoubleLinkListInsertNodeBefore(&(tmp_task->task_dync_sched_member.sched_link), &(task->task_dync_sched_member.sched_link));
|
||||
} else {
|
||||
tail = list->node_prev;
|
||||
DoubleLinkListInsertNodeAfter(tail,&(task->task_dync_sched_member.sched_link));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVALED;
|
||||
break;
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* resume the first task in the suspend list
|
||||
*
|
||||
* @param list task list
|
||||
*
|
||||
*/
|
||||
x_err_t LinklistResume(DoubleLinklistType *list)
|
||||
{
|
||||
x_ubase lock = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(list);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(list->node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("resume task:%s\n", task->task_base_info.name));
|
||||
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* wakeup all the task in the suspend list
|
||||
*
|
||||
* @param list task list
|
||||
*
|
||||
*/
|
||||
x_err_t LinklistResumeAll(DoubleLinklistType *list)
|
||||
{
|
||||
x_ubase lock = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
DoubleLinklistType *node = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(list);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
for(;;) {
|
||||
node = list->node_next;
|
||||
if(node != list) {
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(node, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
task->exstatus = -ERROR;
|
||||
KTaskWakeup(task->id.id);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
110
kernel/thread/lock.c
Normal file
110
kernel/thread/lock.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: lock.c
|
||||
* @brief: system spinlock file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_spinlock.h>
|
||||
#include <xiuos.h>
|
||||
#include <xs_assign.h>
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
struct Spin_Lockfileops spinlock;
|
||||
/*
|
||||
* lock scheduler
|
||||
*/
|
||||
static void DisablePreempt(void)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
lock = DisableLocalInterrupt();
|
||||
Assign.assign_lock[GetCpuId()] ++;
|
||||
EnableLocalInterrupt(lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* enable scheduler
|
||||
*/
|
||||
static void EnablePreempt(void)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
lock = DisableLocalInterrupt();
|
||||
Assign.assign_lock[GetCpuId()] --;
|
||||
DO_KTASK_ASSIGN;
|
||||
EnableLocalInterrupt(lock);
|
||||
}
|
||||
|
||||
void InitSpinLock( struct Spin_Lockfileops * spinlock)
|
||||
{
|
||||
InitHwSpinlock(&spinlock->node_lock.lock);
|
||||
spinlock->SPinLock = _SpinLock;
|
||||
spinlock->UnlockSpinLock =_UnlockSpinLock;
|
||||
spinlock->UnlockSpinLockIrqRestore = _UnlockSpinLockIrqRestore;
|
||||
spinlock->SpinLockIrqSave = _SpinLockIrqSave;
|
||||
|
||||
}
|
||||
|
||||
void _SpinLock(struct Spin_Lockfileops * spinlock)
|
||||
{
|
||||
DisablePreempt();
|
||||
HwLockSpinlock(&spinlock->node_lock.lock);
|
||||
}
|
||||
|
||||
void _UnlockSpinLock(struct Spin_Lockfileops * spinlock)
|
||||
{
|
||||
HwUnlockSpinlock(&spinlock->node_lock.lock);
|
||||
EnablePreempt();
|
||||
}
|
||||
|
||||
x_base _SpinLockIrqSave(struct Spin_Lockfileops * spinlock)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
DisablePreempt();
|
||||
|
||||
lock = DisableLocalInterrupt();
|
||||
HwLockSpinlock(&spinlock->node_lock.lock);
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
void _UnlockSpinLockIrqRestore(struct Spin_Lockfileops * spinlock, x_base lock)
|
||||
{
|
||||
HwUnlockSpinlock(&spinlock->node_lock.lock);
|
||||
EnableLocalInterrupt(lock);
|
||||
|
||||
EnablePreempt();
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* This function will restore the scheduler lock status
|
||||
*
|
||||
*/
|
||||
void RestoreCpusLockStatus(struct TaskDescriptor *task)
|
||||
{
|
||||
#ifdef ARCH_SMP
|
||||
Assign.smp_os_running_task[GetCpuId()] = task;
|
||||
HwUnlockSpinlock(&AssignSpinLock);
|
||||
#else
|
||||
Assign.os_running_task = task;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
496
kernel/thread/msgqueue.c
Normal file
496
kernel/thread/msgqueue.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: msgqueue.c
|
||||
* @brief: msgqueue file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_delay.h>
|
||||
|
||||
DECLARE_ID_MANAGER(k_mq_id_manager, ID_NUM_MAX);
|
||||
DoubleLinklistType k_mq_list = {&k_mq_list, &k_mq_list};
|
||||
|
||||
struct mq_message
|
||||
{
|
||||
struct mq_message *next;
|
||||
};
|
||||
|
||||
static struct MsgQueue *GetMsgQueueById(int32 id)
|
||||
{
|
||||
x_base lock = 0;
|
||||
struct MsgQueue *mq = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (id < 0 )
|
||||
return NONE;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_mq_id_manager, id);
|
||||
if (idnode == NONE){
|
||||
CriticalAreaUnLock(lock);
|
||||
return NONE;
|
||||
}
|
||||
mq = CONTAINER_OF(idnode, struct MsgQueue, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
return mq;
|
||||
}
|
||||
|
||||
static x_err_t _InitMsgQueue( struct MsgQueue *mq ,x_size_t msg_size,
|
||||
x_size_t max_msgs )
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(mq);
|
||||
|
||||
mq->max_msgs = max_msgs;
|
||||
mq->num_msgs = 0;
|
||||
mq->each_len = ALIGN_MEN_UP(msg_size, MEM_ALIGN_SIZE);
|
||||
mq->index = 0;
|
||||
|
||||
InitDoubleLinkList(&mq->send_pend_list);
|
||||
InitDoubleLinkList(&(mq->recv_pend_list));
|
||||
|
||||
mq->msg_buf = x_malloc( mq->each_len * mq->max_msgs);
|
||||
if (mq->msg_buf == NONE) {
|
||||
lock = CriticalAreaLock();
|
||||
DoubleLinkListRmNode(&(mq->link));
|
||||
CriticalAreaUnLock(lock);
|
||||
KERNEL_FREE(mq);
|
||||
return -ENOMEMORY;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static x_err_t _MsgQueueSend(struct MsgQueue *mq,
|
||||
const void *buffer,
|
||||
x_size_t size,
|
||||
int32 msec)
|
||||
{
|
||||
x_ubase lock = 0;
|
||||
uint32 tick_delta = 0;
|
||||
int32 timeout = 0;
|
||||
uint8 *msg = NONE;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(mq);
|
||||
NULL_PARAM_CHECK(buffer);
|
||||
|
||||
if (size > mq->each_len)
|
||||
return -ERROR;
|
||||
|
||||
tick_delta = 0;
|
||||
task = GetKTaskDescriptor();
|
||||
timeout = CalculteTickFromTimeMs(msec);
|
||||
lock = CriticalAreaLock();
|
||||
if (mq->num_msgs >= mq->max_msgs && timeout == 0) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -EFULL;
|
||||
}
|
||||
|
||||
while(mq->num_msgs >= mq->max_msgs ) {
|
||||
|
||||
task->exstatus = EOK;
|
||||
if (timeout == 0) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -EFULL;
|
||||
}
|
||||
KDEBUG_IN_KTASK_CONTEXT;
|
||||
LinklistSuspend(&(mq->send_pend_list), task, LINKLIST_FLAG_FIFO);
|
||||
|
||||
if (timeout > 0) {
|
||||
tick_delta = CurrentTicksGain();
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("mq_send_wait: start timer of task:%s\n",
|
||||
task->task_base_info.name));
|
||||
KTaskSetDelay(task,timeout);
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
if (task->exstatus != EOK) {
|
||||
return task->exstatus;
|
||||
}
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
if (timeout > 0) {
|
||||
tick_delta = CurrentTicksGain() - tick_delta;
|
||||
timeout -= tick_delta;
|
||||
if (timeout < 0)
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
msg = mq->msg_buf + ( ( mq->index + mq->num_msgs ) % mq->max_msgs ) * mq->each_len ;
|
||||
memcpy(msg, buffer, size);
|
||||
mq->num_msgs ++;
|
||||
if (!IsDoubleLinkListEmpty(&mq->recv_pend_list)) {
|
||||
LinklistResume(&(mq->recv_pend_list));
|
||||
CriticalAreaUnLock(lock);
|
||||
DO_KTASK_ASSIGN;
|
||||
return EOK;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static x_err_t _MsgQueueUrgentSend(struct MsgQueue *mq, const void *buffer, x_size_t size)
|
||||
{
|
||||
x_ubase lock = 0;
|
||||
uint8 *msg = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(mq);
|
||||
NULL_PARAM_CHECK(buffer);
|
||||
|
||||
if (size > mq->each_len)
|
||||
return -ERROR;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
if (mq->num_msgs >= mq->max_msgs) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -EFULL;
|
||||
}
|
||||
|
||||
mq->index --;
|
||||
if (mq->index < 0)
|
||||
mq->index += mq->max_msgs;
|
||||
|
||||
msg = mq->msg_buf + ( ( mq->index + mq->num_msgs ) % mq->max_msgs ) * mq->each_len ;
|
||||
memcpy(msg , buffer, size);
|
||||
mq->num_msgs ++;
|
||||
if (!IsDoubleLinkListEmpty(&mq->send_pend_list)) {
|
||||
LinklistResume(&(mq->send_pend_list));
|
||||
CriticalAreaUnLock(lock);
|
||||
DO_KTASK_ASSIGN;
|
||||
return EOK;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static x_err_t _MsgQueueRecv(struct MsgQueue *mq,
|
||||
void *buffer,
|
||||
x_size_t size,
|
||||
int32 msec)
|
||||
{
|
||||
x_ubase lock = 0;
|
||||
uint32 tick_delta = 0;
|
||||
int32 timeout = 0;
|
||||
struct mq_message *msg = NONE;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(mq);
|
||||
NULL_PARAM_CHECK(buffer);
|
||||
|
||||
tick_delta = 0;
|
||||
task = GetKTaskDescriptor();
|
||||
timeout = CalculteTickFromTimeMs(msec);
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
if (mq->index == 0 && timeout == 0) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ETIMEOUT;
|
||||
}
|
||||
|
||||
for( ; mq->num_msgs <= 0 ; ) {
|
||||
KDEBUG_IN_KTASK_CONTEXT;
|
||||
|
||||
task->exstatus = EOK;
|
||||
if (timeout == 0) {
|
||||
CriticalAreaUnLock(lock);
|
||||
task->exstatus = -ETIMEOUT;
|
||||
return -ETIMEOUT;
|
||||
}
|
||||
|
||||
LinklistSuspend(&(mq->recv_pend_list),
|
||||
task,
|
||||
LINKLIST_FLAG_FIFO);
|
||||
|
||||
if (timeout > 0) {
|
||||
tick_delta = CurrentTicksGain();
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("set task:%s to timer list\n",
|
||||
task->task_base_info.name));
|
||||
KTaskSetDelay(task,timeout);
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
if (task->exstatus != EOK) {
|
||||
return task->exstatus;
|
||||
}
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
if (timeout > 0) {
|
||||
tick_delta = CurrentTicksGain() - tick_delta;
|
||||
timeout -= tick_delta;
|
||||
if (timeout < 0)
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
msg = mq->msg_buf + mq->index * mq->each_len;
|
||||
mq->index = (mq->index + 1) % mq->max_msgs;
|
||||
memcpy(buffer, msg , size > mq->each_len ? mq->each_len : size);
|
||||
mq->num_msgs --;
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&(mq->send_pend_list))) {
|
||||
LinklistResume(&(mq->send_pend_list));
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
return EOK;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static x_err_t _MsgQueueReinit(struct MsgQueue *mq)
|
||||
{
|
||||
x_ubase lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(mq);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
LinklistResumeAll(&mq->send_pend_list);
|
||||
LinklistResumeAll(&(mq->recv_pend_list));
|
||||
mq->index = 0;
|
||||
mq->num_msgs = 0;
|
||||
CriticalAreaUnLock(lock);
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static x_err_t _DeleteMsgQueue(struct MsgQueue *mq)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(mq);
|
||||
|
||||
LinklistResumeAll(&(mq->send_pend_list));
|
||||
LinklistResumeAll(&(mq->recv_pend_list));
|
||||
KERNEL_FREE(mq->msg_buf);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
DoubleLinkListRmNode(&(mq->link));
|
||||
CriticalAreaUnLock(lock);
|
||||
KERNEL_FREE(mq);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static struct MsgQueueDone Done = {
|
||||
.init = _InitMsgQueue ,
|
||||
.urgensend = _MsgQueueUrgentSend,
|
||||
.send = _MsgQueueSend,
|
||||
.recv = _MsgQueueRecv,
|
||||
.reinit = _MsgQueueReinit,
|
||||
.Delete = _DeleteMsgQueue
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will create a msg queue.
|
||||
*
|
||||
* @param msg_size the length of the msg queue.
|
||||
* @param max_msgs the max length of the msg queue.
|
||||
*
|
||||
* @return id on success;ENOMEMORY/ERROR on failure
|
||||
*/
|
||||
int32 KCreateMsgQueue(x_size_t msg_size,
|
||||
x_size_t max_msgs)
|
||||
{
|
||||
int32 id = 0;
|
||||
x_base temp = 0;
|
||||
x_base lock = 0;
|
||||
struct MsgQueue *mq = NONE;
|
||||
|
||||
mq = (struct MsgQueue *)x_malloc(sizeof(struct MsgQueue));
|
||||
if (mq == NONE)
|
||||
return -ENOMEMORY;
|
||||
memset(mq,0x0,sizeof(struct MsgQueue));
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
id = IdInsertObj(&k_mq_id_manager, &mq->id);
|
||||
CriticalAreaUnLock(lock);
|
||||
if (id < 0) {
|
||||
x_free(mq);
|
||||
return -ENOMEMORY;
|
||||
}
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
DoubleLinkListInsertNodeAfter(&k_mq_list, &mq->link);
|
||||
CriticalAreaUnLock(lock);
|
||||
mq->Done = &Done;
|
||||
if( mq->Done->init(mq, msg_size,max_msgs) == EOK )
|
||||
return mq->id.id;
|
||||
else
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will reset a event.
|
||||
*
|
||||
* @param id the id number of event.
|
||||
*
|
||||
* @return EOK on success;EINVALED on failure
|
||||
*/
|
||||
x_err_t KMsgQueueReinit(int32 id)
|
||||
{
|
||||
struct MsgQueue *mq = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -EINVALED;
|
||||
|
||||
mq = GetMsgQueueById(id);
|
||||
if (mq != NONE)
|
||||
return mq->Done->reinit(mq);
|
||||
else
|
||||
return -EINVALED;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* receive message with some waiting time
|
||||
*
|
||||
* @param id the message id
|
||||
* @param buffer message info
|
||||
* @param size the size of buffer
|
||||
* @param timeout time needed waiting
|
||||
*
|
||||
* @return EOK on success;EINVALED on failure
|
||||
*
|
||||
*/
|
||||
x_err_t KMsgQueueRecv(int32 id,
|
||||
void *buffer,
|
||||
x_size_t size,
|
||||
int32 timeout)
|
||||
{
|
||||
struct MsgQueue *mq = NONE;
|
||||
if (id < 0)
|
||||
return -EINVALED;
|
||||
|
||||
mq = GetMsgQueueById(id);
|
||||
if (mq != NONE)
|
||||
return mq->Done->recv(mq,buffer,size,timeout);
|
||||
else
|
||||
return -EINVALED;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* a dynamic messagequeue will be deleted from the manage list
|
||||
*
|
||||
* @param id the message id
|
||||
*
|
||||
* @return EOK on success;EINVALED on failure
|
||||
*
|
||||
*/
|
||||
x_err_t KDeleteMsgQueue(int32 id)
|
||||
{
|
||||
struct MsgQueue *mq = NONE;
|
||||
if (id < 0)
|
||||
return -EINVALED;
|
||||
|
||||
mq = GetMsgQueueById(id);
|
||||
if (mq != NONE)
|
||||
return mq->Done->Delete(mq);
|
||||
else
|
||||
return -EINVALED;
|
||||
}
|
||||
|
||||
/**
|
||||
* send urgent message without waiting time, this message will be inserted to the head of the queue
|
||||
*
|
||||
* @param id the message id
|
||||
* @param buffer message info
|
||||
* @param size the size of buffer
|
||||
*
|
||||
* @return EOK on success;EINVALED on failure
|
||||
*
|
||||
*/
|
||||
x_err_t KMsgQueueUrgentSend(int32 id, const void *buffer, x_size_t size)
|
||||
{
|
||||
struct MsgQueue *mq = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -EINVALED;
|
||||
|
||||
mq = GetMsgQueueById(id);
|
||||
if (mq != NONE)
|
||||
return mq->Done->urgensend(mq,buffer,size);
|
||||
else
|
||||
return -EINVALED;
|
||||
}
|
||||
|
||||
/**
|
||||
* send message without waiting time,current suspend task will be resumed
|
||||
*
|
||||
* @param id the message id
|
||||
* @param buffer message info
|
||||
* @param size the size of buffer
|
||||
*
|
||||
* @return EOK on success;EINVALED on failure
|
||||
*
|
||||
*/
|
||||
x_err_t KMsgQueueSend(int32 id, const void *buffer, x_size_t size)
|
||||
{
|
||||
struct MsgQueue *mq = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -EINVALED;
|
||||
|
||||
mq = GetMsgQueueById(id);
|
||||
if (mq != NONE)
|
||||
return mq->Done->send(mq,buffer,size,0);
|
||||
else
|
||||
return -EINVALED;
|
||||
}
|
||||
/**
|
||||
* send message with waiting time,current suspend task will be resumed
|
||||
*
|
||||
* @param id the message id
|
||||
* @param buffer message info
|
||||
* @param size the size of buffer
|
||||
* @param timeout waiting time
|
||||
*
|
||||
* @return EOK on success;EINVALED on failure
|
||||
*
|
||||
*/
|
||||
x_err_t KMsgQueueSendwait(int32 id, const void *buffer, x_size_t size,int32 timeout)
|
||||
{
|
||||
struct MsgQueue *mq = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -EINVALED;
|
||||
|
||||
mq = GetMsgQueueById(id);
|
||||
if (mq != NONE)
|
||||
return mq->Done->send(mq,buffer,size,timeout);
|
||||
else
|
||||
return -EINVALED;
|
||||
}
|
||||
315
kernel/thread/mutex.c
Normal file
315
kernel/thread/mutex.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: mutex.c
|
||||
* @brief: mutex file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
DECLARE_ID_MANAGER(k_mutex_id_manager, ID_NUM_MAX);
|
||||
DoubleLinklistType k_mutex_list ={&k_mutex_list, &k_mutex_list}; ///< global mutex manage list
|
||||
|
||||
static int32 _MutexCreate()
|
||||
{
|
||||
int32 id = 0;
|
||||
x_base lock = 0;
|
||||
struct Mutex *mutex = NONE;
|
||||
|
||||
mutex = x_malloc(sizeof(struct Mutex));
|
||||
if (mutex == NONE) {
|
||||
return -ENOMEMORY;
|
||||
}
|
||||
|
||||
memset(mutex, 0x0, sizeof(struct Mutex));
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
id = IdInsertObj(&k_mutex_id_manager, &mutex->id);
|
||||
if (id < 0) {
|
||||
CriticalAreaUnLock(lock);
|
||||
x_free(mutex);
|
||||
return -ENOMEMORY;
|
||||
}
|
||||
|
||||
InitDoubleLinkList(&mutex->pend_list);
|
||||
|
||||
mutex->val = 1;
|
||||
mutex->holder = NONE;
|
||||
mutex->origin_prio = 0xFF;
|
||||
mutex->recursive_cnt = 0;
|
||||
|
||||
DoubleLinkListInsertNodeAfter(&k_mutex_list, &mutex->link);
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static void _MutexDelete(struct Mutex *mutex)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(mutex);
|
||||
|
||||
LinklistResumeAll(&mutex->pend_list);
|
||||
lock = CriticalAreaLock();
|
||||
IdRemoveObj(&k_mutex_id_manager, mutex->id.id);
|
||||
|
||||
DoubleLinkListRmNode(&(mutex->link));
|
||||
CriticalAreaUnLock(lock);
|
||||
x_free(mutex);
|
||||
}
|
||||
|
||||
static int32 _MutexObtain(struct Mutex *mutex, int32 msec)
|
||||
{
|
||||
x_base lock = 0;
|
||||
int32 wait_time = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(mutex);
|
||||
|
||||
task = GetKTaskDescriptor();
|
||||
wait_time = CalculteTickFromTimeMs(msec);
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC,
|
||||
("mutex_take: current task %s, mutex value: %d, hold: %d\n",
|
||||
task->task_base_info.name, mutex->val, mutex->recursive_cnt));
|
||||
|
||||
task->exstatus = EOK;
|
||||
|
||||
if (mutex->holder == task) {
|
||||
mutex->recursive_cnt++;
|
||||
} else {
|
||||
if (mutex->val > 0) {
|
||||
mutex->val--;
|
||||
mutex->holder = task;
|
||||
mutex->origin_prio = task->task_dync_sched_member.cur_prio;
|
||||
mutex->recursive_cnt++;
|
||||
} else {
|
||||
if (wait_time == 0) {
|
||||
task->exstatus = -ETIMEOUT;
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ETIMEOUT;
|
||||
} else {
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("mutex_take: suspend task: %s\n",
|
||||
task->task_base_info.name));
|
||||
|
||||
if (task->task_dync_sched_member.cur_prio > mutex->holder->task_dync_sched_member.cur_prio)
|
||||
{
|
||||
KTaskPrioSet(mutex->holder->id.id, task->task_dync_sched_member.cur_prio);
|
||||
}
|
||||
|
||||
LinklistSuspend(&(mutex->pend_list), task, LINKLIST_FLAG_PRIO);
|
||||
|
||||
if (wait_time > 0) {
|
||||
SYS_KDEBUG_LOG(KDBG_IPC,
|
||||
("mutex_take: start the timer of task:%s\n",
|
||||
task->task_base_info.name));
|
||||
KTaskSetDelay(task,wait_time);
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
if (task->exstatus != EOK) {
|
||||
return task->exstatus;
|
||||
} else {
|
||||
lock = CriticalAreaLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static int32 _MutexAbandon(struct Mutex *mutex)
|
||||
{
|
||||
int resched = 0;
|
||||
x_base lock = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(mutex);
|
||||
|
||||
task = GetKTaskDescriptor();
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC,
|
||||
("mutex_release:current task %s, mutex value: %d, hold: %d\n",
|
||||
task->task_base_info.name, mutex->val, mutex->recursive_cnt));
|
||||
|
||||
if (task != mutex->holder) {
|
||||
task->exstatus = -ERROR;
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
mutex->recursive_cnt --;
|
||||
if (mutex->recursive_cnt == 0) {
|
||||
if (mutex->origin_prio != mutex->holder->task_dync_sched_member.cur_prio)
|
||||
{
|
||||
KTaskPrioSet(mutex->holder->id.id, mutex->origin_prio);
|
||||
}
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&mutex->pend_list)) {
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(mutex->pend_list.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("mutex_release: resume task: %s\n",
|
||||
task->task_base_info.name));
|
||||
|
||||
mutex->holder = task;
|
||||
mutex->origin_prio = task->task_dync_sched_member.cur_prio;
|
||||
mutex->recursive_cnt++;
|
||||
|
||||
LinklistResume(&(mutex->pend_list));
|
||||
|
||||
resched = RET_TRUE;
|
||||
} else {
|
||||
mutex->val++;
|
||||
mutex->holder = NONE;
|
||||
mutex->origin_prio = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
if (resched == RET_TRUE)
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static MutexDoneType done = {
|
||||
.MutexCreate = _MutexCreate,
|
||||
.MutexDelete = _MutexDelete,
|
||||
.MutexObtain = _MutexObtain,
|
||||
.MutexAbandon = _MutexAbandon,
|
||||
};
|
||||
|
||||
/**
|
||||
* a mutex will be inited in static way,then this mutex will be inserted to the manage list
|
||||
*
|
||||
* @param mutex the mutex descriptor
|
||||
* @param name mutex name
|
||||
* @param flag mutex flag
|
||||
*
|
||||
* @return EOK on success
|
||||
*
|
||||
*/
|
||||
int32 KMutexCreate()
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
return done.MutexCreate();
|
||||
}
|
||||
|
||||
/**
|
||||
* a dynamic mutex will be deleted from the manage list
|
||||
*
|
||||
* @param mutex mutex descriptor
|
||||
*
|
||||
*/
|
||||
void KMutexDelete(int32 id)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
x_base lock = 0;
|
||||
struct Mutex *mutex = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_mutex_id_manager, id);
|
||||
if (idnode == NONE) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex =CONTAINER_OF(idnode, struct Mutex, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
done.MutexDelete(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* a mutex will be taken when mutex is available
|
||||
*
|
||||
* @param mutex mutex descriptor
|
||||
* @param msec the time needed waiting
|
||||
*
|
||||
* @return EOK on success;ERROR on failure
|
||||
*
|
||||
*/
|
||||
int32 KMutexObtain(int32 id, int32 msec)
|
||||
{
|
||||
KDEBUG_IN_KTASK_CONTEXT;
|
||||
|
||||
x_base lock = 0;
|
||||
struct Mutex *mutex = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -ERROR;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_mutex_id_manager, id);
|
||||
if (idnode == NONE){
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
|
||||
mutex =CONTAINER_OF(idnode, struct Mutex, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return done.MutexObtain(mutex, msec);
|
||||
}
|
||||
|
||||
/**
|
||||
* release the mutex and resume corresponding suspended task
|
||||
*
|
||||
* @param mutex mutex descriptor
|
||||
*
|
||||
* @return EOK on success;ERROR on failure
|
||||
*/
|
||||
int32 KMutexAbandon(int32 id)
|
||||
{
|
||||
KDEBUG_IN_KTASK_CONTEXT;
|
||||
|
||||
x_base lock = 0;
|
||||
struct Mutex *mutex = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -ERROR;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_mutex_id_manager, id);
|
||||
if (idnode == NONE) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
mutex = CONTAINER_OF(idnode, struct Mutex, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
return done.MutexAbandon(mutex);
|
||||
}
|
||||
56
kernel/thread/queue_manager.c
Normal file
56
kernel/thread/queue_manager.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: queue_manager.c
|
||||
* @brief: Unified management of queue
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_queue_manager.h>
|
||||
#include <xs_dataqueue.h>
|
||||
#include <xs_workqueue.h>
|
||||
#include <xs_waitqueue.h>
|
||||
|
||||
#include <xs_memory.h>
|
||||
|
||||
void* g_queue_done[QUEUE_MAX];
|
||||
|
||||
void queuemanager_done_register()
|
||||
{
|
||||
DataQueueDoneType* pdata_queue_done = (DataQueueDoneType*)x_malloc(sizeof(DataQueueDoneType));
|
||||
pdata_queue_done->InitDataqueue = InitDataqueue;
|
||||
pdata_queue_done->PushDataqueue = PushDataqueue;
|
||||
pdata_queue_done->PopDataqueue = PopDataqueue;
|
||||
pdata_queue_done->DataqueuePeak = DataqueuePeak;
|
||||
pdata_queue_done->DeInitDataqueue = DeInitDataqueue;
|
||||
|
||||
WorkQueueDoneType* pwork_queue_done = (WorkQueueDoneType*)x_malloc(sizeof(WorkQueueDoneType));
|
||||
pwork_queue_done->CreateWorkQueue = CreateWorkQueue;
|
||||
pwork_queue_done->WorkInit = WorkInit;
|
||||
pwork_queue_done->WorkSubmit = WorkSubmit;
|
||||
pwork_queue_done->WorkSubmit_immediate = WorkSubmit_immediate;
|
||||
|
||||
WaitQueueDoneType* pwait_queue_done = (WaitQueueDoneType*)x_malloc(sizeof(WaitQueueDoneType));
|
||||
pwait_queue_done->InitWqueue = InitWqueue;
|
||||
pwait_queue_done->WqueueAdd = WqueueAdd;
|
||||
pwait_queue_done->WqueueRemove = WqueueRemove;
|
||||
pwait_queue_done->WqueueWait = WqueueWait;
|
||||
pwait_queue_done->WakeupWqueue = WakeupWqueue;
|
||||
|
||||
g_queue_done[DATA_QUEUE] = pdata_queue_done;
|
||||
g_queue_done[WORK_QUEUE] = pwork_queue_done;
|
||||
g_queue_done[WAIT_QUEUE] = pwait_queue_done;
|
||||
}
|
||||
327
kernel/thread/semaphore.c
Normal file
327
kernel/thread/semaphore.c
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: semaphore.c
|
||||
* @brief: semaphore file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
#ifdef KDEBUG_NOT_IN_INTERRUPT
|
||||
#undef KDEBUG_NOT_IN_INTERRUPT
|
||||
#endif
|
||||
|
||||
#define KDEBUG_NOT_IN_INTERRUPT
|
||||
|
||||
DECLARE_ID_MANAGER(k_sem_id_manager, ID_NUM_MAX);
|
||||
DoubleLinklistType k_sem_list = {&k_sem_list, &k_sem_list};
|
||||
|
||||
static int32 _SemaphoreCreate(uint16 val)
|
||||
{
|
||||
int32 id = 0;
|
||||
x_base lock = 0;
|
||||
struct Semaphore *sem = NONE;
|
||||
|
||||
sem = (struct Semaphore *)x_malloc(sizeof(struct Semaphore));
|
||||
if (sem == NONE)
|
||||
return -ENOMEMORY;
|
||||
|
||||
memset(sem, 0, sizeof(struct Semaphore));
|
||||
lock = CriticalAreaLock();
|
||||
id = IdInsertObj(&k_sem_id_manager, &sem->id);
|
||||
if (id < 0) {
|
||||
x_free(sem);
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ENOMEMORY;
|
||||
}
|
||||
|
||||
sem->value = val;
|
||||
InitDoubleLinkList(&sem->pend_list);
|
||||
|
||||
|
||||
DoubleLinkListInsertNodeAfter(&k_sem_list, &sem->link);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("created semaphore: id %d, value %d\n", id, (int)val));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static void _SemaphoreDelete(struct Semaphore *sem)
|
||||
{
|
||||
int resched = 0;
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(sem);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("deleted semaphore: id %d\n", (int)sem->id.id));
|
||||
lock = CriticalAreaLock();
|
||||
if (!IsDoubleLinkListEmpty(&sem->pend_list)) {
|
||||
resched = 1;
|
||||
LinklistResumeAll(&sem->pend_list);
|
||||
}
|
||||
|
||||
IdRemoveObj(&k_sem_id_manager, sem->id.id);
|
||||
DoubleLinkListRmNode(&sem->link);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
x_free(sem);
|
||||
|
||||
if (resched){
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec)
|
||||
{
|
||||
int lock = 0;
|
||||
int32 wait_time = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
NULL_PARAM_CHECK(sem);
|
||||
|
||||
wait_time = CalculteTickFromTimeMs(msec);
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("obtain semaphore: id %d, value %d, by task %s\n",
|
||||
(int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name));
|
||||
|
||||
if (sem->value > 0) {
|
||||
sem->value--;
|
||||
CriticalAreaUnLock(lock);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
if (wait_time == 0) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ETIMEOUT;
|
||||
}
|
||||
|
||||
task = GetKTaskDescriptor();
|
||||
task->exstatus = EOK;
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("obtain semaphore: suspending task %s\n",
|
||||
GetKTaskDescriptor()->task_base_info.name));
|
||||
|
||||
LinklistSuspend(&sem->pend_list, task, LINKLIST_FLAG_PRIO);
|
||||
|
||||
if (wait_time > 0) {
|
||||
KTaskSetDelay(task, wait_time);
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
return task->exstatus;
|
||||
}
|
||||
|
||||
static int32 _SemaphoreAbandon(struct Semaphore *sem)
|
||||
{
|
||||
int lock = 0;
|
||||
int resched = 0;
|
||||
|
||||
NULL_PARAM_CHECK(sem);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("abandon semaphore: id %d, value %d, by task %s\n",
|
||||
(int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name));
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&sem->pend_list)) {
|
||||
resched = 1;
|
||||
LinklistResume(&sem->pend_list);
|
||||
} else {
|
||||
sem->value++;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
if (resched){
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static int32 _SemaphoreSetValue(struct Semaphore *sem, uint16 val)
|
||||
{
|
||||
int lock = 0;
|
||||
int resched = 0;
|
||||
|
||||
NULL_PARAM_CHECK(sem);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_IPC, ("set semaphore value: id %d, old value %d, new value %d, by task %s\n",
|
||||
(int)sem->id.id, (int)sem->value, (int)val, GetKTaskDescriptor()->task_base_info.name));
|
||||
|
||||
if (sem->value == val) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&sem->pend_list)) {
|
||||
resched = 1;
|
||||
LinklistResumeAll(&sem->pend_list);
|
||||
}
|
||||
sem->value = val;
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
if (resched)
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static SemaphoreDoneType done = {
|
||||
.SemaphoreCreate = _SemaphoreCreate,
|
||||
.SemaphoreDelete = _SemaphoreDelete,
|
||||
.SemaphoreObtain = _SemaphoreObtain,
|
||||
.SemaphoreAbandon = _SemaphoreAbandon,
|
||||
.SemaphoreSetValue = _SemaphoreSetValue,
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new semaphore with specified initial value.
|
||||
*
|
||||
* @param val initial value
|
||||
* @return id of the semaphore
|
||||
*/
|
||||
int32 KSemaphoreCreate(uint16 val)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
return done.SemaphoreCreate(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a semaphore and wakeup all pending tasks on it.
|
||||
*
|
||||
* @param id id of the semaphore to be deleted
|
||||
*/
|
||||
void KSemaphoreDelete(int32 id)
|
||||
{
|
||||
x_base lock = 0;
|
||||
struct Semaphore *sem = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
if (id < 0)
|
||||
return;
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_sem_id_manager, id);
|
||||
if (idnode == NONE){
|
||||
CriticalAreaUnLock(lock);
|
||||
return;
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
sem = CONTAINER_OF(idnode, struct Semaphore, id);
|
||||
done.SemaphoreDelete(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a semaphore when its value is greater than 0; pend on it otherwise.
|
||||
*
|
||||
* @param id id of the semaphore to be obtained
|
||||
* @param msec wait time in millisecond
|
||||
* @return EOK on success, error code on failure
|
||||
*/
|
||||
int32 KSemaphoreObtain(int32 id, int32 msec)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
x_base lock = 0;
|
||||
struct Semaphore *sem = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -ERROR;
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_sem_id_manager, id);
|
||||
if (idnode == NONE){
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
sem =CONTAINER_OF(idnode, struct Semaphore, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
return done.SemaphoreObtain(sem, msec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abandon a semaphore and wakeup a pending task if any.
|
||||
*
|
||||
* @param id id of the semaphore to be abandoned
|
||||
* @return EOK on success, error code on failure
|
||||
*/
|
||||
int32 KSemaphoreAbandon(int32 id)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
x_base lock = 0;
|
||||
struct Semaphore *sem = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -ERROR;
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_sem_id_manager, id);
|
||||
if (idnode == NONE) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
sem =CONTAINER_OF(idnode, struct Semaphore, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return done.SemaphoreAbandon(sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a semaphore, wakeup all pending tasks if new value is positive.
|
||||
*
|
||||
* @param id id of the semaphore for which to set value
|
||||
* @param val new value
|
||||
* @return EOK on success, error code on failure
|
||||
*/
|
||||
int32 KSemaphoreSetValue(int32 id, uint16 val)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
x_base lock = 0;
|
||||
struct Semaphore *sem = NONE;
|
||||
struct IdNode *idnode = NONE;
|
||||
|
||||
if (id < 0)
|
||||
return -ERROR;
|
||||
lock = CriticalAreaLock();
|
||||
idnode = IdGetObj(&k_sem_id_manager, id);
|
||||
if (idnode == NONE) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
sem = CONTAINER_OF(idnode, struct Semaphore, id);
|
||||
CriticalAreaUnLock(lock);
|
||||
return done.SemaphoreSetValue(sem, val);
|
||||
}
|
||||
142
kernel/thread/single_link.c
Normal file
142
kernel/thread/single_link.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: single_link.c
|
||||
* @brief: functions definition of single linklist
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_klist.h>
|
||||
|
||||
/**
|
||||
* This function will init a linklist.
|
||||
*
|
||||
* @param linklist_head linklist node
|
||||
*/
|
||||
void InitSingleLinkList(SysSingleLinklistType *linklist)
|
||||
{
|
||||
linklist->node_next = NONE;
|
||||
}
|
||||
|
||||
void AppendSingleLinkList(SysSingleLinklistType *linklist, SysSingleLinklistType *linklist_node)
|
||||
{
|
||||
struct SingleLinklistNode *node;
|
||||
|
||||
node = linklist;
|
||||
while (node->node_next) node = node->node_next;
|
||||
|
||||
node->node_next = linklist_node;
|
||||
linklist_node->node_next = NONE;
|
||||
}
|
||||
/**
|
||||
* This function will insert a node into list after the node.
|
||||
*
|
||||
* @param linklist linklist node
|
||||
* @param linklist_node the node needed to inserted
|
||||
*/
|
||||
|
||||
void SingleLinkListNodeInsert(SysSingleLinklistType *linklist, SysSingleLinklistType *linklist_node)
|
||||
{
|
||||
linklist_node->node_next = linklist->node_next;
|
||||
linklist->node_next = linklist_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get length of the list.
|
||||
*
|
||||
* @param linklist list head
|
||||
* @return length
|
||||
*/
|
||||
|
||||
unsigned int SingleLinkListGetLen(const SysSingleLinklistType *linklist)
|
||||
{
|
||||
unsigned int length = 0;
|
||||
const SysSingleLinklistType *tmp_list = linklist->node_next;
|
||||
while (tmp_list != NONE)
|
||||
{
|
||||
tmp_list = tmp_list->node_next;
|
||||
length ++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will remove a node from the list.
|
||||
*
|
||||
* @param linklist_node the node needed to removed
|
||||
*/
|
||||
|
||||
SysSingleLinklistType *SingleLinkListRmNode(SysSingleLinklistType *linklist, SysSingleLinklistType *linklist_node)
|
||||
{
|
||||
struct SingleLinklistNode *node = linklist;
|
||||
while (node->node_next && node->node_next != linklist_node) node = node->node_next;
|
||||
|
||||
if (node->node_next != (SysSingleLinklistType *)0){
|
||||
node->node_next = node->node_next->node_next;
|
||||
}
|
||||
|
||||
return linklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the head of the list.
|
||||
*
|
||||
* @param linklist list head
|
||||
* @return list head
|
||||
*/
|
||||
SysSingleLinklistType *SingleLinkListGetFirstNode(SysSingleLinklistType *linklist)
|
||||
{
|
||||
return linklist->node_next;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the tail node of the list.
|
||||
*
|
||||
* @param linklist list head
|
||||
* @return list taile node
|
||||
*/
|
||||
SysSingleLinklistType *SingleLinkListGetTailNode(SysSingleLinklistType *linklist)
|
||||
{
|
||||
while (linklist->node_next) linklist = linklist->node_next;
|
||||
|
||||
return linklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the next node of the list head.
|
||||
*
|
||||
* @param linklist list head
|
||||
* @param linklist_node list head
|
||||
* @return next node of the list head
|
||||
*/
|
||||
|
||||
SysSingleLinklistType *SingleLinkListGetNextNode(SysSingleLinklistType *linklist_node)
|
||||
{
|
||||
return linklist_node->node_next;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will judge the list is empty.
|
||||
*
|
||||
* @param linklist the list head
|
||||
* @return true
|
||||
*/
|
||||
|
||||
int IsSingleLinkListEmpty(SysSingleLinklistType *linklist)
|
||||
{
|
||||
return linklist->node_next == NONE;
|
||||
}
|
||||
487
kernel/thread/smp_assign.c
Normal file
487
kernel/thread/smp_assign.c
Normal file
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: smp_assign.c
|
||||
* @brief: system scheduler of multiple cpu
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_isr.h>
|
||||
#include <xs_spinlock.h>
|
||||
#include <xs_ktask_stat.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_hook.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct Assign Assign;
|
||||
HwSpinlock AssignSpinLock;
|
||||
|
||||
static struct PriorityReadyVectorDone ready_vector_done =
|
||||
{
|
||||
OsAssignReadyVectorInit,
|
||||
KTaskInsertToReadyVector,
|
||||
KTaskOsAssignRemoveKTask,
|
||||
};
|
||||
|
||||
static inline x_ubase SmpGetReadyVectorHighestPrio(void)
|
||||
{
|
||||
uint8 coreid = GetCpuId();
|
||||
|
||||
return ((Assign.os_assign_read_vector.highest_prio > Assign.smp_os_assign_ready_rector[coreid].highest_prio) ? Assign.os_assign_read_vector.highest_prio : Assign.smp_os_assign_ready_rector[coreid].highest_prio);
|
||||
}
|
||||
|
||||
/*
|
||||
* get target highest priority task in ready queue
|
||||
*/
|
||||
static inline struct TaskDescriptor* SmpAssignTargetTaskSelect(void)
|
||||
{
|
||||
|
||||
uint8 coreid = GetCpuId();
|
||||
|
||||
if (Assign.os_assign_read_vector.highest_prio > Assign.smp_os_assign_ready_rector[coreid].highest_prio)
|
||||
{
|
||||
return ChooseTaskWithHighestPrio(&Assign.os_assign_read_vector);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ChooseTaskWithHighestPrio(&Assign.smp_os_assign_ready_rector[coreid]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SmpOsAssignSwtichToNewTask(struct TaskDescriptor* old_task, struct TaskDescriptor* new_task)
|
||||
{
|
||||
NULL_PARAM_CHECK(old_task);
|
||||
NULL_PARAM_CHECK(new_task);
|
||||
|
||||
Assign.ready_vector_done->remove(new_task);
|
||||
KTaskStatSetAsRunning(new_task);
|
||||
|
||||
#ifdef USING_OVERFLOW_CHECK
|
||||
_KTaskOsAssignStackCheck(new_task);
|
||||
#endif
|
||||
|
||||
SwitchKtaskContext((x_ubase)&old_task->stack_point, (x_ubase)&new_task->stack_point, new_task);
|
||||
}
|
||||
|
||||
static inline void SmpSwitchToFirstRunningTask(struct TaskDescriptor* task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
Assign.ready_vector_done->remove(task);
|
||||
KTaskStatSetAsRunning(task);
|
||||
|
||||
SwitchKtaskContextTo((x_ubase)&task->stack_point, task);
|
||||
|
||||
}
|
||||
|
||||
static inline void SetSystemRunningTask(struct TaskDescriptor* task)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
task->task_smp_info.runing_coreid = GetCpuId();
|
||||
}
|
||||
|
||||
static void SmpOsAssignInit(void)
|
||||
{
|
||||
int coreid = 0;
|
||||
while(coreid < CPU_NUMBERS) {
|
||||
Assign.ready_vector_done->init(&Assign.smp_os_assign_ready_rector[coreid]);
|
||||
Assign.smp_os_running_task[coreid] = NONE;
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
isrManager.isr_switch_trigger_flag[coreid] = 0;
|
||||
#else
|
||||
isrManager.isr_switch_trigger_flag = 0;
|
||||
#endif
|
||||
Assign.current_priority[coreid] = KTASK_PRIORITY_MAX - 1;
|
||||
Assign.assign_lock[coreid] = 0;
|
||||
coreid++;
|
||||
}
|
||||
}
|
||||
|
||||
struct smp_assign_done smp_assign_done =
|
||||
{
|
||||
SmpGetReadyVectorHighestPrio,
|
||||
SmpAssignTargetTaskSelect,
|
||||
SmpOsAssignSwtichToNewTask,
|
||||
SmpSwitchToFirstRunningTask,
|
||||
SetSystemRunningTask,
|
||||
SmpOsAssignInit,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* task schedule function.getting the highest priority task then switching to it
|
||||
*/
|
||||
void KTaskOsAssign(void)
|
||||
{
|
||||
x_base lock = 0;
|
||||
int coreid = 0;
|
||||
x_ubase highest_prio = 0;
|
||||
struct TaskDescriptor *new_task = NONE;
|
||||
struct TaskDescriptor *runningtask = NONE;
|
||||
|
||||
coreid = GetCpuId();
|
||||
if (isrManager.done->isInIsr()) {
|
||||
isrManager.done->setSwitchTrigerFlag();
|
||||
return;
|
||||
}
|
||||
|
||||
if(Assign.assign_lock[coreid] >= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
runningtask = Assign.smp_os_running_task[coreid];
|
||||
|
||||
/* if the bitmap is empty then do not switch */
|
||||
if((RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.os_assign_read_vector)) &&
|
||||
(RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.smp_os_assign_ready_rector[coreid]))) {
|
||||
return;
|
||||
}
|
||||
|
||||
highest_prio = Assign.smp_assign_done->GetHighest();
|
||||
new_task = Assign.smp_assign_done->select();
|
||||
|
||||
|
||||
if(RET_TRUE != JudgeKTaskStatIsRunning(runningtask)) {
|
||||
CHECK(NONE != new_task);
|
||||
goto SWITCH;
|
||||
}
|
||||
/* if the running task’ priority is the highest and this task is not be yield then do not switch */
|
||||
if(highest_prio < runningtask->task_dync_sched_member.cur_prio) {
|
||||
return;
|
||||
} else {
|
||||
Assign.ready_vector_done->insert(runningtask);
|
||||
}
|
||||
SWITCH:
|
||||
|
||||
new_task->task_smp_info.runing_coreid = coreid;
|
||||
Assign.current_priority[coreid] = (uint8)highest_prio;
|
||||
|
||||
HOOK(hook.assign.hook_Assign,(runningtask, new_task));
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED,
|
||||
("[%d]switch to priority#%d "
|
||||
"task:%.*s(sp:0x%08x), "
|
||||
"from task:%.*s(sp: 0x%08x)\n",
|
||||
isrManager.done->getCounter(), highest_prio,
|
||||
NAME_NUM_MAX, new_task->task_base_info.name, new_task->stack_point,
|
||||
NAME_NUM_MAX, runningtask->task_base_info.name, runningtask->stack_point));
|
||||
|
||||
Assign.smp_assign_done->SwitchToNew(runningtask,new_task);
|
||||
}
|
||||
|
||||
/**
|
||||
* task switch in IRQ context.
|
||||
*/
|
||||
void KTaskOsAssignDoIrqSwitch(void *context)
|
||||
{
|
||||
int coreid = 0;
|
||||
x_base lock = 0;
|
||||
x_ubase highest_priority = 0;
|
||||
struct TaskDescriptor *new_task = NONE;
|
||||
struct TaskDescriptor *runningtask = NONE;
|
||||
|
||||
coreid = GetCpuId();
|
||||
if ( isrManager.done->getSwitchTrigerFlag() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Assign.assign_lock[coreid] >= 1 || isrManager.done->getCounter() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
isrManager.done->clearSwitchTrigerFlag();
|
||||
|
||||
runningtask = Assign.smp_os_running_task[coreid];
|
||||
|
||||
if((RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.os_assign_read_vector)) &&
|
||||
(RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.smp_os_assign_ready_rector[coreid]))) {
|
||||
return;
|
||||
}
|
||||
|
||||
highest_priority = Assign.smp_assign_done->GetHighest();
|
||||
new_task = Assign.smp_assign_done->select();
|
||||
|
||||
if (RET_TRUE == JudgeKTaskStatIsRunning(runningtask)) {
|
||||
if (runningtask->task_dync_sched_member.cur_prio > highest_priority) {
|
||||
new_task = runningtask;
|
||||
} else {
|
||||
Assign.ready_vector_done->insert(runningtask);
|
||||
}
|
||||
}
|
||||
|
||||
new_task->task_smp_info.runing_coreid = coreid;
|
||||
if (new_task != runningtask) {
|
||||
Assign.current_priority[coreid] = (uint8)highest_priority;
|
||||
HOOK(hook.assign.hook_Assign, (runningtask, new_task));
|
||||
Assign.ready_vector_done->remove(new_task);
|
||||
KTaskStatSetAsRunning(new_task);
|
||||
|
||||
#ifdef KERNEL_STACK_OVERFLOW_CHECK
|
||||
_KTaskOsAssignStackCheck(new_task);
|
||||
#endif
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("switch in interrupt\n"));
|
||||
|
||||
|
||||
HwInterruptcontextSwitch( (x_ubase)&runningtask->stack_point,
|
||||
(x_ubase)&new_task->stack_point, new_task, context);
|
||||
}
|
||||
}
|
||||
void KTaskOsAssignAfterIrq(void *context)
|
||||
{
|
||||
x_base lock = 0;
|
||||
lock = DISABLE_INTERRUPT();
|
||||
HwLockSpinlock(&AssignSpinLock);
|
||||
KTaskOsAssignDoIrqSwitch(context);
|
||||
HwUnlockSpinlock(&AssignSpinLock);
|
||||
ENABLE_INTERRUPT(lock);
|
||||
}
|
||||
|
||||
static void UncombineInsert(struct TaskDescriptor *task)
|
||||
{
|
||||
uint32 cpu_mask = 0;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
MERGE_FLAG(&Assign.os_assign_read_vector.ready_vector[task->task_dync_sched_member.bitmap_offset], task->task_dync_sched_member.bitmap_row);
|
||||
#endif
|
||||
MERGE_FLAG(&Assign.os_assign_read_vector.priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
AssignPolicyInsert(task, &Assign.os_assign_read_vector);
|
||||
cpu_mask = CPU_MASK ^ (1 << GetCpuId());
|
||||
HwSendIpi(ASSIGN_IPI, cpu_mask);
|
||||
}
|
||||
|
||||
static void ComnbineInsert(struct TaskDescriptor *task, int coreid)
|
||||
{
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
MERGE_FLAG(&Assign.smp_os_assign_ready_rector[coreid].ready_vector[task->task_dync_sched_member.bitmap_offset], task->task_dync_sched_member.bitmap_row);
|
||||
#endif
|
||||
MERGE_FLAG(&Assign.smp_os_assign_ready_rector[coreid].priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
AssignPolicyInsert(task, &Assign.smp_os_assign_ready_rector[coreid]);
|
||||
if (coreid != task->task_smp_info.combined_coreid)
|
||||
{
|
||||
uint32 cpu_mask;
|
||||
cpu_mask = 1 << task->task_smp_info.combined_coreid;
|
||||
HwSendIpi(ASSIGN_IPI, cpu_mask);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* insert a ready task to system ready table with READY state and remove it from suspend list
|
||||
*
|
||||
* @param task the task descriptor
|
||||
*
|
||||
*/
|
||||
void KTaskInsertToReadyVector(struct TaskDescriptor *task)
|
||||
{
|
||||
int coreid = 0;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
KTaskStatSetAsReady(task);
|
||||
|
||||
coreid = task->task_smp_info.combined_coreid;
|
||||
|
||||
switch (coreid)
|
||||
{
|
||||
case UNCOMBINE_CPU_CORE:
|
||||
UncombineInsert(task);
|
||||
break;
|
||||
|
||||
default:
|
||||
ComnbineInsert(task, coreid);
|
||||
break;
|
||||
}
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("insert task[%.*s], the priority: %d\n",
|
||||
NAME_NUM_MAX, task->task_base_info.name, task->task_dync_sched_member.cur_prio));
|
||||
|
||||
}
|
||||
|
||||
static void UncombineRemove(struct TaskDescriptor *task)
|
||||
{
|
||||
register x_ubase number = 0;
|
||||
register x_ubase highest_priority = 0;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
if (IsDoubleLinkListEmpty(&(Assign.os_assign_read_vector.priority_ready_vector[task->task_dync_sched_member.cur_prio]))) {
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
|
||||
CLEAR_FLAG(&Assign.os_assign_read_vector.ready_vector[task->task_dync_sched_member.bitmap_offset], task->task_dync_sched_member.bitmap_row);
|
||||
if (Assign.os_assign_read_vector.ready_vector[task->task_dync_sched_member.bitmap_offset] == 0) {
|
||||
CLEAR_FLAG(&Assign.os_assign_read_vector.priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
}
|
||||
number = PrioCaculate(Assign.os_assign_read_vector.priority_ready_group);
|
||||
highest_priority = (number * 8) + PrioCaculate(Assign.os_assign_read_vector.ready_vector[number]);
|
||||
#else
|
||||
|
||||
|
||||
CLEAR_FLAG(&Assign.os_assign_read_vector.priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
highest_priority = PrioCaculate(Assign.os_assign_read_vector.priority_ready_group);
|
||||
#endif
|
||||
Assign.os_assign_read_vector.highest_prio = highest_priority;
|
||||
}
|
||||
}
|
||||
|
||||
static void CombineRemove(struct TaskDescriptor *task)
|
||||
{
|
||||
register x_ubase number = 0;
|
||||
register x_ubase highest_prio_on_core = 0;
|
||||
uint8 combined_coreid = task->task_smp_info.combined_coreid;
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
if (IsDoubleLinkListEmpty(&(Assign.smp_os_assign_ready_rector[combined_coreid].priority_ready_vector[task->task_dync_sched_member.cur_prio]))) {
|
||||
#if KTASK_PRIORITY_MAX > 32
|
||||
CLEAR_FLAG(&Assign.smp_os_assign_ready_rector[combined_coreid].ready_vector[task->task_dync_sched_member.bitmap_offset], task->task_dync_sched_member.bitmap_row);
|
||||
if (Assign.os_assign_read_vector.ready_vector[task->task_dync_sched_member.bitmap_offset] == 0) {
|
||||
CLEAR_FLAG(&Assign.smp_os_assign_ready_rector[combined_coreid].priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
}
|
||||
number = PrioCaculate(Assign.smp_os_assign_ready_rector[combined_coreid].priority_ready_group);
|
||||
highest_prio_on_core = (number * 8) + PrioCaculate(Assign.smp_os_assign_ready_rector[combined_coreid].ready_vector[number]);
|
||||
#else
|
||||
CLEAR_FLAG(&Assign.smp_os_assign_ready_rector[combined_coreid].priority_ready_group, task->task_dync_sched_member.bitmap_column);
|
||||
highest_prio_on_core = PrioCaculate(Assign.smp_os_assign_ready_rector[combined_coreid].priority_ready_group);
|
||||
#endif
|
||||
Assign.smp_os_assign_ready_rector[combined_coreid].highest_prio = highest_prio_on_core;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* a task will be removed from ready table.
|
||||
*
|
||||
* @param task task descriptor
|
||||
*
|
||||
*/
|
||||
void KTaskOsAssignRemoveKTask(struct TaskDescriptor *task)
|
||||
{
|
||||
|
||||
NULL_PARAM_CHECK(task);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("remove task[%.*s], the priority: %d\n",
|
||||
NAME_NUM_MAX, task->task_base_info.name,
|
||||
task->task_dync_sched_member.cur_prio));
|
||||
|
||||
DoubleLinkListRmNode(&(task->task_dync_sched_member.sched_link));
|
||||
switch (task->task_smp_info.combined_coreid)
|
||||
{
|
||||
case UNCOMBINE_CPU_CORE:
|
||||
UncombineRemove(task);
|
||||
break;
|
||||
|
||||
default:
|
||||
CombineRemove(task);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x_err_t YieldOsAssign(void)
|
||||
{
|
||||
x_base lock = 0;
|
||||
int coreid = 0;
|
||||
x_ubase highest_prio = 0;
|
||||
struct TaskDescriptor *new_task = NONE;
|
||||
struct TaskDescriptor *runningtask = NONE;
|
||||
|
||||
lock = DISABLE_INTERRUPT();
|
||||
HwLockSpinlock(&AssignSpinLock);
|
||||
coreid = GetCpuId();
|
||||
runningtask = Assign.smp_os_running_task[coreid];
|
||||
|
||||
if (isrManager.done->getCounter()) {
|
||||
HwUnlockSpinlock(&AssignSpinLock);
|
||||
ENABLE_INTERRUPT(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
if(Assign.assign_lock[coreid] >= 1) {
|
||||
HwUnlockSpinlock(&AssignSpinLock);
|
||||
ENABLE_INTERRUPT(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
/* if the bitmap is empty then do not switch */
|
||||
if((RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.os_assign_read_vector)) &&
|
||||
(RET_TRUE == JudgeAssignReadyBitmapIsEmpty(&Assign.smp_os_assign_ready_rector[coreid]))) {
|
||||
HwUnlockSpinlock(&AssignSpinLock);
|
||||
ENABLE_INTERRUPT(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
highest_prio = Assign.smp_assign_done->GetHighest();
|
||||
new_task = Assign.smp_assign_done->select();
|
||||
|
||||
if(RET_TRUE != JudgeKTaskStatIsRunning(runningtask)) {
|
||||
CHECK(NONE != new_task);
|
||||
} else {
|
||||
Assign.ready_vector_done->insert(runningtask);
|
||||
}
|
||||
|
||||
new_task->task_smp_info.runing_coreid = coreid;
|
||||
Assign.current_priority[coreid] = (uint8)highest_prio;
|
||||
|
||||
HOOK(hook.assign.hook_Assign,(runningtask, new_task));
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED,
|
||||
("[%d]switch to priority#%d "
|
||||
"task:%.*s(sp:0x%08x), "
|
||||
"from task:%.*s(sp: 0x%08x)\n",
|
||||
isrManager.done->getCounter(), highest_prio,
|
||||
NAME_NUM_MAX, new_task->task_base_info.name, new_task->stack_point,
|
||||
NAME_NUM_MAX, runningtask->task_base_info.name, runningtask->stack_point));
|
||||
|
||||
Assign.smp_assign_done->SwitchToNew(runningtask,new_task);
|
||||
|
||||
ENABLE_INTERRUPT(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* OsAssign startup function
|
||||
* .
|
||||
*/
|
||||
void StartupOsAssign(void)
|
||||
{
|
||||
struct TaskDescriptor *FirstRunningTask = NONE;
|
||||
|
||||
FirstRunningTask = Assign.smp_assign_done->select();
|
||||
Assign.smp_assign_done->SetSystemTask(FirstRunningTask);
|
||||
Assign.smp_assign_done->SwitchToFirst(FirstRunningTask);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* system OsAssign init function
|
||||
*/
|
||||
void SysInitOsAssign(void)
|
||||
{
|
||||
SYS_KDEBUG_LOG(KDBG_SCHED, ("start Os Assign: max priority 0x%02x\n",
|
||||
KTASK_PRIORITY_MAX));
|
||||
|
||||
Assign.ready_vector_done = &ready_vector_done;
|
||||
Assign.smp_assign_done = &smp_assign_done;
|
||||
Assign.ready_vector_done->init(&Assign.os_assign_read_vector);
|
||||
Assign.smp_assign_done->SmpInit();
|
||||
|
||||
}
|
||||
357
kernel/thread/softtimer.c
Normal file
357
kernel/thread/softtimer.c
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: softtimer.c
|
||||
* @brief: softtimer file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
|
||||
DoubleLinklistType xiaoshan_timer_sort_head = {&xiaoshan_timer_sort_head, &xiaoshan_timer_sort_head};
|
||||
DoubleLinklistType k_timer_list = {&k_timer_list, &k_timer_list};
|
||||
|
||||
DECLARE_ID_MANAGER(k_softtimer_id_manager, ID_NUM_MAX);
|
||||
extern queue *sys_workq;
|
||||
|
||||
void _Init(struct Timer *timer,
|
||||
const char *name,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter,
|
||||
x_ticks_t time,
|
||||
uint8 trigger_mode)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(timer);
|
||||
|
||||
strncpy(timer->name, name, NAME_NUM_MAX);
|
||||
|
||||
// insert to link
|
||||
lock = CriticalAreaLock();
|
||||
DoubleLinkListInsertNodeAfter(&(k_timer_list), &(timer->link));
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
timer->trigger_mode = trigger_mode;
|
||||
timer->active_status = TIMER_ACTIVE_FALSE;
|
||||
timer->func_callback = timeout;
|
||||
timer->param = parameter;
|
||||
timer->deadline_timeslice = 0;
|
||||
timer->origin_timeslice = time;
|
||||
timer->prio = GetKTaskDescriptor()->task_base_info.origin_prio;
|
||||
}
|
||||
|
||||
x_err_t _Delete(TimerType timer)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(timer);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
DoubleLinkListRmNode(&(timer->sortlist));
|
||||
DoubleLinkListRmNode(&(timer->link));
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
KERNEL_FREE(timer);
|
||||
timer = NONE;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
x_err_t _StartRun(TimerType timer)
|
||||
{
|
||||
NULL_PARAM_CHECK(timer);
|
||||
|
||||
x_base lock = CriticalAreaLock();
|
||||
timer->active_status = TIMER_ACTIVE_FALSE;
|
||||
|
||||
CHECK(timer->origin_timeslice < TICK_SIZE_MAX / 2);
|
||||
timer->deadline_timeslice = CurrentTicksGain() + timer->origin_timeslice;
|
||||
timer->active_status = TIMER_ACTIVE_TRUE;
|
||||
|
||||
DoubleLinklistType *pLink = NONE;
|
||||
TimerType pNode = NONE;
|
||||
|
||||
DOUBLE_LINKLIST_FOR_EACH(pLink, &xiaoshan_timer_sort_head) {
|
||||
pNode = CONTAINER_OF(pLink, struct Timer, sortlist);
|
||||
if (timer->deadline_timeslice < pNode->deadline_timeslice) {
|
||||
DoubleLinkListInsertNodeBefore(pLink, &timer->sortlist);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pLink == &xiaoshan_timer_sort_head) {
|
||||
DoubleLinkListInsertNodeBefore(&xiaoshan_timer_sort_head, &timer->sortlist);
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
// Just stop working, don't free memory
|
||||
x_err_t _QuitRun(TimerType timer)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(timer);
|
||||
|
||||
if (!(timer->active_status == TIMER_ACTIVE_TRUE))
|
||||
return -ERROR;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
timer->active_status = TIMER_ACTIVE_FALSE;
|
||||
timer->deadline_timeslice = 0;
|
||||
DoubleLinkListRmNode(&(timer->sortlist));
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
x_err_t _Modify(TimerType timer, x_ticks_t ticks)
|
||||
{
|
||||
NULL_PARAM_CHECK(timer);
|
||||
if (0 == ticks) {
|
||||
KPrintf("timeout ticks must be setted more then 0.\n");
|
||||
return -EINVALED;
|
||||
}
|
||||
timer->origin_timeslice = ticks;
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static struct TimerDone Done =
|
||||
{
|
||||
.Init = _Init,
|
||||
.Delete = _Delete,
|
||||
.StartRun = _StartRun,
|
||||
.QuitRun = _QuitRun,
|
||||
.Modify = _Modify,
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will create a softtimer.
|
||||
*
|
||||
* @param name the length of the msg queue.
|
||||
* @param timeout the callback of the timer.
|
||||
* @param parameter the parameter of the callback function
|
||||
* @param time the timeout time
|
||||
* @param trigger_mode the trigger way of the timer
|
||||
*
|
||||
* @return id on success
|
||||
*/
|
||||
|
||||
int32 KCreateTimer(const char *name,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter,
|
||||
x_ticks_t time,
|
||||
uint8 trigger_mode)
|
||||
{
|
||||
struct Timer *timer = NONE;
|
||||
|
||||
timer = (struct Timer *)x_malloc(sizeof(struct Timer));
|
||||
if (timer == NONE) {
|
||||
return NONE;
|
||||
}
|
||||
memset(timer, 0x0, sizeof(struct Timer));
|
||||
|
||||
// Generate ID
|
||||
int32 id = IdInsertObj(&k_softtimer_id_manager, &timer->id_node);
|
||||
if (id < 0) {
|
||||
x_free(timer);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
timer->done = &Done;
|
||||
timer->done->Init(timer, name, timeout, parameter, time, trigger_mode);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will delete a timer.
|
||||
*
|
||||
* @param timer_id the id number of timer.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
x_err_t KDeleteTimer(int32 timer_id)
|
||||
{
|
||||
TimerType timer = KGetTimer(timer_id);
|
||||
|
||||
timer->done->Delete(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will startup a timer.
|
||||
*
|
||||
* @param timer_id the id number of timer.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
x_err_t KTimerStartRun(int32 timer_id)
|
||||
{
|
||||
TimerType timer = KGetTimer(timer_id);
|
||||
|
||||
return timer->done->StartRun(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will stop a timer.
|
||||
*
|
||||
* @param timer_id the id number of timer.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
x_err_t KTimerQuitRun(int32 timer_id)
|
||||
{
|
||||
TimerType timer = KGetTimer(timer_id);
|
||||
|
||||
timer->done->QuitRun(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will modify the timeout of a timer.
|
||||
*
|
||||
* @param timer_id the id number of timer.
|
||||
* @param ticks timeout ticks
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
x_err_t KTimerModify(int32 timer_id, x_ticks_t ticks)
|
||||
{
|
||||
TimerType timer = KGetTimer(timer_id);
|
||||
|
||||
timer->done->Modify(timer, ticks);
|
||||
}
|
||||
|
||||
static void TimerCBEnter(void *param)
|
||||
{
|
||||
struct Timer *t = (struct Timer *)param;
|
||||
|
||||
t->func_callback(t->param);
|
||||
free(t->t_work);
|
||||
}
|
||||
|
||||
void timer_work_func(struct Work *work, void *work_data)
|
||||
{
|
||||
x_err_t flag;
|
||||
struct Timer *t = work_data;
|
||||
|
||||
int32 timer_work = KTaskCreate("timer_work_thr", TimerCBEnter, t, 2048, t->prio);
|
||||
flag = StartupKTask(timer_work);
|
||||
if (flag != EOK) {
|
||||
KPrintf("timer create callback thread failed .\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void CheckTimerList(void)
|
||||
{
|
||||
x_base lock = 0;
|
||||
struct Timer *t = NONE;
|
||||
x_ticks_t current_tick = 0;
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SOFTTIMER, ("timer check enter\n"));
|
||||
|
||||
current_tick = CurrentTicksGain();
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
while (!IsDoubleLinkListEmpty(&xiaoshan_timer_sort_head)) {
|
||||
t = SYS_DOUBLE_LINKLIST_ENTRY(xiaoshan_timer_sort_head.node_next,
|
||||
struct Timer, sortlist);
|
||||
|
||||
if ((current_tick - t->deadline_timeslice) < TICK_SIZE_MAX / 2) {
|
||||
if (t->active_status == TIMER_ACTIVE_TRUE) {
|
||||
DoubleLinkListRmNode(&t->sortlist); // Take it off the list first
|
||||
|
||||
current_tick = CurrentTicksGain();
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SOFTTIMER, ("current tick: %d\n", current_tick));
|
||||
|
||||
if (t->trigger_mode == TIMER_TRIGGER_PERIODIC) {
|
||||
t->done->StartRun(t); // Periodic timer, re insert the appropriate position of the list
|
||||
} else {
|
||||
t->done->QuitRun(t);
|
||||
}
|
||||
|
||||
// Throw it to the task queue and start a new thread
|
||||
t->t_work = x_malloc(sizeof(struct Work));
|
||||
|
||||
((WorkQueueDoneType *)sys_workq->done)->WorkInit(t->t_work, timer_work_func, t);
|
||||
CriticalAreaUnLock(lock);
|
||||
((WorkQueueDoneType *)sys_workq->done)->WorkSubmit((WorkqueueType *)sys_workq->property, t->t_work, 0);
|
||||
lock = CriticalAreaLock();
|
||||
} else {
|
||||
KPrintf("sortlist run unactive timer(%s), quit this timer\n", t->name);
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
SYS_KDEBUG_LOG(KDBG_SOFTTIMER, ("timer check leave\n"));
|
||||
}
|
||||
|
||||
x_err_t KTimerAssignMemberRun(int32 timer_id, x_ticks_t ticks)
|
||||
{
|
||||
TimerType timer = KGetTimer(timer_id);
|
||||
|
||||
NULL_PARAM_CHECK(timer);
|
||||
if (ticks == 0) {
|
||||
KPrintf("Timeout ticks must be setted more than 0.\n");
|
||||
return -EINVALED;
|
||||
}
|
||||
timer->origin_timeslice = ticks;
|
||||
|
||||
return timer->done->StartRun(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the timer with id.
|
||||
*
|
||||
* @param id the id number of timer.
|
||||
*
|
||||
* @return timer structrue
|
||||
*/
|
||||
TimerType KGetTimer(int32 id)
|
||||
{
|
||||
x_base lock = 0;
|
||||
TimerType timer = NONE;
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
struct IdNode *idnode = IdGetObj(&k_softtimer_id_manager, id);
|
||||
if (idnode == NONE){
|
||||
CriticalAreaUnLock(lock);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
timer = CONTAINER_OF(idnode, struct Timer, id_node);
|
||||
CriticalAreaUnLock(lock);
|
||||
return timer;
|
||||
}
|
||||
|
||||
int32 KGetTimerID(TimerType timer)
|
||||
{
|
||||
return timer->id_node.id;
|
||||
}
|
||||
123
kernel/thread/tick.c
Normal file
123
kernel/thread/tick.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: tick.c
|
||||
* @brief: system heartbeat_ticks update
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_spinlock.h>
|
||||
#include <xs_delay.h>
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
static x_ticks_t heartbeat_ticks[CPU_NUMBERS] = {0};
|
||||
#else
|
||||
static x_ticks_t heartbeat_ticks = 0;
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_SMP
|
||||
#define UPDATE_GLOBAL_HEARTBEAT() \
|
||||
do { \
|
||||
heartbeat_ticks[GetCpuId()]++; \
|
||||
} while(0);
|
||||
#else
|
||||
#define UPDATE_GLOBAL_HEARTBEAT() \
|
||||
do { \
|
||||
heartbeat_ticks ++; \
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* get haertbeat count
|
||||
*
|
||||
* @return CurrentTicks
|
||||
*/
|
||||
x_ticks_t CurrentTicksGain(void)
|
||||
{
|
||||
#ifdef ARCH_SMP
|
||||
return heartbeat_ticks[GetCpuId()];
|
||||
#else
|
||||
return heartbeat_ticks;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* this function increases global systick in tick interrupt,and process task time slice
|
||||
*
|
||||
*/
|
||||
void TickAndTaskTimesliceUpdate(void)
|
||||
{
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
UPDATE_GLOBAL_HEARTBEAT();
|
||||
|
||||
#if defined(SCHED_POLICY_FIFO)
|
||||
FifoTaskTimesliceUpdate();
|
||||
#elif defined (SCHED_POLICY_RR)
|
||||
task = GetKTaskDescriptor();
|
||||
RoundRobinTaskTimesliceUpdate(task);
|
||||
#elif defined (SCHED_POLICY_RR_REMAINSLICE)
|
||||
task = GetKTaskDescriptor();
|
||||
RoundRobinRemainTaskTimesliceUpdate(task);
|
||||
#endif
|
||||
CheckTaskDelay();
|
||||
#ifdef KERNEL_SOFTTIMER
|
||||
CheckTimerList();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will convert ms to ticks.
|
||||
*
|
||||
* @param ms time need to be converted
|
||||
* @return ticks
|
||||
*/
|
||||
#define MIN_TICKS 1
|
||||
|
||||
x_ticks_t CalculteTickFromTimeMs(uint32 ms)
|
||||
{
|
||||
uint32 tmp = 0;
|
||||
x_ticks_t ticks = 0;
|
||||
|
||||
ticks = (uint32)(((uint64)(ms * TICK_PER_SECOND)) / 1000) ;
|
||||
if (0 == ticks) {
|
||||
ticks = MIN_TICKS;
|
||||
} else {
|
||||
tmp = (uint32)(((uint64)(ms * TICK_PER_SECOND)) % 1000);
|
||||
|
||||
if(tmp >= 5 && tmp <= 9) {
|
||||
ticks = ticks + MIN_TICKS;
|
||||
}
|
||||
}
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will convert ticks to ms.
|
||||
*
|
||||
* @param ticks ticks need to be converted
|
||||
* @return ms
|
||||
*/
|
||||
uint32 CalculteTimeMsFromTick(x_ticks_t ticks)
|
||||
{
|
||||
uint32 ms = 0;
|
||||
|
||||
ms = (uint32)(((uint64)(ticks * 1000)) / TICK_PER_SECOND);
|
||||
|
||||
return ms;
|
||||
}
|
||||
148
kernel/thread/waitqueue.c
Normal file
148
kernel/thread/waitqueue.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: waitqueue.c
|
||||
* @brief: waitqueue file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <xs_isr.h>
|
||||
#include <device.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_memory.h>
|
||||
/**
|
||||
* This function will add a waitqueue node to the wait queue list
|
||||
*@parm queue waitqueue descriptor
|
||||
*@parm work the node need to be added
|
||||
*
|
||||
*/
|
||||
void WqueueAdd(WaitQueueType *queue, struct WaitqueueNode *node)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(queue);
|
||||
NULL_PARAM_CHECK(node);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
DoubleLinkListInsertNodeBefore(&(queue->block_threads_list), &(node->list));
|
||||
CriticalAreaUnLock(lock);
|
||||
}
|
||||
/**
|
||||
* This function will remove a waitqueue node from the wait queue list
|
||||
*@parm work the node need to be removed
|
||||
*
|
||||
*/
|
||||
void WqueueRemove(struct WaitqueueNode *node)
|
||||
{
|
||||
x_base lock = 0;
|
||||
NULL_PARAM_CHECK(node);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
DoubleLinkListRmNode(&(node->list));
|
||||
CriticalAreaUnLock(lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function restarts the suspended task of the queue
|
||||
* @parm waitqueue pointer
|
||||
* @parm the awake key
|
||||
*/
|
||||
void WakeupWqueue(WaitQueueType *queue, void *key)
|
||||
{
|
||||
x_base lock = 0;
|
||||
|
||||
NULL_PARAM_CHECK(queue);
|
||||
NULL_PARAM_CHECK(key);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
struct SysDoubleLinklistNode *node = NONE;
|
||||
DOUBLE_LINKLIST_FOR_EACH(node, &(queue->block_threads_list)) {
|
||||
struct WaitqueueNode *pEnter;
|
||||
pEnter = SYS_DOUBLE_LINKLIST_ENTRY(node, struct WaitqueueNode, list);
|
||||
if (pEnter->cb != NONE && pEnter->cb(pEnter, key) != 0) {
|
||||
continue;
|
||||
} else {
|
||||
KTaskWakeup(pEnter->polling_task->id.id);
|
||||
}
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
if (node == &(queue->block_threads_list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
/**
|
||||
* This function will suspend current task and start up a timer
|
||||
* @parm queue waitqueue descriptor
|
||||
* @parm msec waiting time
|
||||
*
|
||||
*/
|
||||
int WqueueWait(WaitQueueType *queue, x_ticks_t tick)
|
||||
{
|
||||
NULL_PARAM_CHECK(queue);
|
||||
|
||||
if (tick == 0)
|
||||
return 0;
|
||||
|
||||
struct WaitqueueNode* pin_node = x_malloc(sizeof(struct WaitqueueNode));
|
||||
|
||||
// set timeout awake
|
||||
if (tick != WAITING_FOREVER) {
|
||||
pin_node->deadline_tick = CurrentTicksGain() + tick;
|
||||
KTaskSetDelay(GetKTaskDescriptor(), tick);
|
||||
} else {
|
||||
pin_node->deadline_tick = 0;
|
||||
}
|
||||
|
||||
// init block node
|
||||
pin_node->polling_task = GetKTaskDescriptor();
|
||||
pin_node->key = 0;
|
||||
pin_node->cb = NONE;
|
||||
pin_node->list.node_next = &pin_node->list;
|
||||
pin_node->list.node_prev = &pin_node->list;
|
||||
|
||||
// start block
|
||||
x_base lock;
|
||||
lock = CriticalAreaLock();
|
||||
WqueueAdd(queue, pin_node);
|
||||
SuspendKTask(GetKTaskDescriptor()->id.id);
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
// end block, delete node
|
||||
WqueueRemove(pin_node);
|
||||
x_free(pin_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will create a wait queue.
|
||||
*
|
||||
* @param queue queue waitqueue descriptor
|
||||
*
|
||||
*/
|
||||
void InitWqueue(WaitQueueType *queue)
|
||||
{
|
||||
NULL_PARAM_CHECK(queue);
|
||||
|
||||
InitDoubleLinkList(&(queue->block_threads_list));
|
||||
}
|
||||
183
kernel/thread/workqueue.c
Normal file
183
kernel/thread/workqueue.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: workqueue.c
|
||||
* @brief: workqueue file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <device.h>
|
||||
queue *sys_workq = NONE;
|
||||
|
||||
static void _WorkQueueKTaskEntry(void *parameter)
|
||||
{
|
||||
x_base lock = 0;
|
||||
WorkqueueType *p_queue = (WorkqueueType *)parameter;
|
||||
|
||||
while (1)
|
||||
{
|
||||
lock = CriticalAreaLock();
|
||||
if (p_queue->front != p_queue->rear) { // The team is not empty
|
||||
struct Work *work = &(p_queue->base[p_queue->front]);
|
||||
|
||||
p_queue->front = (p_queue->front + 1) % MAX_WORK_QUEUE;
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
if (work->cb_func) {
|
||||
work->cb_func(work, work->cb_param);
|
||||
}
|
||||
} else {
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
SuspendKTask(p_queue->task);
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeInitWorkQueue(WorkqueueType *p_queue)
|
||||
{
|
||||
if (NONE != p_queue->task) {
|
||||
KTaskDelete(p_queue->task);
|
||||
}
|
||||
|
||||
if (NONE != p_queue) {
|
||||
if (NONE != p_queue->base) {
|
||||
x_free(p_queue->base);
|
||||
}
|
||||
x_free(p_queue);
|
||||
}
|
||||
}
|
||||
|
||||
WorkqueueType *CreateWorkQueue(const char *name, uint16 stack_size, uint8 priority)
|
||||
{
|
||||
WorkqueueType *p_queue = NONE;
|
||||
do {
|
||||
p_queue = x_malloc(sizeof(WorkqueueType));
|
||||
|
||||
if (NONE == p_queue) {
|
||||
KPrintf("CreateWorkQueue x_malloc(sizeof(WorkqueueType) failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
memset(p_queue, 0, sizeof(WorkqueueType));
|
||||
|
||||
p_queue->base = x_malloc(MAX_WORK_QUEUE * sizeof(struct Work));
|
||||
if (NONE == p_queue->base) {
|
||||
KPrintf("CreateWorkQueue x_malloc(MAX_WORK_QUEUE * sizeof(struct Work) failed\n");
|
||||
break;
|
||||
}
|
||||
memset(p_queue->base, 0, MAX_WORK_QUEUE * sizeof(struct Work));
|
||||
|
||||
p_queue->front = p_queue->rear = 0;
|
||||
|
||||
// start work thread
|
||||
p_queue->task = KTaskCreate(name, _WorkQueueKTaskEntry, p_queue, 2048, priority);
|
||||
if (NONE == p_queue->task) {
|
||||
KPrintf("CreateWorkQueue KTaskCreate failed\n");
|
||||
break;
|
||||
}
|
||||
StartupKTask(p_queue->task);
|
||||
|
||||
return p_queue;
|
||||
} while (0);
|
||||
|
||||
DeInitWorkQueue(p_queue);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
void WorkInit(struct Work *work, void (*work_func)(struct Work *work, void *work_data), void *work_data)
|
||||
{
|
||||
work->cb_func = work_func;
|
||||
work->cb_param = work_data;
|
||||
}
|
||||
|
||||
void work_elem_timeout(void *in_param)
|
||||
{
|
||||
WorkTimerParamType *param = (WorkTimerParamType *)in_param;
|
||||
WorkSubmit_immediate(param->p_queue, param->p_work);
|
||||
}
|
||||
|
||||
x_err_t WorkSubmit_immediate(WorkqueueType *sys_workq, struct Work *work)
|
||||
{
|
||||
x_base lock = CriticalAreaLock();
|
||||
|
||||
NULL_PARAM_CHECK(sys_workq);
|
||||
NULL_PARAM_CHECK(work);
|
||||
|
||||
// check queue is full
|
||||
if ((sys_workq->rear + 1 + MAX_WORK_QUEUE) % MAX_WORK_QUEUE == sys_workq->front) {
|
||||
CriticalAreaUnLock(lock);
|
||||
return -ERROR;
|
||||
}
|
||||
// add to queue
|
||||
sys_workq->base[sys_workq->rear].cb_func = work->cb_func;
|
||||
sys_workq->base[sys_workq->rear].cb_param = work->cb_param;
|
||||
sys_workq->rear = (sys_workq->rear + 1) % MAX_WORK_QUEUE;
|
||||
|
||||
// awake work thread
|
||||
KTaskWakeup(sys_workq->task);
|
||||
CriticalAreaUnLock(lock);
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
|
||||
x_err_t WorkSubmit(WorkqueueType *sys_workq, struct Work *work, x_ticks_t time)
|
||||
{
|
||||
NULL_PARAM_CHECK(sys_workq);
|
||||
NULL_PARAM_CHECK(work);
|
||||
|
||||
if (0 == time) {
|
||||
WorkSubmit_immediate(sys_workq, work);
|
||||
} else {
|
||||
// init a timer, add to queue later
|
||||
WorkTimerParamType *param = x_malloc(sizeof(WorkTimerParamType));
|
||||
param->p_queue = sys_workq;
|
||||
param->p_work = work;
|
||||
param->p_timer = KCreateTimer("wk_timer", work_elem_timeout, param, time, TIMER_TRIGGER_ONCE);
|
||||
if (NONE == param->p_timer) {
|
||||
KPrintf("WorkSubmit KCreateTimer failed \n");
|
||||
x_free(param);
|
||||
return -ERROR;
|
||||
}
|
||||
KTimerStartRun(param->p_timer);
|
||||
}
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will create a workqueue.
|
||||
*
|
||||
* @return EOK on success;ERROR on failure
|
||||
*/
|
||||
int WorkSysWorkQueueInit(void)
|
||||
{
|
||||
if (sys_workq != NONE)
|
||||
return 0;
|
||||
|
||||
sys_workq = x_malloc(sizeof(queue));
|
||||
sys_workq->done = g_queue_done[WORK_QUEUE];
|
||||
sys_workq->property = ((WorkQueueDoneType*)sys_workq->done)->CreateWorkQueue("sys_work", WORKQUEUE_KTASK_STACKSIZE,
|
||||
WORKQUEUE_KTASK_PRIORITY);
|
||||
|
||||
if (sys_workq->property == NONE) {
|
||||
KPrintf("log sys_workq create failed\n");
|
||||
} else {
|
||||
KPrintf("log sys_workq create success\n");
|
||||
}
|
||||
|
||||
return sys_workq->property == NONE ? ERROR : EOK;
|
||||
}
|
||||
96
kernel/thread/zombierecycle.c
Normal file
96
kernel/thread/zombierecycle.c
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: zombierecycle.c
|
||||
* @brief: a recycle task of system
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#ifdef TASK_ISOLATION
|
||||
#include <xs_isolation.h>
|
||||
#endif
|
||||
|
||||
DoubleLinklistType KTaskZombie;
|
||||
|
||||
#ifndef ZOMBIE_KTASK_STACKSIZE
|
||||
#define ZOMBIE_KTASK_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
int32 zombie_recycle;
|
||||
|
||||
int JudgeZombieKTaskIsNotEmpty(void)
|
||||
{
|
||||
return (IsDoubleLinkListEmpty(&KTaskZombie) ? 0 : RET_TRUE);
|
||||
}
|
||||
|
||||
static void ZombieKTaskEntry(void *parameter)
|
||||
{
|
||||
x_base lock = 0;
|
||||
KTaskDescriptorType task = NONE;
|
||||
|
||||
while(RET_TRUE)
|
||||
{
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
lock = CriticalAreaLock();
|
||||
if (JudgeZombieKTaskIsNotEmpty()) {
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(KTaskZombie.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
DoubleLinkListRmNode(&(task->task_dync_sched_member.sched_link));
|
||||
CriticalAreaUnLock(lock);
|
||||
#ifdef SEPARATE_COMPILE
|
||||
if(1 == task->task_dync_sched_member.isolation_flag ){
|
||||
#ifdef MOMERY_PROTECT_ENABLE
|
||||
if(mem_access.Free)
|
||||
mem_access.Free(task->task_dync_sched_member.isolation);
|
||||
#endif
|
||||
x_ufree(task->task_base_info.stack_start);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
KERNEL_FREE(task->task_base_info.stack_start);
|
||||
}
|
||||
|
||||
DoubleLinkListRmNode(&(task->link));
|
||||
|
||||
KTaskIdDelete(task->id.id);
|
||||
|
||||
if(task->task_dync_sched_member.delay != NONE){
|
||||
|
||||
}
|
||||
KERNEL_FREE(task->task_dync_sched_member.delay);
|
||||
|
||||
KERNEL_FREE(task);
|
||||
} else {
|
||||
SuspendKTask(zombie_recycle);
|
||||
CriticalAreaUnLock(lock);
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZombieTaskRecycleInit(void)
|
||||
{
|
||||
InitDoubleLinkList(&KTaskZombie);
|
||||
|
||||
zombie_recycle = KTaskCreate("ZombieRecycleKTask",
|
||||
ZombieKTaskEntry,
|
||||
NONE,
|
||||
ZOMBIE_KTASK_STACKSIZE,
|
||||
KTASK_LOWEST_PRIORITY + 1);
|
||||
|
||||
StartupKTask(zombie_recycle);
|
||||
}
|
||||
Reference in New Issue
Block a user