参考代码

This commit is contained in:
LokLiang
2024-03-28 12:19:52 +08:00
commit 7b86aa3362
96 changed files with 19986 additions and 0 deletions

124
components/system/test/main.c Executable file
View File

@@ -0,0 +1,124 @@
#include "os_test.h"
#include "sys_init.h"
#include "os/os.h"
#undef SYS_LOG_DOMAIN
#define SYS_LOG_DOMAIN "OS"
#include "os_util.h"
#ifndef CONFIG_OS_THREAD_MAIN_STACK_SIZE
#define CONFIG_OS_THREAD_MAIN_STACK_SIZE 0x2000
#endif
#ifndef CONFIG_OS_THREAD_MAIN_PRIORITY
#define CONFIG_OS_THREAD_MAIN_PRIORITY OS_PRIORITY_NORMAL
#endif
static unsigned s_int_nest;
static unsigned _port_interrupt_save(void)
{
if (s_int_nest == 0)
{
os_interrupt_disable();
}
return s_int_nest++;
}
static void _port_interrupt_restore(unsigned nest)
{
s_int_nest = nest;
if (nest == 0)
{
os_interrupt_enable();
}
}
static k_work_q_t *_port_get_work_q_hdl(void)
{
struct os_thread_handle *thread_handle = os_thread_get_self();
os_work_q_list_t *work_q_list = thread_handle->work_q_list;
return &work_q_list->work_q_handle;
}
static void _port_thread_sleep(k_tick_t sleep_ticks)
{
vTaskDelay(sleep_ticks);
}
static void _work_app_main(void *arg)
{
}
static void _os_init(void)
{
static k_init_t const init_struct = {
.malloc = os_malloc,
.free = os_free,
.get_sys_ticks = os_get_sys_ticks,
.interrupt_save = _port_interrupt_save,
.interrupt_restore = _port_interrupt_restore,
.scheduler_disable = os_scheduler_suspend,
.scheduler_enable = os_scheduler_resume,
.get_work_q_hdl = _port_get_work_q_hdl,
.thread_sleep = _port_thread_sleep,
};
k_init(&init_struct);
os_work_q_create(default_os_work_q_hdl,
"app-work_q",
CONFIG_OS_THREAD_MAIN_STACK_SIZE,
CONFIG_OS_THREAD_MAIN_PRIORITY);
static os_work_t _work_hdl_init;
os_work_create(&_work_hdl_init, "work-main", _work_app_main, NULL, 3);
os_work_submit(default_os_work_q_hdl, &_work_hdl_init, 0);
}
#include "sh.h"
static void _work_sh(void *arg)
{
char c;
// while (drv_uart_poll_read(board_uart_cons.id, &c) == 0)
// {
// sh_putc(&g_uart_handle_vt100, c);
// }
os_work_later(10);
}
static void _start_shell(void)
{
static os_work_t work_handler_shell;
os_work_create(&work_handler_shell, "work-shell", _work_sh, NULL, 0);
os_work_submit(default_os_work_q_hdl, &work_handler_shell, 0);
sh_putstr_quiet(&g_uart_handle_vt100, "sh version\r");
sh_set_prompt(&g_uart_handle_vt100, "sh:/> ");
sh_putc(&g_uart_handle_vt100, '\r');
}
void _app_main_handler(void *pArg)
{
extern int os_test_main(void);
os_test_main();
}
int app_main(void)
{
_os_init();
_start_shell();
static os_thread_t s_main_thread;
static char *const FirstTaskName = "test_main"; // 首个线程的线程名
os_thread_create(&s_main_thread,
FirstTaskName,
_app_main_handler,
(void *)rand(),
0x1000,
1);
return 0;
}

11
components/system/test/main.h Executable file
View File

@@ -0,0 +1,11 @@
#ifndef __MAIN_H__
#define __MAIN_H__
#include "kk.h"
#include "os/os.h"
void main_k_init(void);
void main_timer_reset(void);
void main_timer_hook(void (*fn)(void));
#endif

View File

@@ -0,0 +1,82 @@
#include "os_test.h"
#include "sys_init.h"
Type_OS_TestMem_Def rm_Test; // 用于测试的内存
os_work_t test_work_handle[10];
os_fifo_t fifo_handle[10];
os_queue_t queue_handle[10];
os_pipe_t pipe_handle[10];
os_thread_t *os_test_create_thread(os_thread_t *thread_handle, void (*TaskRoute)(void *), char *name, s16_t Priority)
{
os_thread_create(thread_handle,
name,
TaskRoute,
0,
0x1000,
Priority);
return thread_handle;
}
//
/* 具体测试 */
extern void os_test_fifo(void);
extern void os_test_queue(void);
extern void os_test_pipe(void);
extern void os_test_yield(uint TestTime);
extern void os_test_sem(uint TestTime);
extern void os_test_sleep(uint TestTime);
typedef void (*test_single_t)(void);
typedef void (*test_con_t)(uint TestTime);
static test_con_t const test_tab_rt[] = {
os_test_yield,
os_test_sem,
os_test_sleep,
};
static test_single_t const test_tab_ipc[] = {
os_test_fifo,
os_test_queue,
os_test_pipe,
};
INIT_EXPORT_APP(99)
{
SYS_LOG_INF("success");
os_thread_sleep(200);
}
void os_test_main(void)
{
rand(); // rand() 用到 malloc()
CONS_PRINT("\r\n"); // printf() 用到 _malloc_r()
SYS_LOG_INF("测试准备中 ... \r\n");
CONS_PRINT("开始测试...\r\n\r\n");
for (uint i = 0; i < sizeof(test_tab_rt) / sizeof(test_tab_rt[0]); i++)
{
test_tab_rt[i](1);
CONS_PRINT("\r\n");
}
for (uint i = 0; i < sizeof(test_tab_ipc) / sizeof(test_tab_ipc[0]); i++)
{
test_tab_ipc[i]();
}
for (uint n = 0; n < sizeof(test_work_handle) / sizeof(test_work_handle[0]); n++)
{
if (os_work_is_valid(&test_work_handle[n]))
{
os_work_delete(&test_work_handle[n]);
}
}
CONS_PRINT("所有测试结束\r\n");
CONS_PRINT("============================\r\n");
}

View File

@@ -0,0 +1,68 @@
#ifndef __OS_TEST_H__
#define __OS_TEST_H__
#define CONFIG_SYS_LOG_COLOR_ON 1
#undef CONFIG_SYS_LOG_LEVEL
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_DBG
#include "sys_log.h"
#include "os/os.h"
#include <stdio.h>
#include <stdlib.h>
#define OSTest_Assert 1
/* 测试使用到的内存结构 */
typedef struct
{
u8_t UseRate; //记录 CPU 使用率
uint CyclePreMS; //计算平均每毫秒运行了任务的循环次数
uint StickCount; //累计系统嘀嗒时钟的中断次数
uint Error_Line; //调度暂停位置
void (*SysTickRoute)(void); //每当产生系统节拍时钟中断时运行的测试函数
os_mutex_t Mem_Mutex1;
os_mutex_t Mem_Mutex2;
os_mutex_t Mem_Mutex3;
os_mutex_t Mem_Mutex4;
uint Mutex_Value;
struct
{
os_thread_t thread_handle; //任务句柄
os_timer_t timer_handle; //任务句柄
struct Type_OS_TaskMemDef *AllocMem; //申请到的内存地址
uint RunTimes; //任务循环次数
uint EventTimes; //
uint Stack_Used; //任务最大使用堆栈
uint Stack_Empty; //任务最大剩余堆栈
vuint Count;
double Result_dFPU;
volatile float Result_fFPU;
} Task[8];
struct
{
uint TotalWrite;
uint TotalRead;
uint WriteLog;
uint ReadComp;
uint DebugTime1;
uint DebugTime2;
} BufTest;
} Type_OS_TestMem_Def;
extern Type_OS_TestMem_Def rm_Test;
extern os_work_t test_work_handle[10];
extern os_fifo_t fifo_handle[10];
extern os_queue_t queue_handle[10];
extern os_pipe_t pipe_handle[10];
/* 用于测试的简便工具 */
os_thread_t *os_test_create_thread(os_thread_t *thread_handle, void (*TaskRoute)(void *), char *name, s16_t Priority); //简单创建任务
#endif
//

View File

@@ -0,0 +1,81 @@
#include "os_test.h"
static vuint test_flag = 0;
static void _os_test_fifo_handler_0(void *arg)
{
SYS_LOG_INF("测试创建和清空, 应出现1个警告");
void *first_handle;
SYS_ASSERT_FALSE(os_fifo_q_create(&fifo_handle[0]) != OS_OK, "");
first_handle = fifo_handle[0].handle;
os_fifo_q_clr(&fifo_handle[0]);
os_fifo_q_delete(&fifo_handle[0]);
SYS_LOG_INF("测试警告, 应出现3个警告");
SYS_ASSERT_FALSE(os_fifo_q_create(&fifo_handle[0]) != OS_OK, "");
uint32_t *p32 = os_fifo_alloc(sizeof(*p32));
SYS_ASSERT_FALSE(p32 == 0, "");
*p32 = 0x1234abcd;
SYS_ASSERT_FALSE(os_fifo_put(&fifo_handle[0], p32) != OS_OK, "");
SYS_ASSERT_FALSE(os_fifo_put(&fifo_handle[0], p32) == OS_OK, ""); // os_fifo_put(): fifo_data not valid
SYS_ASSERT_FALSE(os_fifo_take(&fifo_handle[0], 0) != p32, "");
SYS_ASSERT_FALSE(*p32 != 0x1234abcd, "");
SYS_ASSERT_FALSE(os_fifo_take(&fifo_handle[0], 0) != 0, "");
SYS_ASSERT_FALSE(os_fifo_free(p32) != OS_OK, "");
SYS_ASSERT_FALSE(os_fifo_free(p32) == OS_OK, ""); // os_fifo_free(): 0x.. was not in fifo queue, can not to free
SYS_ASSERT_FALSE(os_fifo_put(&fifo_handle[0], p32) == OS_OK, ""); // os_fifo_put(): fifo_data not valid
SYS_LOG_INF("测试清除");
SYS_ASSERT_FALSE(os_fifo_alloc(sizeof(*p32)) != p32, "");
SYS_ASSERT_FALSE(os_fifo_put(&fifo_handle[0], p32) != OS_OK, "");
os_fifo_q_clr(&fifo_handle[0]);
SYS_ASSERT_FALSE(os_fifo_take(&fifo_handle[0], 0) != 0, "");
SYS_ASSERT_FALSE(os_fifo_alloc(sizeof(*p32)) != p32, "");
SYS_ASSERT_FALSE(os_fifo_free(p32) != OS_OK, "");
SYS_LOG_INF("测试自动释放已在队列内的数据");
SYS_ASSERT_FALSE(os_fifo_alloc(sizeof(*p32)) != p32, "");
SYS_ASSERT_FALSE(os_fifo_put(&fifo_handle[0], p32) != 0, "");
os_fifo_q_delete(&fifo_handle[0]);
SYS_ASSERT_FALSE(os_fifo_q_create(&fifo_handle[0]) != OS_OK, "");
SYS_ASSERT_FALSE(first_handle != fifo_handle[0].handle, "");
SYS_ASSERT_FALSE(os_fifo_alloc(sizeof(*p32)) != p32, "");
SYS_ASSERT_FALSE(os_fifo_put(&fifo_handle[0], p32) != OS_OK, "");
os_fifo_q_delete(&fifo_handle[0]);
test_flag = 1;
}
static void _os_test_fifo_t1(void *arg)
{
test_flag = test_flag << 4 | 1;
void *mem = os_fifo_take(&fifo_handle[0], -1u);
test_flag = test_flag << 4 | 2;
os_fifo_free(mem);
}
void os_test_fifo(void)
{
SYS_LOG_INF("-------------------------------");
test_flag = 0;
os_work_create(&test_work_handle[0], "", _os_test_fifo_handler_0, NULL, 1);
os_work_submit(default_os_work_q_hdl, &test_work_handle[0], 0);
os_work_delete(&test_work_handle[0]);
SYS_ASSERT_FALSE(test_flag == 0, "");
SYS_LOG_INF("-------------------------------");
size_t max_block_size;
os_heap_info(NULL, NULL, &max_block_size);
static os_thread_t t1;
void *mem;
SYS_LOG_INF("测试提交 FIFO 唤醒");
test_flag = 0;
os_fifo_q_create(&fifo_handle[0]);
os_test_create_thread(&t1, _os_test_fifo_t1, "t1", OS_PRIORITY_HIGHEST);
SYS_ASSERT_FALSE(test_flag != 0x1, "");
mem = os_fifo_alloc(0x10);
SYS_ASSERT_FALSE(test_flag != 0x1, "");
os_fifo_put(&fifo_handle[0], mem);
SYS_ASSERT_FALSE(test_flag != 0x12, "");
os_fifo_q_delete(&fifo_handle[0]);
}

View File

@@ -0,0 +1,57 @@
#include "os_test.h"
static vuint test_flag = 0;
static void _os_test_pipe_handler_0(void *arg)
{
uint32_t data = 0;
uint8_t *p8 = (uint8_t *)&data;
SYS_LOG_INF("测试创建和清空, 应出现1个警告");
void *first_handle;
SYS_ASSERT_FALSE(os_pipe_create(&pipe_handle[0], 4) != OS_OK, "");
first_handle = pipe_handle[0].handle;
os_pipe_clr(&pipe_handle[0]);
os_pipe_delete(&pipe_handle[0]);
SYS_LOG_INF("测试状态");
SYS_ASSERT_FALSE(os_pipe_create(&pipe_handle[0], 3) != OS_OK, "");
SYS_ASSERT_FALSE(first_handle != pipe_handle[0].handle, "");
SYS_ASSERT_FALSE(os_pipe_is_ne(&pipe_handle[0]) != false, "");
SYS_ASSERT_FALSE(os_pipe_get_valid_size(&pipe_handle[0]) != 0, "");
SYS_ASSERT_FALSE(os_pipe_get_empty_size(&pipe_handle[0]) != 3, "");
SYS_LOG_INF("测试写");
SYS_ASSERT_FALSE(os_pipe_poll_write(&pipe_handle[0], 1) != 1, "");
SYS_ASSERT_FALSE(os_pipe_is_ne(&pipe_handle[0]) != true, "");
SYS_ASSERT_FALSE(os_pipe_get_valid_size(&pipe_handle[0]) != 1, "");
SYS_ASSERT_FALSE(os_pipe_get_empty_size(&pipe_handle[0]) != 2, "");
p8[0] = 2, p8[1] = 3;
SYS_ASSERT_FALSE(os_pipe_fifo_fill(&pipe_handle[0], &data, sizeof(data)) != 2, "");
SYS_ASSERT_FALSE(os_pipe_get_valid_size(&pipe_handle[0]) != 3, "");
SYS_ASSERT_FALSE(os_pipe_get_empty_size(&pipe_handle[0]) != 0, "");
SYS_LOG_INF("测试读");
data = -1u;
SYS_ASSERT_FALSE(os_pipe_poll_read(&pipe_handle[0], &p8[0]) != 1, "");
SYS_ASSERT_FALSE(os_pipe_is_ne(&pipe_handle[0]) != true, "");
SYS_ASSERT_FALSE(os_pipe_get_valid_size(&pipe_handle[0]) != 2, "");
SYS_ASSERT_FALSE(os_pipe_get_empty_size(&pipe_handle[0]) != 1, "");
SYS_ASSERT_FALSE(os_pipe_fifo_read(&pipe_handle[0], &p8[1], 3) != 2, "");
SYS_ASSERT_FALSE(os_pipe_is_ne(&pipe_handle[0]) != false, "");
SYS_ASSERT_FALSE(os_pipe_get_valid_size(&pipe_handle[0]) != 0, "");
SYS_ASSERT_FALSE(os_pipe_get_empty_size(&pipe_handle[0]) != 3, "");
SYS_ASSERT_FALSE(data != 0xff030201, "");
os_pipe_delete(&pipe_handle[0]);
test_flag = 1;
}
void os_test_pipe(void)
{
SYS_LOG_INF("-------------------------------");
test_flag = 0;
os_work_create(&test_work_handle[0], "", _os_test_pipe_handler_0, NULL, 1);
os_work_submit(default_os_work_q_hdl, &test_work_handle[0], 0);
os_work_delete(&test_work_handle[0]);
SYS_ASSERT_FALSE(test_flag == 0, "");
}

View File

@@ -0,0 +1,47 @@
#include "os_test.h"
static vuint test_flag = 0;
static void _os_test_queue_t3(void *arg)
{
uint64_t dst_64 = 0;
test_flag = test_flag << 4 | 1;
SYS_ASSERT_FALSE(os_queue_recv(&queue_handle[0], &dst_64, OS_WAIT_FOREVER) != OS_OK, "");
SYS_ASSERT_FALSE(dst_64 != 0x1234567890abcdef, "");
test_flag = test_flag << 4 | 2;
}
void os_test_queue(void)
{
SYS_LOG_INF("-------------------------------");
static os_thread_t t2;
uint64_t src_64 = 0x1234567890abcdef;
uint64_t dst_64 = 0;
int systime_start;
int systime_end;
os_queue_create(&queue_handle[0], 1, sizeof(src_64));
SYS_LOG_INF("测试发送和接收");
test_flag = 0;
os_test_create_thread(&t2, _os_test_queue_t3, "t3", OS_PRIORITY_HIGHEST);
SYS_ASSERT_FALSE(test_flag != 0x1, "test_flag = 0x%x", test_flag);
SYS_ASSERT_FALSE(os_queue_send(&queue_handle[0], &src_64, 100) != OS_OK, "");
SYS_ASSERT_FALSE(test_flag != 0x12, "test_flag = 0x%x", test_flag);
SYS_LOG_INF("测试发送和发送超时");
systime_start = os_get_sys_ticks();
SYS_ASSERT_FALSE(os_queue_send(&queue_handle[0], &src_64, 100) != OS_OK, "");
SYS_ASSERT_FALSE(os_queue_send(&queue_handle[0], &src_64, 100) == OS_OK, "");
systime_end = os_get_sys_ticks();
SYS_ASSERT_FALSE(systime_end - systime_start < 100 || systime_end - systime_start > 120, "systime_end - systime_start = %d", systime_end - systime_start);
SYS_LOG_INF("测试接收和接收超时");
systime_start = os_get_sys_ticks();
SYS_ASSERT_FALSE(os_queue_recv(&queue_handle[0], &dst_64, 100) != OS_OK, "");
SYS_ASSERT_FALSE(dst_64 != src_64, "");
SYS_ASSERT_FALSE(os_queue_recv(&queue_handle[0], &dst_64, 100) == OS_OK, "");
systime_end = os_get_sys_ticks();
SYS_ASSERT_FALSE(systime_end - systime_start < 100 || systime_end - systime_start > 120, "systime_end - systime_start = %d", systime_end - systime_start);
os_queue_delete(&queue_handle[0]);
}

View File

@@ -0,0 +1,46 @@
#include "os_test.h"
static os_thread_t thread_1;
static os_thread_t thread_2;
static os_thread_t thread_3;
static os_sem_t test_sem_fifo;
static vuint test_flag = 0;
static void _test_os_t1(void *arg)
{
os_sem_take(&test_sem_fifo, OS_WAIT_FOREVER);
test_flag = test_flag << 4 | 1;
os_sem_take(&test_sem_fifo, OS_WAIT_FOREVER);
test_flag = test_flag << 4 | 1;
}
static void _test_os_t2(void *arg)
{
os_sem_take(&test_sem_fifo, OS_WAIT_FOREVER);
test_flag = test_flag << 4 | 2;
}
static void _test_os_t3(void *arg)
{
os_sem_take(&test_sem_fifo, OS_WAIT_FOREVER);
test_flag = test_flag << 4 | 3;
}
void os_test_sem(uint TestTime)
{
SYS_LOG_INF("");
SYS_LOG_DBG("测试 os_sem_create()");
SYS_ASSERT_FALSE(os_sem_create(&test_sem_fifo, 1, 3) != OS_OK, "");
SYS_LOG_DBG("测试 OS_SEM_TYPE_FIFO");
test_flag = 0;
os_test_create_thread(&thread_1, _test_os_t1, "task01-2", 2);
os_test_create_thread(&thread_2, _test_os_t2, "task02-3", 3);
os_test_create_thread(&thread_3, _test_os_t3, "task03-4", 4);
SYS_ASSERT(test_flag == 0x1, "");
os_sem_release(&test_sem_fifo);
os_sem_release(&test_sem_fifo);
os_sem_release(&test_sem_fifo);
SYS_ASSERT(test_flag == 0x1321, "test_flag = %#x", test_flag);
os_sem_delete(&test_sem_fifo);
}

View File

@@ -0,0 +1,27 @@
#include "os_test.h"
void os_test_sleep(uint TestTime)
{
vuint start_tick;
vuint test_tick;
int offset;
SYS_LOG_INF("测试延时");
SYS_LOG_DBG("测试 os_thread_sleep()");
os_thread_sleep(1);
start_tick = os_get_sys_ticks();
os_thread_sleep(10);
test_tick = os_get_sys_ticks();
offset = test_tick - start_tick;
SYS_ASSERT_FALSE(offset != 10 && offset != 11, "offset = %d", offset);
SYS_LOG_DBG("测试 os_thread_sleep_until()");
os_thread_sleep(1);
start_tick = os_get_sys_ticks();
os_thread_sleep(30);
test_tick = os_get_sys_ticks();
offset = test_tick - start_tick;
SYS_ASSERT_FALSE(offset < 30 || offset > 31, "offset = %d", offset); //使用软件测试时允许有1毫秒的误差
}

View File

@@ -0,0 +1,110 @@
#include "os_test.h"
static os_thread_t thread_1;
static os_thread_t thread_2;
static os_thread_t thread_3;
static os_thread_t thread_4;
static vuint count1 = 0;
static vuint count2 = 0;
static vuint count3 = 0;
static vuint count4 = 0;
#define _TEST_TIMES 2000
static void _test_os_t1(void *arg)
{
count1 = 0;
while (1)
{
if (count1++ % _TEST_TIMES == 0)
{
SYS_LOG_DBG("%d", count1 / _TEST_TIMES);
if (count1 >= (_TEST_TIMES * 10))
{
return;
}
}
os_thread_yield();
}
}
static void _test_os_t2(void *arg)
{
count2 = 0;
while (1)
{
if (count2++ % _TEST_TIMES == 0)
{
SYS_LOG_DBG("%d", count2 / _TEST_TIMES);
if (count2 >= (_TEST_TIMES * 10))
{
return;
}
}
os_thread_yield();
}
}
static void _test_os_t3(void *arg)
{
count3 = 0;
while (1)
{
if (count3++ % _TEST_TIMES == 0)
{
SYS_LOG_DBG("%d", count3 / _TEST_TIMES);
if (count3 >= (_TEST_TIMES * 10))
{
return;
}
}
os_thread_suspend(NULL);
SYS_ASSERT_FALSE(count3 != count4, "count3 = %d, count4 = %d, suspend fail", count3, count4);
}
}
static void _test_os_t4(void *arg)
{
count4 = 0;
while (1)
{
if (count4++ % _TEST_TIMES == 0)
{
SYS_LOG_DBG("%d", count4 / _TEST_TIMES);
if (count4 >= (_TEST_TIMES * 10))
{
return;
}
}
os_thread_resume(&thread_3);
SYS_ASSERT_FALSE(count4 + 1 != count3, "count3 = %d, count4 = %d, thread 3 dead!", count3, count4);
}
}
void os_test_yield(uint TestTime)
{
uint start_tick, test_tick, time_nS;
SYS_LOG_INF("");
os_scheduler_suspend();
os_test_create_thread(&thread_1, _test_os_t1, "task01-4", 4);
os_test_create_thread(&thread_2, _test_os_t2, "task02-4", 4);
start_tick = os_get_sys_ticks();
os_scheduler_resume();
test_tick = os_get_sys_ticks();
time_nS = (test_tick - start_tick) * 1000000 / (count1 + count2);
SYS_LOG_DBG("平均时间: %d.%03d uS", time_nS / 1000, time_nS % 1000);
os_scheduler_suspend();
os_test_create_thread(&thread_3, _test_os_t3, "task03-3", 3);
os_test_create_thread(&thread_4, _test_os_t4, "task04-2", 2);
start_tick = os_get_sys_ticks();
os_scheduler_resume();
test_tick = os_get_sys_ticks();
time_nS = (test_tick - start_tick) * 1000000 / (count3 + count4);
SYS_LOG_DBG("平均时间: %d.%03d uS", time_nS / 1000, time_nS % 1000);
os_sys_print_info();
}