增加自动测试框架&优化多arch支持

This commit is contained in:
zhangzheng
2024-09-17 11:38:12 +08:00
parent aaad929523
commit 354abcd569
72 changed files with 863 additions and 446 deletions

5
.vscode/launch.json vendored
View File

@@ -53,8 +53,9 @@
// "miDebuggerPath": "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gdb",
// "miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
// "miDebuggerPath": "/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
"miDebuggerPath": "/home/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
"miDebuggerServerAddress": "127.0.0.1:33333",
// "miDebuggerPath": "/home/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
"miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb",
"miDebuggerServerAddress": "127.0.0.1:3333",
"MIMode": "gdb",
"setupCommands": [
{

View File

@@ -104,7 +104,11 @@
"ref.h": "c",
"fcntl.h": "c",
"syscall.h": "c",
"statvfs.h": "c"
"statvfs.h": "c",
"cutest.h": "c",
"u_mutex.h": "c",
"stdint.h": "c",
"cons_cli.h": "c"
},
"cortex-debug.showRTOS": false,
"cortex-debug.variableUseNaturalFormat": false,

View File

@@ -124,8 +124,8 @@ if ((DEFINED CONFIG_MMU) AND (CONFIG_MMU STREQUAL "y"))
mkrtos_dump_elf
sh_dump_elf
cpiofs_dump_elf
net_dump_elf
uvmm_dump_elf
# net_dump_elf
# uvmm_dump_elf
)
set_source_files_properties(${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio.elf PROPERTIES EXTERNAL_OBJECT true)
add_executable(bootstrap.elf

View File

@@ -1,18 +1,18 @@
#pragma once
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed char int8_t; //!< 8位有符号整数
typedef signed short int16_t; //!< 16位有符号整数
typedef signed int int32_t; //!< 32位有符号整数
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t; //!< 16位无符号整数
typedef unsigned int uint32_t; //!< 32位无符号整数
typedef unsigned long long uint64_t;
typedef unsigned long long uint64_t; //!< 64位无符号整数
typedef long long int64_t;
typedef unsigned long umword_t;
typedef unsigned long umword_t; //!< 无符号字
typedef unsigned short uhmword_t;
typedef long mword_t;
typedef short uhumword_t;

View File

@@ -4,12 +4,12 @@
#
CONFIG_KNL_INFO=y
CONFIG_KNL_TEXT_ADDR=0x8000000
CONFIG_KNL_TEXT_SIZE=0x100000
CONFIG_KNL_TEXT_SIZE=0x800000
CONFIG_KNL_DATA_ADDR=0x20000000
CONFIG_KNL_DATA_SIZE=0x800000
CONFIG_KNL_OFFSET=0x2000
CONFIG_INIT_TASK_OFFSET=0x10000
CONFIG_BOOTFS_OFFSET=0x22000
CONFIG_BOOTFS_OFFSET=0x30000
CONFIG_MK_MPU_CFG=y
CONFIG_FT_ADDR_NR=16
CONFIG_SYS_SCHE_HZ=1000

View File

@@ -4,9 +4,9 @@
#
CONFIG_KNL_INFO=y
CONFIG_KNL_TEXT_ADDR=0x8000000
CONFIG_KNL_TEXT_SIZE=0x100000
CONFIG_KNL_TEXT_SIZE=0x800000
CONFIG_KNL_DATA_ADDR=0x20000000
CONFIG_KNL_DATA_SIZE=0x2000000
CONFIG_KNL_DATA_SIZE=0x800000
CONFIG_KNL_OFFSET=0x2000
CONFIG_INIT_TASK_OFFSET=0x10000
CONFIG_BOOTFS_OFFSET=0x22000

View File

@@ -7,9 +7,9 @@ CONFIG_KNL_TEXT_ADDR=0x00000000
CONFIG_KNL_TEXT_SIZE=0x80000
CONFIG_KNL_DATA_ADDR=0x20000000
CONFIG_KNL_DATA_SIZE=0x10000
CONFIG_KNL_OFFSET=0x2000
CONFIG_INIT_TASK_OFFSET=0x10000
CONFIG_BOOTFS_OFFSET=0x22000
CONFIG_KNL_OFFSET=0x3000
CONFIG_INIT_TASK_OFFSET=0x1a000
CONFIG_BOOTFS_OFFSET=0x32000
CONFIG_MK_MPU_CFG=n
CONFIG_FT_ADDR_NR=16
CONFIG_SYS_SCHE_HZ=1000

View File

@@ -6,17 +6,19 @@
#include <util.h>
/**
* @brief 调度函数
*
* @param usp
* @param ksp
* @param sp_type
* @return sp_info_t*
*
* @param usp
* @param ksp
* @param sp_type
* @return sp_info_t*
*/
sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type)
{
// printk("cur_th:0x%lx\n", thread_get_current());
scheduler_t *sche = scheduler_get_current();
sched_t *next = sche->cur_sche;
assert(next);
thread_t *next_th = container_of(next, thread_t, sche);
assert(next_th->magic == THREAD_MAGIC);

View File

@@ -39,7 +39,8 @@ typedef struct sp_info
} sp_info_t;
#define _dmb(ins)
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define cpu_sleep() asm volatile("wfi" : : : "memory")
#define read_reg(addr) (*((volatile umword_t *)(addr)))
#define write_reg(addr, data) \
do \

View File

@@ -38,8 +38,10 @@ typedef struct sp_info
void *knl_sp; //!< 内核sp
mword_t sp_type; //!< 使用的栈类型
} sp_info_t;
#define _dmb(ins)
#define _dmb(ins) asm volatile("dmb" : : : "memory")
#define _dsb(ins) asm volatile("dsb" : : : "memory")
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define cpu_sleep() asm volatile("wfi" : : : "memory")
#define read_reg(addr) (*((volatile umword_t *)(addr)))
#define write_reg(addr, data) \
do \
@@ -122,11 +124,10 @@ static inline int arch_get_current_cpu_id(void)
{ \
write_sysreg(0, PRIMASK); \
} while (0)
#define cli() \
do \
{ \
__asm__ __volatile__("CPSID I\n" :: \
:); \
#define cli() \
do \
{ \
write_sysreg(1, PRIMASK); \
} while (0)
static inline __attribute__((optimize(0))) void preemption(void)

View File

@@ -2,7 +2,7 @@ ENTRY(Reset_Handler)
MEMORY
{
RAM (arw) : ORIGIN = 0x20000000, LENGTH = 0x10000
FLASH (arx) : ORIGIN = 0x00000000 + 0x2000, LENGTH = 0x10000 - 0x2000
FLASH (arx) : ORIGIN = 0x00000000 + 0x3000, LENGTH = 0x1a000 - 0x3000
}
SECTIONS
{

View File

@@ -38,7 +38,8 @@ typedef struct sp_info
mword_t sp_type; //!< 使用的栈类型
} sp_info_t;
#define _dmb(ins)
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define cpu_sleep() asm volatile("wfi" : : : "memory")
#define read_reg(addr) (*((volatile umword_t *)(addr)))
#define write_reg(addr, data) \
do \

View File

@@ -1,7 +1,7 @@
ENTRY(Reset_Handler)
MEMORY
{
RAM (arw) : ORIGIN = 0x20000000, LENGTH = 0x2000000
RAM (arw) : ORIGIN = 0x20000000, LENGTH = 0x800000
FLASH (arx) : ORIGIN = 0x8000000 + 0x2000, LENGTH = 0x10000 - 0x2000
}
SECTIONS

View File

@@ -38,7 +38,8 @@ typedef struct sp_info
mword_t sp_type; //!< 使用的栈类型
} sp_info_t;
#define _dmb(ins)
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define cpu_sleep() asm volatile("wfi" : : : "memory")
#define read_reg(addr) (*((volatile umword_t *)(addr)))
#define write_reg(addr, data) \
do \

View File

@@ -25,16 +25,17 @@ typedef struct region_info
#endif
typedef struct mm_space
{
#if IS_ENABLED(CONFIG_MK_MPU_CFG)
region_info_t pt_regions[CONFIG_REGION_NUM]; //!< mpu内存保护块
#endif
#if IS_ENABLED(CONFIG_MMU)
page_entry_t mem_dir; //!< MMU根映射表存放映射信息
task_vma_t mem_vma;
umword_t asid;
#endif
#else
void *mm_block; //!< task 的私有内存块
size_t mm_block_size; //!< 私有内存块的大小
#if IS_ENABLED(CONFIG_MK_MPU_CFG)
region_info_t pt_regions[CONFIG_REGION_NUM]; //!< mpu内存保护块
#endif
#endif
} mm_space_t;
enum region_rights
@@ -87,11 +88,4 @@ static inline void mm_space_get_ram_block(mm_space_t *mm_space, void **mem, size
*mem = mm_space->mm_block;
*size = mm_space->mm_block_size;
}
#else
static inline void mm_space_set_ram_block(mm_space_t *mm_space, void *mem, size_t size)
{
}
static inline void mm_space_get_ram_block(mm_space_t *mm_space, void **mem, size_t *size)
{
}
#endif

View File

@@ -12,6 +12,7 @@
SECTION(".data") type name
#endif
void pre_cpu_init(void);
bool_t pre_cpu_is_init(void);
void *pre_get_current_cpu_var(void *mem_addr);
void *pre_cpu_get_var_cpu(uint32_t cpu_inx, void *mem_addr);
void *pre_cpu_get_current_cpu_var(void *mem_addr);

View File

@@ -40,4 +40,4 @@ void dumpstack(void);
*
*/
#define dbg_print_kobj(kobj, fmt, ...) printk(kobject_get_name(kobj), "[%s]" fmt, __VA_ARGS__)
#define dbg_printk(fmt, ...) printk("[%d]" fmt, arch_get_sys_clk(), __VA_ARGS__)
#define dbg_printk(fmt, ...) printk("[%d]" fmt, sys_tick_cnt_get(), __VA_ARGS__)

View File

@@ -11,7 +11,8 @@
#include "slist.h"
#define PRIO_MAX WORD_BITS
// extern umword_t sched_reset;
#define SCHEDULER_DEBUG 0
typedef struct sched
{

View File

@@ -7,8 +7,8 @@
#define MK_SET_BIT(a, b) ((a) |= 1UL << (b)) //!< 设置BIT
#define MK_CLR_BIT(a, b) ((a) &= ~(1UL << (b))) //!< 清除BIT
#define MK_GET_BIT(a, b) (((a) >> (b)) & 0x1) //!< 获取某位的bit
#define ABS(a) ((a) < 0 ? -(a) : (a)) //!< 取绝对值
#define MK_GET_BIT(a, b) (((a) >> (b)) & 0x1) //!< 获取某位的bit
#define ABS(a) ((a) < 0 ? -(a) : (a)) //!< 取绝对值
#define ROUND(a, b) (((a) / (b)) + (((a) % (b)) ? 1 : 0)) //!< a/b后的值向上取整
#define ROUND_UP(a, b) ROUND(a, b) //!< a除b向上取整数
@@ -22,20 +22,19 @@
#define ALIGN(mem, align) (((mem) + ((align) - 1)) & (~((align) - 1))) //!< 向上对齐
#define ALIGN_DOWN(mem, align) ((mem) & (~((align) - 1))) //!< 向下对齐
#define PACKED __attribute__((packed))
#define SECTION(section) __attribute__((__section__(section)))
#define __ALIGN__(size) __attribute__((aligned(size)))
#define PACKED __attribute__((packed)) //!< 打包
#define SECTION(section) __attribute__((__section__(section))) //!< 指定section
#define __ALIGN__(size) __attribute__((aligned(size))) //!< 对齐
#define __WEAK__ __attribute__((weak))
#define __WEAK__ __attribute__((weak)) //!< 弱引用
#define container_of(ptr, type, member) \
((type *)(((unsigned long)(ptr)) - ((unsigned long)(&(((type *)0)->member)))))
((type *)(((unsigned long)(ptr)) - ((unsigned long)(&(((type *)0)->member))))) //!< 获取结构体指针
#define USED __attribute__((used)) //!< 使用
#define UNUSED __attribute__((unused)) //!< 未使用
#define USED __attribute__((used))
#define UNUSED __attribute__((unused))
#define __ARG_PLACEHOLDER_1 0,
#define __ARG_PLACEHOLDER_1 0,
#define __take_second_arg(__ignored, val, ...) val
#define __is_defined(x) ___is_defined(x)
#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val)
@@ -46,11 +45,16 @@
#define IS_BUILTIN(option) __is_defined(option)
#define IS_MODULE(option) __is_defined(option##_MODULE)
#define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option))
#define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option)) //!< 判断option是否被定义
int ffs(int x);
int clz(umword_t x);
/**
* @brief 判断是否是2的幂
*
* @param num 需要判断的数
* @return umword_t 是2的幂返回true否则返回false
*/
static inline umword_t is_power_of_2(umword_t num)
{
return (num & (num - 1)) == 0;

View File

@@ -21,17 +21,21 @@
#include <fcntl.h>
#include <vma.h>
#include <globals.h>
/**
* @brief virtual memory object 定义
*
*/
typedef struct vma_obj
{
kobject_t kobj;
vma_t vmam;
kobject_t kobj; //!< 内核对象
} vma_obj_t;
enum
{
VMA_ALLOC,
VMA_FREE,
VMA_GRANT,
VMA_ALLOC, //!< 申请
VMA_FREE, //!< 释放
VMA_GRANT, //!< 转移
};
static void vma_obj_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f)
@@ -78,16 +82,20 @@ static void vma_obj_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_
kobject_t *kobj;
kobj = obj_space_lookup_kobj_cmp_type(&tk->obj_space, f->regs[0], TASK_TYPE);
if (kobj==NULL) {
if (kobj == NULL)
{
f->regs[0] = msg_tag_init4(0, 0, 0, -ENOENT).raw;
break;
}
ret = task_vma_grant(&tk->mm_space.mem_vma, &((task_t *)kobj)->mm_space.mem_vma,
f->regs[1], f->regs[2], f->regs[3]);
f->regs[1], f->regs[2], f->regs[3]);
f->regs[0] = msg_tag_init4(0, 0, 0, ret).raw;
}
break;
default:
f->regs[0] = msg_tag_init4(0, 0, 0, -ENOSYS).raw;
break;
}
}
static bool_t vma_obj_put(kobject_t *kobj)

View File

@@ -28,6 +28,10 @@ void pre_cpu_init(void)
memset(pre_cpu_data, 0, pre_cpu_data_size * CONFIG_CPU);
}
}
bool_t pre_cpu_is_init(void)
{
return !!pre_cpu_data;
}
INIT_KOBJ_MEM(pre_cpu_init);
@@ -36,8 +40,11 @@ void pre_cpu_init(void)
{
}
INIT_KOBJ_MEM(pre_cpu_init);
bool_t pre_cpu_is_init(void)
{
return TRUE;
}
#endif
void *pre_cpu_get_var_cpu(uint32_t cpu_inx, void *mem_addr)
{
#if IS_ENABLED(CONFIG_SMP)
@@ -46,6 +53,7 @@ void *pre_cpu_get_var_cpu(uint32_t cpu_inx, void *mem_addr)
return (void *)((addr_t)pre_cpu_data +
offset + cpu_inx * pre_cpu_data_size);
#else
assert(cpu_inx == 0);
return mem_addr;
#endif
}

View File

@@ -13,7 +13,8 @@
#include "stdarg.h"
#include "uart/uart.h"
#include "xprintf.h"
#include "thread.h"
#include "pre_cpu.h"
static spinlock_t lock;
static char print_cache[CONFIG_PRINTK_CACHE_SIZE];
@@ -24,7 +25,8 @@ static char print_cache[CONFIG_PRINTK_CACHE_SIZE];
*/
static void print_raw(const char *str)
{
for (int i = 0; str[i]; i++) {
for (int i = 0; str[i]; i++)
{
uart_putc(uart_get_global(), str[i]);
}
}
@@ -51,13 +53,16 @@ void printk(const char *fmt, ...)
{
va_list args;
umword_t state = 0;
thread_t *cut_th = thread_get_current();
state = spinlock_lock(&lock);
xsprintf(print_cache, "[%8d]%s: ",
pre_cpu_is_init() ? sys_tick_cnt_get() : 0,
kobject_get_name(&cut_th->kobj));
print_raw(print_cache);
va_start(args, fmt);
xvsprintf(print_cache, fmt, args);
va_end(args);
print_raw(print_cache);
spinlock_set(&lock, state);
}

View File

@@ -23,6 +23,9 @@ void scheduler_reset(void)
sched->sched_reset = 0;
sched->cur_sche = NULL;
#if SCHEDULER_DEBUG
printk("%s set to null\n", __func__);
#endif
}
scheduler_t *scheduler_get_current(void)
@@ -35,8 +38,10 @@ scheduler_t *scheduler_get_cpu(int inx)
}
void scheduler_init(void)
{
for (int j = 0; j < CONFIG_CPU; j++) {
for (int i = 0; i < PRIO_MAX; i++) {
for (int j = 0; j < CONFIG_CPU; j++)
{
for (int i = 0; i < PRIO_MAX; i++)
{
slist_init(&(scheduler_get_cpu(j)->prio_list[i]));
}
}
@@ -51,38 +56,48 @@ bool_t scheduler_add_to_cpu(sched_t *node, int cpu)
int ret = 0;
thread_t *node_th = container_of(node, thread_t, sche);
assert(cpulock_get_status());
assert(node_th->magic == THREAD_MAGIC);
scheduler_t *sched = scheduler_get_cpu(cpu);
assert(node->prio >= 0);
assert(node->prio < PRIO_MAX);
if (node->prio > sched->max_prio) {
if (node->prio > sched->max_prio)
{
sched->max_prio = node->prio;
sched->cur_sche = NULL;
#if SCHEDULER_DEBUG
printk("%s set to null\n", __func__);
#endif
ret = 1;
}
MK_SET_BIT(sched->bitmap[node->prio / PRIO_MAX], node->prio % PRIO_MAX);
slist_add(&(sched->prio_list[node->prio]), &node->node);
return 0;
return ret;
}
void scheduler_del(sched_t *node)
{
scheduler_t *sched = scheduler_get_current();
thread_t *th = container_of(node, thread_t, sche);
assert(cpulock_get_status());
assert(thread_get_status(th) == THREAD_SUSPEND);
assert(node->prio >= 0);
assert(node->prio < PRIO_MAX);
slist_del(&node->node);
if (slist_is_empty(&sched->prio_list[node->prio])) {
if (slist_is_empty(&sched->prio_list[node->prio]))
{
MK_CLR_BIT(sched->bitmap[node->prio / PRIO_MAX], node->prio % PRIO_MAX);
for (mword_t i = (PRIO_MAX / WORD_BITS - 1); i >= 0; i--) {
for (mword_t i = (PRIO_MAX / WORD_BITS - 1); i >= 0; i--)
{
int ret = clz(sched->bitmap[i]);
if (ret != WORD_BITS) {
if (ret != WORD_BITS)
{
int max_prio = (i + 1) * WORD_BITS - ret - 1;
assert(!slist_is_empty(&sched->prio_list[max_prio]));
sched->max_prio = max_prio;
@@ -90,6 +105,9 @@ void scheduler_del(sched_t *node)
}
}
sched->cur_sche = NULL;
#if SCHEDULER_DEBUG
printk("%s set to null\n", __func__);
#endif
}
}
sched_t *scheduler_next_cpu(int cpu)
@@ -97,12 +115,17 @@ sched_t *scheduler_next_cpu(int cpu)
scheduler_t *sche = scheduler_get_cpu(cpu);
sched_t *next_sch = NULL;
slist_head_t *next = NULL;
assert(cpulock_get_status());
if (sche->cur_sche == NULL || slist_is_empty(&sche->cur_sche->node)) {
if (sche->cur_sche == NULL || slist_is_empty(&sche->cur_sche->node))
{
next = slist_first(&sche->prio_list[sche->max_prio]);
} else {
}
else
{
next = sche->cur_sche->node.next;
if (next == &(sche->prio_list[sche->max_prio])) {
if (next == &(sche->prio_list[sche->max_prio]))
{
next = slist_first(&sche->prio_list[sche->max_prio]);
}
}

View File

@@ -132,7 +132,7 @@ static sema_t *sema_create(ram_limit_t *lim, umword_t cnt, umword_t max)
#if IS_ENABLED(CONFIG_BUDDY_SLAB)
kobj = mm_limit_alloc_slab(sema_slab, lim);
#else
kobj = mm_limit_alloc(lim, sizeof(factory_t));
kobj = mm_limit_alloc(lim, sizeof(sema_t));
#endif
if (!kobj)
{
@@ -155,7 +155,7 @@ static void sema_release_stage1(kobject_t *kobj)
static void sema_release_stage2(kobject_t *kobj)
{
/*TODO:*/
printk("sema 0x%x free.\n", kobj);
printk("TODO:sema 0x%x free.\n", kobj);
}
void sema_init(sema_t *obj, int cnt, int max)

View File

@@ -15,6 +15,7 @@
#include <factory.h>
#include <string.h>
#include <slab.h>
#include <vma.h>
#include "mm_wrap.h"
#include "mpu.h"
#include "init.h"
@@ -186,6 +187,7 @@ static int share_mem_free_pmem(share_mem_t *obj)
return -ENOSYS;
case SHARE_MEM_CNT_DPD:
{
#if IS_ENABLED(CONFIG_MMU)
for (ssize_t st = 0; st < obj->size; st += PAGE_SIZE)
{
mm_limit_free_buddy(obj->lim, obj->mem_array[st / PAGE_SIZE], PAGE_SIZE);
@@ -194,6 +196,9 @@ static int share_mem_free_pmem(share_mem_t *obj)
size_t mem_array_size = ALIGN(mem_cnt * sizeof(void *), PAGE_SIZE);
mm_limit_free_buddy(obj->lim, obj->mem_array, mem_array_size);
#else
return -ENOSYS;
#endif
}
break;
}
@@ -207,6 +212,8 @@ static int share_mem_free_pmem(share_mem_t *obj)
*/
static int share_mem_alloc_pmem(share_mem_t *obj)
{
int align_size = 0;
assert(obj);
if (obj->mem)
{
@@ -218,7 +225,7 @@ static int share_mem_alloc_pmem(share_mem_t *obj)
#if IS_ENABLED(CONFIG_MMU)
obj->mem = mm_limit_alloc_buddy(obj->lim, obj->size);
#else
int align_size = obj->size;
align_size = obj->size;
#if CONFIG_MK_MPU_CFG
#if CONFIG_MPU_VERSION == 1
@@ -241,7 +248,7 @@ static int share_mem_alloc_pmem(share_mem_t *obj)
align_size = sizeof(void *);
#endif
obj->mem = mm_limit_alloc_align(lim, obj->size, align_size);
obj->mem = mm_limit_alloc_align(obj->lim, obj->size, align_size);
#endif
if (obj->mem == NULL)
{
@@ -254,6 +261,7 @@ static int share_mem_alloc_pmem(share_mem_t *obj)
return -ENOSYS;
case SHARE_MEM_CNT_DPD:
{
#if IS_ENABLED(CONFIG_MMU)
/** 非连续内存,按页申请 */
int mem_cnt = ROUND_UP(obj->size, PAGE_SIZE);
size_t mem_array_size = ALIGN(mem_cnt * sizeof(void *), PAGE_SIZE);
@@ -280,6 +288,9 @@ static int share_mem_alloc_pmem(share_mem_t *obj)
}
memset(obj->mem_array[i], 0, PAGE_SIZE);
}
#else
return -ENOSYS;
#endif
}
break;
}
@@ -345,14 +356,14 @@ static ssize_t share_mem_map(share_mem_t *obj, vma_addr_t addr, vaddr_t *ret_vad
return ret;
}
#else
bool_t _ret = mm_space_add(&task->mm_space, (umword_t)(sm->mem), sm->size, attr);
bool_t _ret = mm_space_add(&task->mm_space, (umword_t)(obj->mem), obj->size, REGION_RWX /*TODO:这里写死了*/);
if (_ret)
{
mpu_switch_to_task(task);
}
map_size = _ret == TRUE ? 0 : -ENOMEM;
*ret_vaddr = sm->mem;
*ret_vaddr = (vaddr_t)(obj->mem);
#endif
return map_size;
}

View File

@@ -58,6 +58,8 @@ static void task_mem_init(void)
#endif
}
INIT_KOBJ_MEM(task_mem_init);
#if !IS_ENABLED(CONFIG_MMU)
/**
* @brief 为task分配其可以使用的内存空间
*
@@ -82,6 +84,7 @@ int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size)
printk("task alloc size is %d, base is 0x%x\n", size + THREAD_MSG_BUG_LEN, ram);
return 0;
}
#endif
/**
* @brief 获取线程绑定的task
*
@@ -259,6 +262,7 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
cpulock_set(status);
tag = msg_tag_init4(0, 0, 0, 0);
} break;
#if !IS_ENABLED(CONFIG_MMU)
case TASK_ALLOC_RAM_BASE: //!< 分配task所拥有的内存空间
{
mword_t status = spinlock_lock(&tag_task->kobj.lock);
@@ -271,6 +275,7 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
f->regs[1] = (umword_t)(tag_task->mm_space.mm_block);
spinlock_set(&tag_task->kobj.lock, status);
} break;
#endif
case TASK_COPY_DATA: //!< 拷贝数据到task的内存区域
{
void *mem;

View File

@@ -225,7 +225,9 @@ static void thread_release_stage1(kobject_t *kobj)
if (cur != th)
{
thread_release_stage1_remote(th);
} else {
}
else
{
thread_release_stage1_remote(cur);
}
// if (cur != th)
@@ -294,7 +296,6 @@ static void thread_release_stage2(kobject_t *kobj)
{
thread_t *th = container_of(kobj, thread_t, kobj);
thread_t *cur_th = thread_get_current();
// printk("release thread 0x%x\n", kobj);
if (cur_th == th)
{
@@ -307,6 +308,7 @@ static void thread_release_stage2(kobject_t *kobj)
#else
mm_limit_free_align(th->lim, kobj, CONFIG_THREAD_BLOCK_SIZE);
// mm_trace();
// printk("release thread 0x%x\n", kobj);
#endif
}
@@ -352,6 +354,7 @@ void thread_unbind(thread_t *th)
}
void thread_suspend_sw(thread_t *th, bool_t is_sche)
{
assert(cpulock_get_status());
assert(slist_in_list(&th->sche.node));
assert(th->cpu == arch_get_current_cpu_id());
umword_t status = cpulock_lock();
@@ -366,9 +369,10 @@ void thread_suspend_sw(thread_t *th, bool_t is_sche)
}
else
{
thread_sched(FALSE);
arch_to_sche(); //!< 触发调度中断
}
// printk("suspend: cpu:%d sp:0x%lx\n", arch_get_current_cpu_id(), th->sp.sp);
// printk("suspend: th:0x%lx\n", th);
cpulock_set(status);
}
/**
@@ -408,6 +412,7 @@ bool_t thread_sched(bool_t is_sche)
sched_t *next_sche = scheduler_next();
thread_t *th = thread_get_current();
assert(next_sche);
assert(th->magic == THREAD_MAGIC);
if (next_sche == &th->sche)
{
@@ -489,8 +494,10 @@ void thread_ready(thread_t *th, bool_t is_sche)
}
else
{
thread_sched(FALSE);
arch_to_sche();
}
// printk("ready: th:0x%lx\n", th);
cpulock_set(status);
}
void thread_todead(thread_t *th, bool_t is_sche)
@@ -771,9 +778,8 @@ static int thread_del_wait_send_handler(ipi_msg_t *msg, bool_t *is_sched)
int thread_del_wait_send_remote(thread_wait_entry_t *wait)
{
assert(cpulock_get_status() == TRUE);
#if IS_ENABLED(CONFIG_SMP)
thread_t *th = wait->th;
#if IS_ENABLED(CONFIG_SMP)
if (th->cpu != arch_get_current_cpu_id())
{
th->ipi_msg_node.msg = (umword_t)wait;
@@ -781,6 +787,7 @@ int thread_del_wait_send_remote(thread_wait_entry_t *wait)
cpu_ipi_to_msg(1 << th->cpu, &th->ipi_msg_node, IPI_CALL);
}
else
#endif
{
if (slist_in_list(&wait->node_timeout))
{
@@ -788,13 +795,6 @@ int thread_del_wait_send_remote(thread_wait_entry_t *wait)
}
thread_ready(th, FALSE);
}
#else
if (slist_in_list(&wait->node_timeout))
{
slist_del(&wait->node_timeout);
}
thread_ready(wait->th, TRUE);
#endif
return 0;
}
/**
@@ -876,11 +876,11 @@ static int thread_ipc_recv(msg_tag_t *ret_msg, ipc_timeout_t timeout,
thread_set_ipc_state(cur_th, THREAD_RECV);
thread_suspend_sw(cur_th, FALSE);
spinlock_set(&cur_th->recv_lock, lock_status2);
preemption(); //!< 进行调度
#if THREAD_IS_DEBUG
dbg_printk(TAG "%s:%d ipc recv wait: %s[0x%x] status:%d ipc_status:%d recv_obj:0x%x\n", __func__, __LINE__,
kobject_get_name(&cur_th->kobj), cur_th, cur_th->status, cur_th->ipc_status, recv_obj);
#endif
preemption(); //!< 进行调度
assert(cur_th->status == THREAD_READY);
// cur_th->has_wait_send_th = FALSE;
#if THREAD_IS_DEBUG
@@ -1017,6 +1017,7 @@ static int thread_remote_suspend_handler(ipi_msg_t *msg, bool_t *is_sched)
#endif
int thread_suspend_remote(thread_t *th, bool_t is_sche)
{
assert(cpulock_get_status());
#if IS_ENABLED(CONFIG_SMP)
if (th->cpu != arch_get_current_cpu_id())
{
@@ -1029,7 +1030,7 @@ int thread_suspend_remote(thread_t *th, bool_t is_sche)
thread_suspend_sw(th, is_sche);
}
#else
thread_suspend_sw(th);
thread_suspend_sw(th, is_sche);
#endif
return 0;
}
@@ -1050,7 +1051,9 @@ static int thread_wait_recv_thread(thread_t *recv_th, ipc_timeout_t timeout)
again_check:
lock_status = spinlock_lock(&recv_th->recv_lock);
if ((thread_get_status(recv_th) != THREAD_SUSPEND || thread_get_ipc_state(recv_th) != THREAD_RECV) || recv_th->has_wait_send_th == FALSE /*如果已经在有人准备从这个线程获取数据则当前call者需要挂起*/)
if ((thread_get_status(recv_th) != THREAD_SUSPEND ||
thread_get_ipc_state(recv_th) != THREAD_RECV) ||
recv_th->has_wait_send_th == FALSE /*如果已经在有人准备从这个线程获取数据则当前call者需要挂起*/)
{
thread_wait_entry_t wait;
@@ -1110,7 +1113,6 @@ __attribute__((optimize(0))) int thread_ipc_call(
}
thread_t *cur_th = thread_get_current();
thread_t *recv_kobj = to_th;
mword_t lock_stats;
mword_t lock_stats2;
#if THREAD_IS_DEBUG
@@ -1167,7 +1169,6 @@ again:
}
else
{
thread_timeout_del_recv_remote(recv_kobj, TRUE);
#if THREAD_IS_DEBUG
dbg_printk(TAG "%s:%d ipc call wake: %s[0x%x]\n", __func__, __LINE__,
@@ -1436,10 +1437,12 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p,
if (!slist_in_list(&tag_th->sche.node))
{
thread_ready(tag_th, TRUE);
}
else
{
thread_suspend(tag_th);
preemption();
tag_th->sche.prio =
(tge_prio >= PRIO_MAX ? PRIO_MAX - 1 : tge_prio);
thread_ready(tag_th, TRUE);

View File

@@ -182,8 +182,8 @@ void task_knl_kill(thread_t *kill_thread, bool_t is_knl)
printk("kill task:0x%x, pid:%d\n", task, task->pid);
umword_t status2;
thread_suspend(kill_thread);
status2 = spinlock_lock(&del_lock);
thread_suspend(kill_thread);
slist_add_append(&del_task_head, &task->del_node);
spinlock_set(&del_lock, status2);
} else {

View File

@@ -10,6 +10,12 @@
*/
#include "types.h"
/**
* @brief 获取x的最低有效位
*
* @param x 需要获取最低有效位的数
* @return int 最低有效位的位置
*/
int ffs(int x)
{
int ret;
@@ -21,6 +27,12 @@ int ffs(int x)
ret = (WORD_BITS - 1) - ret;
return ret;
}
/**
* @brief 获取x的前导零的个数
*
* @param x 需要获取前导零的个数的数
* @return int 前导零的个数
*/
int clz(umword_t x)
{
int ret;

View File

@@ -11,6 +11,12 @@ export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/ar
export BOARD=STM32F205
export CROSS_COMPILE_NAME=arm-none-eabi-
set -e
if [ -z "$1" ]; then
export MKRTOS_TEST_MODE="normal"
else
export MKRTOS_TEST_MODE=$1
fi
set -e -x
cmake -G Ninja -B build/$KNL .
cd build/$KNL && ninja

View File

@@ -12,7 +12,12 @@ export TOOLCHAIN_LIB=/Applications/ArmGNUToolchain/11.3.rel1/aarch64-none-elf/li
# export TOOLCHAIN_LIB=/home/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/lib/gcc/aarch64-none-elf/10.3.1
export BOARD=aarch64_qemu
export CROSS_COMPILE_NAME=aarch64-none-elf-
if [ -z "$1" ]; then
export MKRTOS_TEST_MODE="normal"
else
export MKRTOS_TEST_MODE=$1
fi
set -e
set -e -x
cmake -G Ninja -B build/$KNL .
cd build/$KNL && ninja

49
mkrtos_script/build_test.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/bash
set -e
# 定义超时时间(秒)
TIMEOUT=30
# 定义成功标志
SUCCESS_MSG="MKRTOS test ok."
# 运行命令并检查输出的函数
run_and_check() {
local cmd="$1"
local timeout="$2"
echo "Running: $cmd"
# 使用管道和 grep 来监听输出
timeout --preserve-status --foreground $timeout $cmd | while IFS= read -r line
do
echo "$line"
if [[ "$line" == *"$SUCCESS_MSG"* ]]; then
echo "Success message detected. Exiting..."
kill -INT $$
return 0;
fi
done
# 检查 timeout 命令的退出状态
if [ $? -eq 124 ]; then
echo "Test timed out: $cmd"
exit -1
fi
return 0
}
# 清理
./mkrtos_script/clean.sh
./mkrtos_script/build_qemu_aarch64.sh test
# 运行测试
run_and_check "./mkrtos_script/run_aarch64_qemu.sh" "$TIMEOUT"
./mkrtos_script/clean.sh
./mkrtos_script/build_f2.sh test
run_and_check "./mkrtos_script/run_m3.sh" "$TIMEOUT"
# ./mkrtos_script/clean.sh
# run_and_check "./mkrtos_script/build_swm34s.sh test" "$TIMEOUT"
echo "All tests completed."

View File

@@ -1,4 +1,4 @@
#!/bin/bash
set -e
# set -e
rm -r $PWD/build

View File

@@ -1,6 +1,6 @@
#!/bin/bash
# netduino2
if [ -z "$1"]; then
if [ -z "$1" ]; then
echo "请输入板卡名字,使用默认板卡:"
echo "netduino2"
set $1 "netduino2"

View File

@@ -11,16 +11,21 @@
* CuStr
*-------------------------------------------------------------------------*/
char* CuStrAlloc(int size)
char *CuStrAlloc(int size)
{
char* newStr = (char*) malloc( sizeof(char) * (size) );
char *newStr = (char *)malloc(sizeof(char) * (size));
if (newStr == NULL)
{
printf("malloc failed\n");
exit(1);
}
return newStr;
}
char* CuStrCopy(const char* old)
char *CuStrCopy(const char *old)
{
int len = strlen(old);
char* newStr = CuStrAlloc(len + 1);
char *newStr = CuStrAlloc(len + 1);
strcpy(newStr, old);
return newStr;
}
@@ -29,42 +34,64 @@ char* CuStrCopy(const char* old)
* CuString
*-------------------------------------------------------------------------*/
void CuStringInit(CuString* str)
void CuStringInit(CuString *str)
{
str->length = 0;
str->size = STRING_MAX;
str->buffer = (char*) malloc(sizeof(char) * str->size);
str->buffer = (char *)malloc(sizeof(char) * str->size);
if (str->buffer == NULL)
{
printf("malloc failed\n");
exit(1);
}
str->buffer[0] = '\0';
}
CuString* CuStringNew(void)
CuString *CuStringNew(void)
{
CuString* str = (CuString*) malloc(sizeof(CuString));
CuString *str = (CuString *)malloc(sizeof(CuString));
if (str == NULL)
{
printf("malloc failed\n");
exit(1);
}
str->length = 0;
str->size = STRING_MAX;
str->buffer = (char*) malloc(sizeof(char) * str->size);
str->buffer = (char *)malloc(sizeof(char) * str->size);
if (str->buffer == NULL)
{
printf("malloc failed\n");
exit(1);
}
str->buffer[0] = '\0';
return str;
}
void CuStringDelete(CuString *str)
{
if (!str) return;
free(str->buffer);
free(str);
if (!str)
return;
free(str->buffer);
free(str);
}
void CuStringResize(CuString* str, int newSize)
void CuStringResize(CuString *str, int newSize)
{
str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize);
str->buffer = (char *)realloc(str->buffer, sizeof(char) * newSize);
if (str->buffer == NULL)
{
printf("realloc failed\n");
exit(1);
}
str->size = newSize;
}
void CuStringAppend(CuString* str, const char* text)
void CuStringAppend(CuString *str, const char *text)
{
int length;
if (text == NULL) {
if (text == NULL)
{
text = "NULL";
}
@@ -75,7 +102,7 @@ void CuStringAppend(CuString* str, const char* text)
strcat(str->buffer, text);
}
void CuStringAppendChar(CuString* str, char ch)
void CuStringAppendChar(CuString *str, char ch)
{
char text[2];
text[0] = ch;
@@ -83,7 +110,7 @@ void CuStringAppendChar(CuString* str, char ch)
CuStringAppend(str, text);
}
void CuStringAppendFormat(CuString* str, const char* format, ...)
void CuStringAppendFormat(CuString *str, const char *format, ...)
{
va_list argp;
char buf[HUGE_STRING_LEN];
@@ -93,7 +120,7 @@ void CuStringAppendFormat(CuString* str, const char* format, ...)
CuStringAppend(str, buf);
}
void CuStringInsert(CuString* str, const char* text, int pos)
void CuStringInsert(CuString *str, const char *text, int pos)
{
int length = strlen(text);
if (pos > str->length)
@@ -109,7 +136,7 @@ void CuStringInsert(CuString* str, const char* text, int pos)
* CuTest
*-------------------------------------------------------------------------*/
void CuTestInit(CuTest* t, const char* name, TestFunction function)
void CuTestInit(CuTest *t, const char *name, TestFunction function)
{
t->name = CuStrCopy(name);
t->failed = 0;
@@ -119,21 +146,22 @@ void CuTestInit(CuTest* t, const char* name, TestFunction function)
t->jumpBuf = NULL;
}
CuTest* CuTestNew(const char* name, TestFunction function)
CuTest *CuTestNew(const char *name, TestFunction function)
{
CuTest* tc = CU_ALLOC(CuTest);
CuTest *tc = CU_ALLOC(CuTest);
CuTestInit(tc, name, function);
return tc;
}
void CuTestDelete(CuTest *t)
{
if (!t) return;
free(t->name);
free(t);
if (!t)
return;
free(t->name);
free(t);
}
void CuTestRun(CuTest* tc)
void CuTestRun(CuTest *tc)
{
jmp_buf buf;
tc->jumpBuf = &buf;
@@ -145,7 +173,7 @@ void CuTestRun(CuTest* tc)
tc->jumpBuf = 0;
}
static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string)
static void CuFailInternal(CuTest *tc, const char *file, int line, CuString *string)
{
char buf[HUGE_STRING_LEN];
@@ -154,15 +182,16 @@ static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* str
tc->failed = 1;
tc->message = string->buffer;
if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0);
if (tc->jumpBuf != 0)
longjmp(*(tc->jumpBuf), 0);
}
void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message)
void CuFail_Line(CuTest *tc, const char *file, int line, const char *message2, const char *message)
{
CuString string;
CuStringInit(&string);
if (message2 != NULL)
if (message2 != NULL)
{
CuStringAppend(&string, message2);
CuStringAppend(&string, ": ");
@@ -171,25 +200,26 @@ void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, c
CuFailInternal(tc, file, line, &string);
}
void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition)
void CuAssert_Line(CuTest *tc, const char *file, int line, const char *message, int condition)
{
if (condition) return;
if (condition)
return;
CuFail_Line(tc, file, line, NULL, message);
}
void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
const char* expected, const char* actual)
void CuAssertStrEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message,
const char *expected, const char *actual)
{
CuString string;
if ((expected == NULL && actual == NULL) ||
(expected != NULL && actual != NULL &&
strcmp(expected, actual) == 0))
(expected != NULL && actual != NULL &&
strcmp(expected, actual) == 0))
{
return;
}
CuStringInit(&string);
if (message != NULL)
if (message != NULL)
{
CuStringAppend(&string, message);
CuStringAppend(&string, ": ");
@@ -202,114 +232,118 @@ void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const cha
CuFailInternal(tc, file, line, &string);
}
void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
int expected, int actual)
void CuAssertIntEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message,
int expected, int actual)
{
char buf[STRING_MAX];
if (expected == actual) return;
if (expected == actual)
return;
sprintf(buf, "expected <%d> but was <%d>", expected, actual);
CuFail_Line(tc, file, line, message, buf);
}
void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
double expected, double actual, double delta)
void CuAssertDblEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message,
double expected, double actual, double delta)
{
char buf[STRING_MAX];
if (fabs(expected - actual) <= delta) return;
/* sprintf(buf, "expected <%lf> but was <%lf>", expected, actual); */
sprintf(buf, "expected <%f> but was <%f>", expected, actual);
if (fabs(expected - actual) <= delta)
return;
/* sprintf(buf, "expected <%lf> but was <%lf>", expected, actual); */
sprintf(buf, "expected <%f> but was <%f>", expected, actual);
CuFail_Line(tc, file, line, message, buf);
}
void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
void* expected, void* actual)
void CuAssertPtrEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message,
void *expected, void *actual)
{
char buf[STRING_MAX];
if (expected == actual) return;
if (expected == actual)
return;
sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual);
CuFail_Line(tc, file, line, message, buf);
}
/*-------------------------------------------------------------------------*
* CuSuite
*-------------------------------------------------------------------------*/
void CuSuiteInit(CuSuite* testSuite)
void CuSuiteInit(CuSuite *testSuite)
{
testSuite->count = 0;
testSuite->failCount = 0;
memset(testSuite->list, 0, sizeof(testSuite->list));
memset(testSuite->list, 0, sizeof(testSuite->list));
}
CuSuite* CuSuiteNew(void)
CuSuite *CuSuiteNew(void)
{
CuSuite* testSuite = CU_ALLOC(CuSuite);
CuSuite *testSuite = CU_ALLOC(CuSuite);
CuSuiteInit(testSuite);
return testSuite;
}
void CuSuiteDelete(CuSuite *testSuite)
{
unsigned int n;
for (n=0; n < MAX_TEST_CASES; n++)
{
if (testSuite->list[n])
{
CuTestDelete(testSuite->list[n]);
}
}
free(testSuite);
unsigned int n;
for (n = 0; n < MAX_TEST_CASES; n++)
{
if (testSuite->list[n])
{
CuTestDelete(testSuite->list[n]);
}
}
free(testSuite);
}
void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
void CuSuiteAdd(CuSuite *testSuite, CuTest *testCase)
{
assert(testSuite->count < MAX_TEST_CASES);
testSuite->list[testSuite->count] = testCase;
testSuite->count++;
}
void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
void CuSuiteAddSuite(CuSuite *testSuite, CuSuite *testSuite2)
{
int i;
for (i = 0 ; i < testSuite2->count ; ++i)
for (i = 0; i < testSuite2->count; ++i)
{
CuTest* testCase = testSuite2->list[i];
CuTest *testCase = testSuite2->list[i];
CuSuiteAdd(testSuite, testCase);
}
}
void CuSuiteRun(CuSuite* testSuite)
void CuSuiteRun(CuSuite *testSuite)
{
int i;
for (i = 0 ; i < testSuite->count ; ++i)
for (i = 0; i < testSuite->count; ++i)
{
CuTest* testCase = testSuite->list[i];
CuTest *testCase = testSuite->list[i];
printf("=======TEST [%s] start=======\n", testCase->name);
CuTestRun(testCase);
if (testCase->failed) {
testSuite->failCount += 1;
if (testCase->failed)
{
testSuite->failCount += 1;
printf("=======TEST [%s] failed=======\n", testCase->name);
} else {
}
else
{
printf("=======TEST [%s] sucess=======\n", testCase->name);
}
}
}
void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
void CuSuiteSummary(CuSuite *testSuite, CuString *summary)
{
int i;
for (i = 0 ; i < testSuite->count ; ++i)
for (i = 0; i < testSuite->count; ++i)
{
CuTest* testCase = testSuite->list[i];
CuTest *testCase = testSuite->list[i];
CuStringAppend(summary, testCase->failed ? "F" : ".");
}
CuStringAppend(summary, "\n\n");
}
void CuSuiteDetails(CuSuite* testSuite, CuString* details)
void CuSuiteDetails(CuSuite *testSuite, CuString *details)
{
int i;
int failCount = 0;
@@ -317,7 +351,7 @@ void CuSuiteDetails(CuSuite* testSuite, CuString* details)
if (testSuite->failCount == 0)
{
int passCount = testSuite->count - testSuite->failCount;
const char* testWord = passCount == 1 ? "test" : "tests";
const char *testWord = passCount == 1 ? "test" : "tests";
CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
}
else
@@ -327,20 +361,20 @@ void CuSuiteDetails(CuSuite* testSuite, CuString* details)
else
CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount);
for (i = 0 ; i < testSuite->count ; ++i)
for (i = 0; i < testSuite->count; ++i)
{
CuTest* testCase = testSuite->list[i];
CuTest *testCase = testSuite->list[i];
if (testCase->failed)
{
failCount++;
CuStringAppendFormat(details, "%d) %s: %s\n",
failCount, testCase->name, testCase->message);
failCount, testCase->name, testCase->message);
}
}
CuStringAppend(details, "\n!!!FAILURES!!!\n");
CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount);
CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount);
}
}

View File

@@ -6,31 +6,31 @@
/* CuString */
char* CuStrAlloc(int size);
char* CuStrCopy(const char* old);
char *CuStrAlloc(int size);
char *CuStrCopy(const char *old);
#define CU_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE)))
#define CU_ALLOC(TYPE) ((TYPE *)malloc(sizeof(TYPE)))
#define HUGE_STRING_LEN 8192
#define STRING_MAX 256
#define STRING_INC 256
#define HUGE_STRING_LEN 8192
#define STRING_MAX 256
#define STRING_INC 256
typedef struct
{
int length;
int size;
char* buffer;
char *buffer;
} CuString;
void CuStringInit(CuString* str);
CuString* CuStringNew(void);
void CuStringRead(CuString* str, const char* path);
void CuStringAppend(CuString* str, const char* text);
void CuStringAppendChar(CuString* str, char ch);
void CuStringAppendFormat(CuString* str, const char* format, ...);
void CuStringInsert(CuString* str, const char* text, int pos);
void CuStringResize(CuString* str, int newSize);
void CuStringDelete(CuString* str);
void CuStringInit(CuString *str);
CuString *CuStringNew(void);
void CuStringRead(CuString *str, const char *path);
void CuStringAppend(CuString *str, const char *text);
void CuStringAppendChar(CuString *str, char ch);
void CuStringAppendFormat(CuString *str, const char *format, ...);
void CuStringInsert(CuString *str, const char *text, int pos);
void CuStringResize(CuString *str, int newSize);
void CuStringDelete(CuString *str);
/* CuTest */
@@ -40,75 +40,74 @@ typedef void (*TestFunction)(CuTest *);
struct CuTest
{
char* name;
char *name;
TestFunction function;
int failed;
int ran;
const char* message;
const char *message;
jmp_buf *jumpBuf;
};
void CuTestInit(CuTest* t, const char* name, TestFunction function);
CuTest* CuTestNew(const char* name, TestFunction function);
void CuTestRun(CuTest* tc);
void CuTestInit(CuTest *t, const char *name, TestFunction function);
CuTest *CuTestNew(const char *name, TestFunction function);
void CuTestRun(CuTest *tc);
void CuTestDelete(CuTest *t);
/* Internal versions of assert functions -- use the public versions */
void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message);
void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition);
void CuAssertStrEquals_LineMsg(CuTest* tc,
const char* file, int line, const char* message,
const char* expected, const char* actual);
void CuAssertIntEquals_LineMsg(CuTest* tc,
const char* file, int line, const char* message,
int expected, int actual);
void CuAssertDblEquals_LineMsg(CuTest* tc,
const char* file, int line, const char* message,
double expected, double actual, double delta);
void CuAssertPtrEquals_LineMsg(CuTest* tc,
const char* file, int line, const char* message,
void* expected, void* actual);
void CuFail_Line(CuTest *tc, const char *file, int line, const char *message2, const char *message);
void CuAssert_Line(CuTest *tc, const char *file, int line, const char *message, int condition);
void CuAssertStrEquals_LineMsg(CuTest *tc,
const char *file, int line, const char *message,
const char *expected, const char *actual);
void CuAssertIntEquals_LineMsg(CuTest *tc,
const char *file, int line, const char *message,
int expected, int actual);
void CuAssertDblEquals_LineMsg(CuTest *tc,
const char *file, int line, const char *message,
double expected, double actual, double delta);
void CuAssertPtrEquals_LineMsg(CuTest *tc,
const char *file, int line, const char *message,
void *expected, void *actual);
/* public assert functions */
#define CuFail(tc, ms) CuFail_Line( (tc), __FILE__, __LINE__, NULL, (ms))
#define CuAssert(tc, ms, cond) CuAssert_Line((tc), __FILE__, __LINE__, (ms), (cond))
#define CuAssertTrue(tc, cond) CuAssert_Line((tc), __FILE__, __LINE__, "assert failed", (cond))
#define CuFail(tc, ms) CuFail_Line((tc), __FILE__, __LINE__, NULL, (ms))
#define CuAssert(tc, ms, cond) CuAssert_Line((tc), __FILE__, __LINE__, (ms), (cond))
#define CuAssertTrue(tc, cond) CuAssert_Line((tc), __FILE__, __LINE__, "assert failed", (cond))
#define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac))
#define CuAssertStrEquals_Msg(tc,ms,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac))
#define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac))
#define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac))
#define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl))
#define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl))
#define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac))
#define CuAssertPtrEquals_Msg(tc,ms,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac))
#define CuAssertStrEquals(tc, ex, ac) CuAssertStrEquals_LineMsg((tc), __FILE__, __LINE__, NULL, (ex), (ac))
#define CuAssertStrEquals_Msg(tc, ms, ex, ac) CuAssertStrEquals_LineMsg((tc), __FILE__, __LINE__, (ms), (ex), (ac))
#define CuAssertIntEquals(tc, ex, ac) CuAssertIntEquals_LineMsg((tc), __FILE__, __LINE__, NULL, (ex), (ac))
#define CuAssertIntEquals_Msg(tc, ms, ex, ac) CuAssertIntEquals_LineMsg((tc), __FILE__, __LINE__, (ms), (ex), (ac))
#define CuAssertDblEquals(tc, ex, ac, dl) CuAssertDblEquals_LineMsg((tc), __FILE__, __LINE__, NULL, (ex), (ac), (dl))
#define CuAssertDblEquals_Msg(tc, ms, ex, ac, dl) CuAssertDblEquals_LineMsg((tc), __FILE__, __LINE__, (ms), (ex), (ac), (dl))
#define CuAssertPtrEquals(tc, ex, ac) CuAssertPtrEquals_LineMsg((tc), __FILE__, __LINE__, NULL, (ex), (ac))
#define CuAssertPtrEquals_Msg(tc, ms, ex, ac) CuAssertPtrEquals_LineMsg((tc), __FILE__, __LINE__, (ms), (ex), (ac))
#define CuAssertPtrNotNull(tc,p) CuAssert_Line((tc),__FILE__,__LINE__,"null pointer unexpected",(p != NULL))
#define CuAssertPtrNotNullMsg(tc,msg,p) CuAssert_Line((tc),__FILE__,__LINE__,(msg),(p != NULL))
#define CuAssertPtrNotNull(tc, p) CuAssert_Line((tc), __FILE__, __LINE__, "null pointer unexpected", (p != NULL))
#define CuAssertPtrNotNullMsg(tc, msg, p) CuAssert_Line((tc), __FILE__, __LINE__, (msg), (p != NULL))
/* CuSuite */
#define MAX_TEST_CASES 1024
#define MAX_TEST_CASES 128
#define SUITE_ADD_TEST(SUITE,TEST) CuSuiteAdd(SUITE, CuTestNew(#TEST, TEST))
#define SUITE_ADD_TEST(SUITE, TEST) CuSuiteAdd(SUITE, CuTestNew(#TEST, TEST))
typedef struct
{
int count;
CuTest* list[MAX_TEST_CASES];
CuTest *list[MAX_TEST_CASES];
int failCount;
} CuSuite;
void CuSuiteInit(CuSuite* testSuite);
CuSuite* CuSuiteNew(void);
void CuSuiteInit(CuSuite *testSuite);
CuSuite *CuSuiteNew(void);
void CuSuiteDelete(CuSuite *testSuite);
void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase);
void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2);
void CuSuiteRun(CuSuite* testSuite);
void CuSuiteSummary(CuSuite* testSuite, CuString* summary);
void CuSuiteDetails(CuSuite* testSuite, CuString* details);
void CuSuiteAdd(CuSuite *testSuite, CuTest *testCase);
void CuSuiteAddSuite(CuSuite *testSuite, CuSuite *testSuite2);
void CuSuiteRun(CuSuite *testSuite);
void CuSuiteSummary(CuSuite *testSuite, CuString *summary);
void CuSuiteDetails(CuSuite *testSuite, CuString *details);
#endif /* CU_TEST_H */

View File

@@ -6,14 +6,17 @@
#include "u_app.h"
#include "cons_cli.h"
#include "u_arch.h"
#include "u_mutex.h"
#include "u_hd_man.h"
#include <pthread_impl.h>
#include <assert.h>
static pthread_spinlock_t lock;
static int lock_is_init;
static u_mutex_t lock;
extern void *app_start_addr;
#ifdef CONFIG_EX_RAM_SIZE
static umword_t mm_bitemp[ROUND(CONFIG_EX_RAM_SIZE, MK_PAGE_SIZE) / (sizeof(umword_t) * 8) + 1];
static umword_t mm_bitmap[ROUND(CONFIG_EX_RAM_SIZE, MK_PAGE_SIZE) / (sizeof(umword_t) * 8) + 1];
#else
static umword_t mm_bitemp[ROUND(CONFIG_KNL_DATA_SIZE, MK_PAGE_SIZE) / (sizeof(umword_t) * 8) + 1];
static umword_t mm_bitmap[ROUND(CONFIG_KNL_DATA_SIZE, MK_PAGE_SIZE) / (sizeof(umword_t) * 8) + 1];
#endif
static void *mm_page_alloc(int page_nr)
{
@@ -28,19 +31,32 @@ static void *mm_page_alloc(int page_nr)
{
return NULL;
}
if (max_page_nr > sizeof(mm_bitemp) * WORD_BITS)
if (max_page_nr > sizeof(mm_bitmap) * WORD_BITS)
{
cons_write_str("mm bitmap is to small.\n");
}
// printf("heap is 0x%x, max page nr is %d.\n", heap_addr, max_page_nr);
pthread_spin_lock(&lock);
if (!lock_is_init)
{
obj_handler_t mutex_hd;
mutex_hd = handler_alloc();
if (mutex_hd == HANDLER_INVALID)
{
cons_write_str("mutex_hd alloc failed.\n");
assert(0);
}
u_mutex_init(&lock, handler_alloc());
lock_is_init = 1;
}
u_mutex_lock(&lock);
for (umword_t i = 0; i < ROUND_UP(max_page_nr, WORD_BITS); i++)
{
if (mm_bitemp[i] != (umword_t)(-1))
if (mm_bitmap[i] != (umword_t)(-1))
{
for (int j = 0; j < WORD_BITS; j++)
{
if (MK_GET_BIT(mm_bitemp[i], j) == 0)
if (MK_GET_BIT(mm_bitmap[i], j) == 0)
{
// 找到空闲的
if (find_inx == -1)
@@ -50,7 +66,7 @@ static void *mm_page_alloc(int page_nr)
cnt++;
if (find_inx + cnt > max_page_nr)
{
pthread_spin_unlock(&lock);
u_mutex_unlock(&lock);
return NULL;
}
if (cnt >= page_nr)
@@ -58,9 +74,9 @@ static void *mm_page_alloc(int page_nr)
for (int m = find_inx; m < find_inx + cnt; m++)
{
MK_SET_BIT(mm_bitemp[m / WORD_BITS], m % WORD_BITS);
MK_SET_BIT(mm_bitmap[m / WORD_BITS], m % WORD_BITS);
}
pthread_spin_unlock(&lock);
u_mutex_unlock(&lock);
// printf("st_inx:%d, cnt:%d\n", find_inx, cnt);
return find_inx * PAGE_SIZE + (char *)heap_addr;
}
@@ -73,7 +89,7 @@ static void *mm_page_alloc(int page_nr)
}
}
}
pthread_spin_unlock(&lock);
u_mutex_unlock(&lock);
return NULL;
}
@@ -85,12 +101,12 @@ static void mm_page_free(int st, int nr)
void *heap_addr = (void *)((umword_t)TASK_RAM_BASE() + info->i.heap_offset - info->i.data_offset);
size_t max_page_nr = (info->i.heap_size) / PAGE_SIZE;
pthread_spin_lock(&lock);
u_mutex_lock(&lock);
for (int i = st; (i < st + nr) && (i < max_page_nr); i++)
{
MK_CLR_BIT(mm_bitemp[i / WORD_BITS], i % WORD_BITS);
MK_CLR_BIT(mm_bitmap[i / WORD_BITS], i % WORD_BITS);
}
pthread_spin_unlock(&lock);
u_mutex_unlock(&lock);
}
static int _sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_t _offset, umword_t *addr)
@@ -152,7 +168,7 @@ umword_t be_munmap(void *start, size_t len)
// printf("munmap 0x%x, 0x%x.\n", start, len);
mm_page_free(((umword_t)(start) - (umword_t)heap_addr) / PAGE_SIZE, len / PAGE_SIZE);
}
long sys_munmap(va_list ap)
long sys_munmap(va_list ap)
{
void *start;
size_t len;

View File

@@ -7,6 +7,7 @@
#include "u_log.h"
#include "u_thread.h"
#include "u_sys.h"
#include "cons_cli.h"
#include <errno.h>
#include <u_sleep.h>
#undef hidden
@@ -62,6 +63,10 @@ unsigned long get_thread_area(void)
thread_msg_buf_get(-1, &msg, &len);
i_msg = (ipc_msg_t *)msg;
if (i_msg->user[0] == 0)
{
cons_write_str("get_thread_area failed\n");
}
return i_msg->user[0];
}

View File

@@ -42,8 +42,6 @@
static int pthread_cnt = 1;
#define PTHREAD_DONT_RUN 0x1
#define THREAD_USED_NEW_BUF 0x1
void pthread_cnt_inc(void)
{
a_inc(&pthread_cnt);
@@ -94,7 +92,7 @@ int be_clone(int (*func)(void *), void *stack, int flags, void *args, pid_t *pti
}
umword_t msg_buf_addr;
#if THREAD_USED_NEW_BUF
#if IS_ENABLED(CONFIG_MMU)
tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RW, 0, 0),
PAGE_SIZE, 0, (addr_t *)(&msg_buf_addr));
if (msg_tag_get_val(tag) < 0)
@@ -143,7 +141,7 @@ int be_clone(int (*func)(void *), void *stack, int flags, void *args, pid_t *pti
ret = 0;
goto end_ok;
end_free_mm:
#if THREAD_USED_NEW_BUF
#if IS_ENABLED(CONFIG_MMU)
u_vmam_free(VMA_PROT, msg_buf_addr, PAGE_SIZE);
#endif
end:

View File

@@ -23,12 +23,12 @@ longjmp:
// HWCAP_ARM_FPA
tst r1,#0x20
beq 2f
ldc p2, cr4, [ip], #48
// ldc p2, cr4, [ip], #48
#endif
2: tst r1,#0x40
beq 2f
.fpu vfp
vldmia ip!, {d8-d15}
// .fpu vfp
// vldmia ip!, {d8-d15}
.fpu softvfp
.eabi_attribute 10, 0
.eabi_attribute 27, 0
@@ -36,12 +36,12 @@ longjmp:
// HWCAP_ARM_IWMMXT
2: tst r1,#0x200
beq 3f
ldcl p1, cr10, [ip], #8
ldcl p1, cr11, [ip], #8
ldcl p1, cr12, [ip], #8
ldcl p1, cr13, [ip], #8
ldcl p1, cr14, [ip], #8
ldcl p1, cr15, [ip], #8
// ldcl p1, cr10, [ip], #8
// ldcl p1, cr11, [ip], #8
// ldcl p1, cr12, [ip], #8
// ldcl p1, cr13, [ip], #8
// ldcl p1, cr14, [ip], #8
// ldcl p1, cr15, [ip], #8
#endif
2:
3: bx lr

View File

@@ -24,12 +24,12 @@ setjmp:
// HWCAP_ARM_FPA
tst r1,#0x20
beq 2f
stc p2, cr4, [ip], #48
// stc p2, cr4, [ip], #48
#endif
2: tst r1,#0x40
beq 2f
.fpu vfp
vstmia ip!, {d8-d15}
// .fpu vfp
// vstmia ip!, {d8-d15}
.fpu softvfp
.eabi_attribute 10, 0
.eabi_attribute 27, 0
@@ -37,12 +37,12 @@ setjmp:
// HWCAP_ARM_IWMMXT
2: tst r1,#0x200
beq 3f
stcl p1, cr10, [ip], #8
stcl p1, cr11, [ip], #8
stcl p1, cr12, [ip], #8
stcl p1, cr13, [ip], #8
stcl p1, cr14, [ip], #8
stcl p1, cr15, [ip], #8
// stcl p1, cr10, [ip], #8
// stcl p1, cr11, [ip], #8
// stcl p1, cr12, [ip], #8
// stcl p1, cr13, [ip], #8
// stcl p1, cr14, [ip], #8
// stcl p1, cr15, [ip], #8
#endif
2:
3: bx lr

View File

@@ -21,6 +21,9 @@ static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec
if (r == ETIMEDOUT || r == EINVAL) return r;
__tl_sync(t);
if (res) *res = t->result;
// TODO:和be_exit有一个原子性的错误
extern int usleep(unsigned useconds);
usleep(10000);
if (t->map_base) __munmap(t->map_base, t->map_size);
return 0;
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <u_types.h>
typedef struct u_mutex
{
obj_handler_t obj;
} u_mutex_t;
int u_mutex_init(u_mutex_t *lock, obj_handler_t sema_hd);
void u_mutex_lock(u_mutex_t *lock);
void u_mutex_unlock(u_mutex_t *lock);

View File

@@ -1,7 +1,7 @@
#pragma once
#include "u_prot.h"
#include "u_hd_man.h"
#include "u_types.h"
msg_tag_t u_sema_up(obj_handler_t obj);
msg_tag_t u_sema_down(obj_handler_t obj);

View File

@@ -46,3 +46,5 @@ typedef union mk_sd
#ifndef TRUE
#define TRUE (!(FALSE))
#endif
#define HANDLER_INVALID ((umword_t)(-1))

View File

@@ -0,0 +1,36 @@
#include "u_sema.h"
#include "u_mutex.h"
#include "u_types.h"
#include "u_prot.h"
#include "u_thread.h"
#include "u_task.h"
#include "u_factory.h"
/**
* @brief 创建一个mutex
*
* @param lock
* @return int
*/
int u_mutex_init(u_mutex_t *lock, obj_handler_t sema_hd)
{
msg_tag_t tag;
if (sema_hd == HANDLER_INVALID)
{
return -1;
}
tag = facotry_create_sema(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_hd), 1, 1);
if (msg_tag_get_val(tag) < 0)
{
return msg_tag_get_val(tag);
}
return 0;
}
void u_mutex_lock(u_mutex_t *lock)
{
u_sema_down(lock->obj);
}
void u_mutex_unlock(u_mutex_t *lock)
{
u_sema_up(lock->obj);
}

View File

@@ -1,7 +1,6 @@
#pragma once
#include "u_types.h"
#define HANDLER_INVALID ((umword_t)(-1))
obj_handler_t handler_alloc(void);
void handler_free(obj_handler_t hd_inx);

View File

@@ -243,13 +243,26 @@ int app_load(const char *name, uenv_t *cur_env, pid_t *pid, char *argv[], int ar
for (int i = 0; i < arg_cn; i++)
{
cp_args = app_stack_push_str(hd_task, &usp_top, argv[i]);
if ((ALIGN(strlen(argv[i]) + 1, sizeof(void *)) / sizeof(void *)) % 2)
{
app_stack_push_umword(hd_task, &usp_top, 0);
}
printf("app_load 1 cp_args:%p\n", cp_args);
}
for (int i = 0; i < envp_cn; i++)
{
cp_envp = app_stack_push_str(hd_task, &usp_top, envp[i]);
if ((ALIGN(strlen(argv[i]) + 1, sizeof(void *)) / sizeof(void *)) % 2)
{
app_stack_push_umword(hd_task, &usp_top, 0);
}
}
app_stack_push_umword(hd_task, &usp_top, 0);
if ((arg_cn + envp_cn) & 0x1) // 参数是奇数是,多添加一个
{
app_stack_push_umword(hd_task, &usp_top, 0);
}
app_stack_push_umword(hd_task, &usp_top, (umword_t)app_env);
app_stack_push_umword(hd_task, &usp_top, 0xfe);
@@ -262,12 +275,24 @@ int app_load(const char *name, uenv_t *cur_env, pid_t *pid, char *argv[], int ar
{
app_stack_push_umword(hd_task, &usp_top, (umword_t)cp_envp);
cp_envp += ALIGN(strlen(envp[i]), sizeof(void *));
if ((ALIGN(strlen(envp[i]) + 1, sizeof(void *)) / sizeof(void *)) % 2)
{
cp_envp += sizeof(void *);
}
}
if (arg_cn)
{
app_stack_push_umword(hd_task, &usp_top, 0);
for (int i = 0; i < arg_cn; i++)
{
if (i != 0)
{
if ((ALIGN(strlen(argv[i]) + 1, sizeof(void *)) / sizeof(void *)) % 2)
{
cp_args += sizeof(void *);
}
}
printf("app_load 2 cp_args:%p\n", cp_args);
app_stack_push_umword(hd_task, &usp_top, (umword_t)cp_args);
cp_args += ALIGN(strlen(argv[i]) + 1, sizeof(void *));
}

View File

@@ -33,8 +33,8 @@ elseif(${CONFIG_ARCH} STREQUAL "aarch64" )
endif()
add_subdirectory(init)
add_subdirectory(shell)
add_subdirectory(tinycc-arm-thumb)
# add_subdirectory(tinycc-arm-thumb)
add_subdirectory(fs)
add_subdirectory(drv)
add_subdirectory(net)
# add_subdirectory(drv)
# add_subdirectory(net)

View File

@@ -21,7 +21,7 @@ int net_drv_write(obj_handler_t obj, int len)
int ret = -1;
addr_t addr = 0;
umword_t size = 0;
msg_tag_t tag = share_mem_map(obj, 3, &addr, &size);
msg_tag_t tag = share_mem_map(obj, vma_addr_create(VPAGE_PROT_RWX, 0, 0), &addr, &size);
if (msg_tag_get_val(tag) < 0)
{
@@ -39,7 +39,7 @@ int net_drv_read(obj_handler_t obj, int len)
int ret = -1;
addr_t addr = 0;
umword_t size = 0;
msg_tag_t tag = share_mem_map(obj, 3, &addr, &size);
msg_tag_t tag = share_mem_map(obj, vma_addr_create(VPAGE_PROT_RWX, 0, 0), &addr, &size);
uint32_t _err;
// _err = sem_wait(&dm9000input); // 请求信号量

View File

@@ -2,5 +2,5 @@ cmake_minimum_required(VERSION 3.13)
add_subdirectory(cpiofs)
add_subdirectory(fatfs)
add_subdirectory(lxext4)
# add_subdirectory(fatfs)
# add_subdirectory(lxext4)

View File

@@ -11,16 +11,37 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main(int argv, char *args[])
#include <getopt.h>
int main(int argc, char *argv[])
{
obj_handler_t hd;
int ret;
printf("args[0]:%s\n", args[0]);
char *mount_path = NULL;
for (int i = 0; i < argc; i++)
{
printf("args[%d]:%s\n", i, argv[i]);
}
int o;
const char *optstring = "m:"; // 有三个选项-abc其中c选项后有冒号所以后面必须有参数
while ((o = getopt(argc, argv, optstring)) != -1)
{
switch (o)
{
case 'm':
printf("mount path:%s\n", optarg);
mount_path = optarg;
break;
case '?':
printf("error optopt: %c\n", optopt);
printf("error opterr: %d\n", opterr);
break;
}
}
ret = rpc_meta_init(THREAD_MAIN, &hd);
assert(ret >= 0);
fs_svr_init();
ns_register("/bin", hd, MOUNT_NODE);
ns_register(mount_path, hd, MOUNT_NODE);
cons_write_str("cpiofs mount success\n");
fs_svr_loop();

View File

@@ -3,6 +3,11 @@ cmake_minimum_required(VERSION 3.13)
file(GLOB deps src/*.c src/*.S src/test/*.c)
file(GLOB arch_src src/test/${ARCH_NAME}/*.c src/test/${ARCH_NAME}/*.S)
if (NOT $ENV{MKRTOS_TEST_MODE} STREQUAL "normal")
message(STATUS "MKRTOS_TEST_MODE is $ENV{MKRTOS_TEST_MODE}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMKRTOS_TEST_MODE" )
endif()
add_executable(init.elf
${deps}
${arch_src}

View File

@@ -10,8 +10,13 @@
* @copyright Copyright (c) 2023
*
*/
#define HEAP_SIZE 1024
#define STACK_SIZE (1024 + 256)
#ifdef MKRTOS_TEST_MODE
#define HEAP_SIZE (256 * 1024)
#define STACK_SIZE (4 * 1024) //(1024 + 256)
#else
#define HEAP_SIZE (2 * 1024)
#define STACK_SIZE (2 * 1024) //(1024 + 256)
#endif
#if defined(__CC_ARM)
#define HEAP_ATTR SECTION("HEAP") __attribute__((zero_init))

View File

@@ -33,37 +33,6 @@
#define DEFAULT_INIT_CFG "init.cfg"
static void test(void)
{
#if 0
test_main();
u_sema_test();
u_sema_test2();
ipi_test();
ipc_test();
ipc_test2();
thread_vcpu_test();
pthread_lock_test();
pthread_cond_lock_test();
thread_cpu_test();
malloc_test();
printf_test();
mpu_test();
sharea_mem_test();
ulog_test();
factory_test();
thread_exit_test();
map_test();
mm_test();
app_test();
thread_press_test();
kobj_create_press_test();
u_sleep_ms(1000);
ipc_obj_test();
ns_test();
#endif
}
int main(int argc, char *args[])
{
int ret;
@@ -79,8 +48,12 @@ int main(int argc, char *args[])
namespace_init(env->ns_hd);
pm_init();
console_init();
parse_cfg_init();
test();
#if defined(MKRTOS_TEST_MODE)
printf("test_main..\n");
test_main();
#endif
ret = parse_cfg(DEFAULT_INIT_CFG, env);
printf("run app num is %d.\n", ret);

View File

@@ -1,10 +1,10 @@
#一次读取一行,每行代表启动的应用程序,暂时不支持参数
cpiofs -m /bin
# fatfs
# dm9000_drv
# net
# lcd_drv
cpiofs
fatfs.elf
# fatfs.elf
# hello.elf
sh

View File

@@ -19,7 +19,70 @@
#include <string.h>
#include <sys/types.h>
#include <cons_svr.h>
#include <u_mutex.h>
#include <u_hd_man.h>
#define CMD_LEN 64 //!< 命令行最大长度
#define CMD_PARAMS_CN 8 //!< 参数个数
#define CMD_PARAMS_ITEM_LEN 16 //!< 每个参数的最大长度
static char cmd_line[CMD_LEN]; //!< 命令行
static char cmd_params[CMD_PARAMS_CN][CMD_PARAMS_ITEM_LEN]; //!< 参数数组
static int cmd_params_off[CMD_PARAMS_CN]; //!< 参数偏移量
static int cmd_params_num = 0; //!< 参数个数
static u_mutex_t cmd_lock; //!< 命令行锁
#if CMD_PARAMS_CN < 1
#error "CMD_PARAMS_CN must be greater than 1"
#endif
/**
* @brief 初始化命令行锁
*
*/
void parse_cfg_init(void)
{
u_mutex_init(&cmd_lock, handler_alloc());
}
/**
* @brief 解析命令行
*
*/
static void parse_cfg_cmd_line(void)
{
int cmd_params_inx = 0;
cmd_params_num = 0;
printf("cmd_line:%s\n", cmd_line);
for (int i = 0; i < sizeof(cmd_line) && cmd_line[i]; i++)
{
if (i == 0 && cmd_line[i] != ' ')
{
// 第一个参数
cmd_params_off[cmd_params_inx++] = i;
cmd_params_num++;
}
else if (cmd_line[i] == ' ')
{
// 下一个参数
cmd_params_off[cmd_params_inx++] = i + 1;
cmd_line[i] = 0;
cmd_params_num++;
if (cmd_params_inx >= CMD_PARAMS_CN)
{
// 参数个数超过最大值
break;
}
}
}
}
/**
* @brief 查找行结束位置
*
* @param str 字符串
* @param size 字符串长度
* @return int 行结束位置
*/
static int find_line_end(const char *str, size_t size)
{
for (int i = 0; i < size; i++)
@@ -31,27 +94,39 @@ static int find_line_end(const char *str, size_t size)
}
return size;
}
/**
* @brief 解析配置文件
*
* @param parse_cfg_file_name 配置文件名
* @param env 环境变量
* @return int 成功返回启动的应用个数,失败返回-1
*/
int parse_cfg(const char *parse_cfg_file_name, uenv_t *env)
{
int ret = 0;
int run_cn = 0;
msg_tag_t tag;
sys_info_t sys_info;
u_mutex_lock(&cmd_lock);
tag = sys_read_info(SYS_PROT, &sys_info, 0);
if (msg_tag_get_val(tag) < 0)
{
printf("read info is errno.\n");
return -ENOENT;
ret = -ENOENT;
goto out;
}
umword_t size;
int type;
const char *str;
int ret = cpio_find_file((umword_t)sys_info.bootfs_start_addr,
(umword_t)(-1), parse_cfg_file_name, &size, &type, (umword_t *)&str);
ret = cpio_find_file((umword_t)sys_info.bootfs_start_addr,
(umword_t)(-1), parse_cfg_file_name, &size, &type, (umword_t *)&str);
if (ret < 0 || (ret >= 0 && type == 1))
{
return -ENOENT;
ret = -ENOENT;
goto out;
}
for (int i = 0; i < size;)
{
@@ -61,26 +136,32 @@ int parse_cfg(const char *parse_cfg_file_name, uenv_t *env)
{
if (strlen(&str[i]) != 0 && str[i] != '\n')
{
char name[32];
strncpy(name, &str[i], MIN(line_inx, sizeof(name)));
strncpy(cmd_line, &str[i], MIN(line_inx, sizeof(cmd_line)));
if (line_inx + i >= size && str[i + line_inx - 1] != '\n')
{
name[MIN(line_inx + 1, sizeof(name)) - 1] = 0;
cmd_line[MIN(line_inx + 1, sizeof(cmd_line)) - 1] = 0;
}
else
{
name[MIN(line_inx, sizeof(name)) - 1] = 0;
cmd_line[MIN(line_inx, sizeof(cmd_line)) - 1] = 0;
}
pid_t pid;
char *args[] = {
name,
NULL
int params_cn = 0;
char *args[CMD_PARAMS_CN] = {
NULL,
};
int ret = app_load(name, env, &pid, args, 1, NULL, 0);
parse_cfg_cmd_line();
for (int i = 0; i < cmd_params_num; i++)
{
args[i] = &cmd_line[cmd_params_off[i]];
printf("parse_cfg args[%d] = %s\n", i, args[i]);
}
printf("parse_cfg cmd_params_num:%d\n", cmd_params_num);
int ret = app_load(cmd_line, env, &pid, args, cmd_params_num, NULL, 0);
if (ret < 0)
{
printf("%s load fail, 0x%x\n", name, ret);
printf("%s load fail, 0x%x\n", cmd_line, ret);
}
else
{
@@ -91,6 +172,12 @@ int parse_cfg(const char *parse_cfg_file_name, uenv_t *env)
}
i += line_inx;
}
out:
if (ret < 0)
{
printf("parse cfg file fail, ret:%d\n", ret);
return ret;
}
u_mutex_unlock(&cmd_lock);
return run_cn;
}

View File

@@ -12,4 +12,5 @@
#include <u_env.h>
void parse_cfg_init(void);
int parse_cfg(const char *parse_cfg_file_name, uenv_t *env);

View File

@@ -58,7 +58,7 @@ static void thread_test_func(void)
break;
}
}
printf("thread_test_func.\n");
// printf("thread_test_func.\n");
while (1)
{
u_sleep_ms(100000);
@@ -213,21 +213,20 @@ static void ipc_test(CuTest *cu)
tag = thread_run_cpu(th4_hd, 2, 0);
while (test_cn < 1000)
;
/*
TODO:存在bug
{
u_sleep_ms(10);
}
u_thread_del(th1_hd);
u_thread_del(th2_hd);
u_thread_del(th3_hd);
u_thread_del(th4_hd);
*/
printf("test_cn:%d.\n", test_cn);
}
static CuSuite suite;
CuSuite *ipc_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(&suite, ipc_test);
SUITE_ADD_TEST(suite, ipc_test);
return suite;
return &suite;
}

View File

@@ -18,11 +18,13 @@ static void ulog_test(CuTest *tc)
}
#endif
}
static CuSuite suite;
CuSuite *ulog_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, ulog_test);
SUITE_ADD_TEST(&suite, ulog_test);
return suite;
return &suite;
}

View File

@@ -7,7 +7,7 @@
static uint8_t *mem[1000];
static void malloc_test(CuTest *cu)
{
#define TEST_MEM_SIZE 1024 * 1024 * 1
#define TEST_MEM_SIZE (MK_PAGE_SIZE)
void *mem2 = malloc(TEST_MEM_SIZE);
printf("alloc mem 0x%lx\n", mem2);
@@ -16,33 +16,49 @@ static void malloc_test(CuTest *cu)
free(mem2);
printf("free mem 0x%lx\n", mem2);
#undef TEST_MEM_SIZE
#if IS_ENABLED(CONFIG_MMU)
#define TEST_MEM_SIZE 1024 * 1024 * 1
mem2 = malloc(TEST_MEM_SIZE);
printf("alloc mem 0x%lx\n", mem2);
for (int i = 0; i < 1000; i++)
CuAssert(cu, "malloc failed\n", mem2 != NULL);
memset(mem2, 0, TEST_MEM_SIZE);
free(mem2);
printf("free mem 0x%lx\n", mem2);
#undef TEST_MEM_SIZE
#endif
int i;
for (i = 0; i < 1000; i++)
{
mem[i] = malloc(4096);
CuAssert(cu, "malloc failed\n", mem[i] != NULL);
mem[i] = malloc(MK_PAGE_SIZE);
if (mem[i] == NULL)
{
break;
}
// memset(mem[i], 0, 4096);
for (int j = 0; j < 4096; j++)
for (int j = 0; j < MK_PAGE_SIZE; j++)
{
mem[i][j] = j % 256;
}
// printf("alloc %d 0x%lx\n", i, mem[i]);
}
for (int i = 0; i < 1000; i++)
for (int m = 0; m < i; m++)
{
for (int j = 0; j < 4096; j++)
for (int j = 0; j < MK_PAGE_SIZE; j++)
{
CuAssert(cu, "mem failed.\n", mem[i][j] == j % 256);
CuAssert(cu, "mem failed.\n", mem[m][j] == j % 256);
}
free(mem[i]);
free(mem[m]);
// printf("free %d 0x%lx\n", i, mem[i]);
}
}
static CuSuite suite;
CuSuite *malloc_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, malloc_test);
SUITE_ADD_TEST(&suite, malloc_test);
return suite;
return &suite;
}

View File

@@ -45,8 +45,8 @@ static void *thread_test_func(void *arg)
assert(strcmp(TEST_STR, buf) == 0);
ulog_write_str(log_hd, "map test success.\n");
hard_sleep();
thread_ipc_reply(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
printf("thread_test_func.\n");
thread_ipc_reply(msg_tag_init4(0, ROUND_UP(strlen(buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
handler_free(log_hd);
return NULL;
}
@@ -61,7 +61,7 @@ static void *thread_test_func2(void *arg)
strcpy((char *)(ipc_msg->msg_buf), TEST_STR);
ipc_msg->map_buf[0] = vpage_create_raw3(KOBJ_DELETE_RIGHT, VPAGE_FLAGS_MAP, LOG_PROT).raw;
thread_ipc_call(msg_tag_init4(0, ROUND_UP(strlen((char *)(ipc_msg->msg_buf)), WORD_BYTES), 1, 0),
pthread_hd_get(th1), ipc_timeout_create2(0, 0));
pthread_hd_get(th1), ipc_timeout_create2(0, 0));
printf("th2:%s", buf);
assert(strcmp(TEST_STR, buf) == 0);
printf("thread_test_func2.\n");
@@ -80,14 +80,15 @@ static void map_test(CuTest *test)
pthread_create(&th2, NULL, thread_test_func2, NULL);
CuAssert(test, "pthread create error.\n", ret == 0);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
CuAssert(test, "pthread_join fail.\n", pthread_join(th1, NULL) == 0);
CuAssert(test, "pthread_join fail.\n", pthread_join(th2, NULL) == 0);
}
static CuSuite suite;
CuSuite *map_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, map_test);
SUITE_ADD_TEST(&suite, map_test);
return suite;
return &suite;
}

View File

@@ -19,12 +19,12 @@ static void printf_test(CuTest *tc)
printf("%c %d %lf\n", 'a', 1234, 1.1);
}
}
static CuSuite suite;
CuSuite *printf_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, printf_test);
SUITE_ADD_TEST(&suite, printf_test);
return suite;
return &suite;
}

View File

@@ -29,11 +29,12 @@ static void thread_base_test(CuTest *cu)
CuAssert(cu, "pthread join error\n",
pthread_join(th_test, NULL) == 0);
}
static CuSuite suite;
CuSuite *pthread_base_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, thread_base_test);
SUITE_ADD_TEST(&suite, thread_base_test);
return suite;
return &suite;
}

View File

@@ -50,25 +50,26 @@ static void pthread_cond_lock_test(CuTest *cu)
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid1, NULL, thread_signal, NULL);
pthread_create(&tid2, NULL, thread_wait, NULL);
CuAssert(cu, "pthread_create fail.\n", pthread_create(&tid1, NULL, thread_signal, NULL) == 0);
CuAssert(cu, "pthread_create fail.\n", pthread_create(&tid2, NULL, thread_wait, NULL) == 0);
sleep(5);
quit = 1;
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
CuAssert(cu, "pthread_join fail.\n", pthread_join(tid1, NULL) == 0);
CuAssert(cu, "pthread_join fail.\n", pthread_join(tid2, NULL) == 0);
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
}
static CuSuite suite;
CuSuite *pthread_cond_lock_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, pthread_cond_lock_test);
SUITE_ADD_TEST(&suite, pthread_cond_lock_test);
return suite;
return &suite;
}

View File

@@ -74,11 +74,12 @@ static void pthread_lock_test(CuTest *cu)
pthread_join(pth2, NULL);
printf("%s:%d test ok.\n", __func__, __LINE__);
}
static CuSuite suite;
CuSuite *pthread_lock_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, pthread_lock_test);
SUITE_ADD_TEST(&suite, pthread_lock_test);
return suite;
return &suite;
}

View File

@@ -94,18 +94,28 @@ static void u_sema_test2(CuTest *tc)
tag = facotry_create_sema(FACTORY_PROT,
vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_hd2), 0, 1);
CuAssert(tc, "hd alloc fail.\n", msg_tag_get_val(tag) >= 0);
pthread_create(&pth1, NULL, thread_th1, NULL);
pthread_create(&pth2, NULL, thread_th2, NULL);
pthread_create(&pth3, NULL, thread_th3, NULL);
pthread_join(pth1, NULL);
pthread_join(pth2, NULL);
pthread_join(pth3, NULL);
CuAssert(tc, "pthread_create fail.\n", pthread_create(&pth1, NULL, thread_th1, NULL) == 0);
CuAssert(tc, "pthread_create fail.\n", pthread_create(&pth2, NULL, thread_th2, NULL) == 0);
CuAssert(tc, "pthread_create fail.\n", pthread_create(&pth3, NULL, thread_th3, NULL) == 0);
if (pth1 != PTHREAD_NULL)
{
CuAssert(tc, "pthread_join fail.\n", pthread_join(pth1, NULL) == 0);
}
if (pth2 != PTHREAD_NULL)
{
CuAssert(tc, "pthread_join fail.\n", pthread_join(pth2, NULL) == 0);
}
if (pth3 != PTHREAD_NULL)
{
CuAssert(tc, "pthread_join fail.\n", pthread_join(pth3, NULL) == 0);
}
}
static CuSuite suite;
CuSuite *sema_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, u_sema_test2);
SUITE_ADD_TEST(&suite, u_sema_test2);
return suite;
return &suite;
}

View File

@@ -46,12 +46,12 @@ static void sharea_mem_test(CuTest *cu)
share_mem_unmap(hd);
handler_free_umap(hd);
}
static CuSuite suite;
CuSuite *sharem_mem_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, sharea_mem_test);
SUITE_ADD_TEST(&suite, sharea_mem_test);
return suite;
return &suite;
}

View File

@@ -2,33 +2,49 @@
#include "CuTest.h"
#include "test.h"
#include <stdlib.h>
#include <u_util.h>
#include <u_sleep.h>
static CuSuite suite;
static void RunAllTests(void)
{
CuString *output = CuStringNew();
CuSuite* suite = CuSuiteNew();
if (output == NULL)
{
printf("malloc failed\n");
exit(1);
}
CuSuiteInit(&suite);
CuSuiteAddSuite(suite, ipc_test_suite());
CuSuiteAddSuite(suite, ulog_test_suite());
CuSuiteAddSuite(suite, printf_test_suite());
CuSuiteAddSuite(suite, vmm_test_suite());
CuSuiteAddSuite(suite, sharem_mem_test_suite());
CuSuiteAddSuite(suite, map_test_suite());
CuSuiteAddSuite(suite, thread_base_test_suite());
CuSuiteAddSuite(suite, sema_test_suite());
CuSuiteAddSuite(suite, malloc_test_suite());
CuSuiteAddSuite(suite, pthread_base_test_suite());
CuSuiteAddSuite(suite, pthread_press_test_suite());
CuSuiteAddSuite(suite, pthread_lock_test_suite());
CuSuiteAddSuite(suite, pthread_cond_lock_test_suite());
CuSuiteAddSuite(&suite, ipc_test_suite());
CuSuiteAddSuite(&suite, ulog_test_suite());
CuSuiteAddSuite(&suite, printf_test_suite());
#if IS_ENABLED(CONFIG_MMU)
CuSuiteAddSuite(&suite, vmm_test_suite());
CuSuiteAddSuite(&suite, sharem_mem_test_suite());
#endif
CuSuiteAddSuite(&suite, map_test_suite());
CuSuiteAddSuite(&suite, thread_base_test_suite());
CuSuiteAddSuite(&suite, sema_test_suite());
CuSuiteAddSuite(&suite, pthread_base_test_suite());
CuSuiteAddSuite(&suite, pthread_press_test_suite());
CuSuiteAddSuite(&suite, pthread_lock_test_suite());
CuSuiteAddSuite(&suite, pthread_cond_lock_test_suite());
CuSuiteAddSuite(&suite, malloc_test_suite());
CuSuiteRun(suite);
CuSuiteSummary(suite, output);
CuSuiteDetails(suite, output);
CuSuiteRun(&suite);
CuSuiteSummary(&suite, output);
CuSuiteDetails(&suite, output);
printf("%s\n", output->buffer);
u_sleep_ms(3000);
printf("MKRTOS test ok.\n");
}
void test_main(void)
{
RunAllTests();
RunAllTests();
while (1)
{
u_sleep_ms(1000);
}
}

View File

@@ -62,11 +62,12 @@ static void thread_base_test(CuTest *cu)
u_thread_del(th_hd);
}
}
static CuSuite suite;
CuSuite *thread_base_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, thread_base_test);
SUITE_ADD_TEST(&suite, thread_base_test);
return suite;
return &suite;
}

View File

@@ -35,11 +35,12 @@ static void thread_press_test(CuTest *cu)
pthread_join(th_array[i], NULL) == 0);
}
}
static CuSuite suite;
CuSuite *pthread_press_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, thread_press_test);
SUITE_ADD_TEST(&suite, thread_press_test);
return suite;
return &suite;
}

View File

@@ -70,13 +70,14 @@ static void vmm_press_block_test(CuTest *cu)
#undef TEST_MM_SIZE
#undef TEST_MEM_CN
}
static CuSuite suite;
CuSuite *vmm_test_suite(void)
{
CuSuite *suite = CuSuiteNew();
CuSuiteInit(&suite);
SUITE_ADD_TEST(suite, vmm_large_block_test);
SUITE_ADD_TEST(suite, vmm_small_block_test);
SUITE_ADD_TEST(suite, vmm_press_block_test);
SUITE_ADD_TEST(&suite, vmm_large_block_test);
SUITE_ADD_TEST(&suite, vmm_small_block_test);
SUITE_ADD_TEST(&suite, vmm_press_block_test);
return suite;
return &suite;
}