fastipc初版
This commit is contained in:
@@ -115,7 +115,7 @@ CONFIG_BOARD_NAME="STM32F205"
|
||||
CONFIG_BUDDY_SLAB=n
|
||||
CONFIG_SMP=n
|
||||
CONFIG_CPU=1
|
||||
CONFIG_THREAD_BLOCK_SIZE=0x400
|
||||
CONFIG_THREAD_BLOCK_SIZE=0x800
|
||||
CONFIG_PAGE_SHIFT=9
|
||||
CONFIG_MMU=n
|
||||
CONFIG_KNL_TEST=n
|
||||
|
||||
@@ -40,7 +40,7 @@ void thread_knl_pf_set(thread_t *cur_th, void *pc)
|
||||
cur_th->sp.user_sp = 0;
|
||||
cur_th->sp.sp_type = 0xfffffff9;
|
||||
}
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack)
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram)
|
||||
{
|
||||
// assert((((umword_t)user_sp) & 0x7UL) == 0);
|
||||
umword_t usp = ((umword_t)(user_sp) & ~0x7UL);
|
||||
@@ -55,8 +55,12 @@ void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, um
|
||||
cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8);
|
||||
cur_th->sp.user_sp = cur_pf;
|
||||
cur_th->sp.sp_type = 0xfffffffd;
|
||||
|
||||
// printk("exc_regs:%x %x %x\n", cur_pf->pf_s.pc, cur_th->sp.user_sp, ram);
|
||||
}
|
||||
void thread_user_pf_restore(thread_t *cur_th, void *user_sp)
|
||||
{
|
||||
cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8);
|
||||
cur_th->sp.user_sp = user_sp;
|
||||
cur_th->sp.sp_type = 0xfffffffd;
|
||||
}
|
||||
void task_knl_init(task_t *knl_tk)
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ void uart_init(void)
|
||||
nvic_priority_group_config(NVIC_PRIORITY_GROUP_2);
|
||||
nvic_irq_enable(USART1_IRQn, 0, 0);
|
||||
/* configure uart param */
|
||||
usart_init(PRINT_USARTx, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
|
||||
usart_init(PRINT_USARTx, 921600, USART_DATA_8BITS, USART_STOP_1_BIT);
|
||||
usart_transmitter_enable(PRINT_USARTx, TRUE);
|
||||
usart_receiver_enable(PRINT_USARTx, TRUE);
|
||||
|
||||
|
||||
@@ -18,15 +18,15 @@ void sema_init(sema_t *obj, int cnt, int max);
|
||||
void sema_up(sema_t *obj);
|
||||
void sema_down(sema_t *obj);
|
||||
|
||||
void mutex_init(mutex_t *lock)
|
||||
static inline void mutex_init(mutex_t *lock)
|
||||
{
|
||||
sema_init(lock, 1, 1);
|
||||
}
|
||||
void mutex_lock(mutex_t *lock)
|
||||
static inline void mutex_lock(mutex_t *lock)
|
||||
{
|
||||
sema_down(lock);
|
||||
}
|
||||
void mutex_unlock(mutex_t *lock)
|
||||
static inline void mutex_unlock(mutex_t *lock)
|
||||
{
|
||||
sema_up(lock);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "obj_space.h"
|
||||
#include "mm_space.h"
|
||||
#include "ref.h"
|
||||
|
||||
#include "sema.h"
|
||||
typedef struct task
|
||||
{
|
||||
kobject_t kobj; //!< task kernel object.
|
||||
@@ -28,8 +28,15 @@ typedef struct task
|
||||
kobject_t *exec_th; //!< execption thread.
|
||||
ref_counter_t ref_cn; //!< ref count.
|
||||
slist_head_t del_node; //!< delect list node.
|
||||
void *nofity_point; //!< commint point.
|
||||
|
||||
void *nofity_point; //!< commint point func.
|
||||
addr_t nofity_stack; //!< nofity_point_stack.
|
||||
mutex_t nofity_lock;
|
||||
addr_t nofity_msg_buf; //!<
|
||||
umword_t *nofity_bitmap; //!<
|
||||
int nofity_bitmap_len; //!< max is WORD_BITS
|
||||
slist_head_t nofity_theads_head;
|
||||
|
||||
pid_t pid; //!< task pid.
|
||||
} task_t;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ref.h"
|
||||
#include <atomics.h>
|
||||
#include "task.h"
|
||||
#include "stack.h"
|
||||
struct task;
|
||||
typedef struct task task_t;
|
||||
struct thread;
|
||||
@@ -107,13 +108,21 @@ typedef struct msg_buf
|
||||
#endif
|
||||
msg_tag_t tag; //!< 存放发送的临时标识
|
||||
} msg_buf_t;
|
||||
|
||||
typedef struct thread_fast_ipc_item
|
||||
{
|
||||
kobject_t *task_bk; //!< 备份task,用于快速通信
|
||||
void *usp_backup; //!< 备份用户栈,用于快速通信
|
||||
void *msg_buf;
|
||||
} thread_fast_ipc_item_t;
|
||||
#define THREAD_FAST_IPC_ITEM_NUM 8
|
||||
|
||||
#define THREAD_MAGIC 0xdeadead //!< 用于栈溢出检测
|
||||
typedef struct thread
|
||||
{
|
||||
kobject_t kobj; //!< 内核对象节点
|
||||
sched_t sche; //!< 调度节点
|
||||
kobject_t *task; //!< 绑定的task
|
||||
kobject_t *task_bk; //!< 备份task,用于快速通信
|
||||
sp_info_t sp; //!< sp信息
|
||||
ram_limit_t *lim; //!< 内存限制
|
||||
ref_counter_t ref; //!< 引用计数
|
||||
@@ -141,7 +150,9 @@ typedef struct thread
|
||||
enum thread_state status; //!< 线程状态
|
||||
enum thread_ipc_state ipc_status; //!< ipc状态
|
||||
|
||||
void *usp_backup;
|
||||
thread_fast_ipc_item_t fast_ipc_stack_data[THREAD_FAST_IPC_ITEM_NUM]; //!< 栈数据,用于通信栈备份
|
||||
stack_t fast_ipc_stack; //!< fast ipc stack
|
||||
slist_head_t fast_ipc_node; //!< 用于加入到task中去。
|
||||
|
||||
umword_t magic; //!< maigc
|
||||
} thread_t;
|
||||
@@ -207,14 +218,51 @@ static inline thread_t *thread_get_current(void)
|
||||
|
||||
return th;
|
||||
}
|
||||
static inline void thread_set_task_and_backup(thread_t *th, task_t *tk)
|
||||
static inline int thread_fast_ipc_save(thread_t *th, task_t *tk, void *usp)
|
||||
{
|
||||
th->task_bk = th->task;
|
||||
th->task = (void*)(&(tk->kobj));
|
||||
int ret;
|
||||
assert(th);
|
||||
assert(tk);
|
||||
assert(usp);
|
||||
thread_fast_ipc_item_t item = {
|
||||
.task_bk = th->task,
|
||||
.usp_backup = (void *)arch_get_user_sp(),
|
||||
.msg_buf = th->msg.msg,
|
||||
};
|
||||
ret = stack_push(&th->fast_ipc_stack, &item);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
th->task = &tk->kobj;
|
||||
arch_set_user_sp((umword_t)usp); //!< 重新设置
|
||||
return 0;
|
||||
}
|
||||
static inline void thread_task_restore(thread_t *th)
|
||||
static inline int thread_fast_ipc_restore(thread_t *th)
|
||||
{
|
||||
th->task = th->task_bk;
|
||||
int ret;
|
||||
assert(th);
|
||||
thread_fast_ipc_item_t item;
|
||||
|
||||
ret = stack_pop(&th->fast_ipc_stack, &item);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
th->task = item.task_bk;
|
||||
th->msg.msg = item.msg_buf;
|
||||
arch_set_user_sp((umword_t)(item.usp_backup));
|
||||
return 0;
|
||||
}
|
||||
static inline int thread_fast_ipc_pop(thread_t *th, thread_fast_ipc_item_t *item)
|
||||
{
|
||||
int ret;
|
||||
assert(th);
|
||||
assert(item);
|
||||
|
||||
ret = stack_pop(&th->fast_ipc_stack, item);
|
||||
|
||||
return ret;
|
||||
}
|
||||
task_t *thread_get_current_task(void);
|
||||
task_t *thread_get_task(thread_t *th);
|
||||
@@ -225,7 +273,7 @@ static inline pf_t *thread_get_current_pf(void)
|
||||
return thread_get_pf(thread_get_current());
|
||||
}
|
||||
void thread_init(thread_t *th, ram_limit_t *lim, umword_t flags);
|
||||
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp, umword_t ram, umword_t stack);
|
||||
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp, umword_t ram);
|
||||
thread_t *thread_create(ram_limit_t *ram, umword_t flags);
|
||||
void thread_bind(thread_t *th, kobject_t *tk);
|
||||
void thread_unbind(thread_t *th);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
void thread_knl_pf_set(thread_t *cur_th, void *pc);
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack);
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram);
|
||||
void thread_user_pf_restore(thread_t *cur_th, void *user_sp);
|
||||
void task_knl_init(task_t *knl_tk);
|
||||
|
||||
13
mkrtos_knl/inc/lib/stack.h
Normal file
13
mkrtos_knl/inc/lib/stack.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *data;
|
||||
int top;
|
||||
int len;
|
||||
int item_size;
|
||||
} stack_t;
|
||||
|
||||
void stack_init(stack_t *stack, void *stack_data, int len, int item_size);
|
||||
int stack_push(stack_t *stack, void *item);
|
||||
int stack_pop(stack_t *stack, void *item);
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "string.h"
|
||||
#include "thread.h"
|
||||
#include "thread_arch.h"
|
||||
#include "thread_task_arch.h"
|
||||
#if IS_ENABLED(CONFIG_MMU)
|
||||
#include "arch.h"
|
||||
#endif
|
||||
@@ -41,6 +42,8 @@ enum task_op_code
|
||||
TASK_SET_OBJ_NAME, //!< 设置对象的名字
|
||||
TASK_COPY_DATA_TO, //!< 从当前task拷贝数据到目的task
|
||||
TASK_SET_COM_POINT, //!< 通信点
|
||||
TASK_COM_UNLOCK, //!< 任务通信解锁
|
||||
TASK_COM_LOCK, //!< 任务通信加锁
|
||||
};
|
||||
static bool_t task_put(kobject_t *kobj);
|
||||
static void task_release_stage1(kobject_t *kobj);
|
||||
@@ -396,10 +399,51 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
|
||||
tag = msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
break;
|
||||
case TASK_SET_COM_POINT:
|
||||
case TASK_SET_COM_POINT: //!< 设置通信点
|
||||
{
|
||||
if (!is_rw_access(tag_task, (void *)(f->regs[1]), f->regs[2], FALSE))
|
||||
{
|
||||
tag = msg_tag_init4(0, 0, 0, -EPERM);
|
||||
break;
|
||||
}
|
||||
if (f->regs[4] >= WORD_BITS)
|
||||
{
|
||||
tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
||||
break;
|
||||
}
|
||||
if (!is_rw_access(tag_task, (void *)(f->regs[3]), ROUND_UP(f->regs[4], 8), FALSE))
|
||||
{
|
||||
tag = msg_tag_init4(0, 0, 0, -EPERM);
|
||||
break;
|
||||
}
|
||||
if (!is_rw_access(tag_task, (void *)(f->regs[5]), THREAD_MSG_BUG_LEN, FALSE))
|
||||
{
|
||||
tag = msg_tag_init4(0, 0, 0, -EPERM);
|
||||
break;
|
||||
}
|
||||
int stack_size = f->regs[2];
|
||||
|
||||
tag_task->nofity_point = (void *)(f->regs[0]);
|
||||
tag_task->nofity_stack = (addr_t)(f->regs[1]);
|
||||
tag_task->nofity_stack = (addr_t)(f->regs[1] + stack_size);
|
||||
tag_task->nofity_bitmap = (void *)(f->regs[3]);
|
||||
tag_task->nofity_bitmap_len = (f->regs[4]);
|
||||
tag_task->nofity_msg_buf = (addr_t)f->regs[5];
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case TASK_COM_UNLOCK:
|
||||
{
|
||||
task_t *cur_task = thread_get_current_task();
|
||||
|
||||
mutex_unlock(&cur_task->nofity_lock);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case TASK_COM_LOCK:
|
||||
{
|
||||
task_t *cur_task = thread_get_current_task();
|
||||
|
||||
mutex_lock(&cur_task->nofity_lock);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
@@ -420,6 +464,8 @@ void task_init(task_t *task, ram_limit_t *ram, int is_knl)
|
||||
ref_counter_init(&task->ref_cn);
|
||||
ref_counter_inc(&task->ref_cn);
|
||||
slist_init(&task->del_node);
|
||||
slist_init(&task->nofity_theads_head);
|
||||
mutex_init(&task->nofity_lock);
|
||||
task->pid = -1;
|
||||
task->lim = ram;
|
||||
task->kobj.invoke_func = task_syscall_func;
|
||||
@@ -442,6 +488,7 @@ static bool_t task_put(kobject_t *kobj)
|
||||
}
|
||||
static void task_release_stage1(kobject_t *kobj)
|
||||
{
|
||||
int ret;
|
||||
task_t *tk = container_of(kobj, task_t, kobj);
|
||||
kobj_del_list_t kobj_list;
|
||||
kobject_invalidate(kobj);
|
||||
@@ -449,6 +496,28 @@ static void task_release_stage1(kobject_t *kobj)
|
||||
obj_unmap_all(&tk->obj_space, &kobj_list);
|
||||
kobj_del_list_to_do(&kobj_list);
|
||||
|
||||
thread_t *restore_th;
|
||||
thread_fast_ipc_item_t ipc_item;
|
||||
|
||||
slist_foreach(restore_th, &tk->nofity_theads_head, fast_ipc_node)
|
||||
{
|
||||
ret = thread_fast_ipc_pop(restore_th, &ipc_item);
|
||||
if (ret >= 0)
|
||||
{
|
||||
// 还原栈和usp
|
||||
restore_th->ipc_status = THREAD_NONE;
|
||||
if (restore_th->status == THREAD_SUSPEND)
|
||||
{
|
||||
thread_ready(restore_th, TRUE);
|
||||
}
|
||||
restore_th->task = ipc_item.task_bk;
|
||||
thread_user_pf_restore(restore_th, ipc_item.usp_backup);
|
||||
pf_t *cur_pf = ((pf_t *)((char *)restore_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1;
|
||||
cur_pf->regs[5] = (umword_t)(thread_get_bind_task(restore_th)->mm_space.mm_block);
|
||||
ref_counter_dec_and_release(&tk->ref_cn, &tk->kobj);
|
||||
}
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MMU)
|
||||
task_vma_clean(&tk->mm_space.mem_vma);
|
||||
#endif
|
||||
@@ -482,7 +551,7 @@ static void task_release_stage2(kobject_t *kobj)
|
||||
// arch_to_sche();
|
||||
// }
|
||||
// mm_trace();
|
||||
printk("release tk %x\n", tk);
|
||||
printk("release tk %x, name is:%s\n", tk, kobject_get_name(&tk->kobj));
|
||||
}
|
||||
void task_kill(task_t *tk)
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "thread.h"
|
||||
#include "thread_task_arch.h"
|
||||
#include "types.h"
|
||||
#include "sema.h"
|
||||
#if IS_ENABLED(CONFIG_SMP)
|
||||
#include <ipi.h>
|
||||
#endif
|
||||
@@ -120,11 +121,15 @@ void thread_init(thread_t *th, ram_limit_t *lim, umword_t flags)
|
||||
sched_init(&th->sche);
|
||||
slist_init(&th->futex_node);
|
||||
slist_init(&th->wait_send_head);
|
||||
slist_init(&th->fast_ipc_node);
|
||||
spinlock_init(&th->recv_lock);
|
||||
spinlock_init(&th->send_lock);
|
||||
ref_counter_init(&th->ref);
|
||||
ref_counter_inc(&th->ref);
|
||||
thread_arch_init(th, flags);
|
||||
stack_init(&th->fast_ipc_stack, &th->fast_ipc_stack_data,
|
||||
ARRARY_LEN(th->fast_ipc_stack_data),
|
||||
sizeof(th->fast_ipc_stack_data[0]));
|
||||
th->cpu = arch_get_current_cpu_id();
|
||||
th->lim = lim;
|
||||
th->kobj.invoke_func = thread_syscall;
|
||||
@@ -310,7 +315,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);
|
||||
printk("release thread 0x%x, name:%s\n", kobj, kobject_get_name(kobj));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -322,9 +327,9 @@ static void thread_release_stage2(kobject_t *kobj)
|
||||
* @param ip
|
||||
*/
|
||||
void thread_set_exc_regs(thread_t *th, umword_t pc, umword_t user_sp,
|
||||
umword_t ram, umword_t stack)
|
||||
umword_t ram)
|
||||
{
|
||||
thread_user_pf_set(th, (void *)pc, (void *)user_sp, (void *)ram, stack);
|
||||
thread_user_pf_set(th, (void *)pc, (void *)user_sp, (void *)ram);
|
||||
}
|
||||
/**
|
||||
* @brief 线程绑定到task
|
||||
@@ -710,6 +715,41 @@ void thread_timeout_del_recv_remote(thread_t *th, bool_t is_sche)
|
||||
thread_ready(th, is_sche); //!< 直接唤醒接受者
|
||||
#endif
|
||||
}
|
||||
static int ipc_dat_copy_raw(obj_space_t *dst_obj, obj_space_t *src_obj, ram_limit_t *lim,
|
||||
ipc_msg_t *dst_ipc, ipc_msg_t *src_ipc, msg_tag_t tag, int is_reply)
|
||||
{
|
||||
if (tag.map_buf_len > 0)
|
||||
{
|
||||
kobj_del_list_t del;
|
||||
int map_len = tag.map_buf_len;
|
||||
|
||||
kobj_del_list_init(&del);
|
||||
|
||||
for (int i = 0; i < map_len; i++)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
vpage_t dst_page = vpage_create_raw(dst_ipc->map_buf[i]);
|
||||
vpage_t src_page = vpage_create_raw(src_ipc->map_buf[i]);
|
||||
|
||||
if ((src_page.flags & VPAGE_FLAGS_MAP) || is_reply)
|
||||
{
|
||||
ret = obj_map_src_dst(dst_obj, src_obj,
|
||||
vpage_get_obj_handler(dst_page),
|
||||
vpage_get_obj_handler(src_page), lim,
|
||||
vpage_get_attrs(src_page), &del);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
kobj_del_list_to_do(&del);
|
||||
}
|
||||
memcpy(dst_ipc->msg_buf, src_ipc->msg_buf,
|
||||
MIN(tag.msg_buf_len * WORD_BYTES, IPC_MSG_SIZE));
|
||||
}
|
||||
/**
|
||||
* @brief ipc传输时的数据拷贝
|
||||
*
|
||||
@@ -730,38 +770,9 @@ static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag, int
|
||||
src_ipc = src;
|
||||
dst_ipc = dst;
|
||||
|
||||
if (tag.map_buf_len > 0)
|
||||
{
|
||||
kobj_del_list_t del;
|
||||
int map_len = tag.map_buf_len;
|
||||
|
||||
kobj_del_list_init(&del);
|
||||
|
||||
for (int i = 0; i < map_len; i++)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
vpage_t dst_page = vpage_create_raw(dst_ipc->map_buf[i]);
|
||||
vpage_t src_page = vpage_create_raw(src_ipc->map_buf[i]);
|
||||
|
||||
if ((src_page.flags & VPAGE_FLAGS_MAP) || is_reply)
|
||||
{
|
||||
ret = obj_map_src_dst(&dst_tk->obj_space, &src_tk->obj_space,
|
||||
vpage_get_obj_handler(dst_page),
|
||||
vpage_get_obj_handler(src_page), dst_tk->lim,
|
||||
vpage_get_attrs(src_page), &del);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
kobj_del_list_to_do(&del);
|
||||
}
|
||||
ipc_dat_copy_raw(&dst_tk->obj_space, &src_tk->obj_space, dst_tk->lim, dst_ipc, src_ipc, tag, is_reply);
|
||||
dst_ipc->user[2] = task_pid_get(src_tk);
|
||||
memcpy(dst_ipc->msg_buf, src_ipc->msg_buf,
|
||||
MIN(tag.msg_buf_len * WORD_BYTES, IPC_MSG_SIZE));
|
||||
|
||||
dst_th->msg.tag = tag;
|
||||
return 0;
|
||||
}
|
||||
@@ -918,10 +929,11 @@ again:;
|
||||
if (to->ipc_status == THREAD_IPC_ABORT)
|
||||
{
|
||||
ref_counter_dec_and_release(&to->ref, &to->kobj);
|
||||
spinlock_set(&to->recv_lock, status_lock2);
|
||||
return -ECANCELED;
|
||||
}
|
||||
spinlock_set(&to->recv_lock, status_lock2);
|
||||
thread_sched(TRUE);
|
||||
spinlock_set(&to->recv_lock, status_lock2);
|
||||
preemption();
|
||||
goto again;
|
||||
}
|
||||
@@ -946,7 +958,6 @@ again:;
|
||||
assert(to->status == THREAD_SUSPEND && to->ipc_status == THREAD_RECV);
|
||||
thread_timeout_del_from_send_queue_remote(to);
|
||||
}
|
||||
// to->last_send_th = NULL;
|
||||
ref_counter_dec_and_release(&to->ref, &to->kobj);
|
||||
spinlock_set(&to->recv_lock, status_lock2);
|
||||
return 0;
|
||||
@@ -1225,43 +1236,84 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
{
|
||||
case IPC_FAST_REPLAY:
|
||||
{
|
||||
thread_task_restore(cur_th); //!< 切换task到目的task,并且进行备份
|
||||
arch_set_user_sp((umword_t)(cur_th->usp_backup));
|
||||
msg_tag_t in_tag = msg_tag_init(f->regs[0]);
|
||||
task_t *old_task = thread_get_bind_task(cur_th);
|
||||
|
||||
//! 解锁bitmap
|
||||
*(cur_task->nofity_bitmap) &= ~(1 << MIN(f->regs[2], cur_task->nofity_bitmap_len));
|
||||
slist_del(&cur_th->fast_ipc_node);
|
||||
|
||||
ret = thread_fast_ipc_restore(cur_th); // 还原栈和usp
|
||||
if (ret < 0)
|
||||
{
|
||||
mutex_unlock(&old_task->nofity_lock);
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
task_t *cur_task = thread_get_current_task();
|
||||
ipc_msg_t *dst_ipc = (void *)cur_th->msg.msg;
|
||||
ipc_msg_t *src_ipc = (void *)old_task->nofity_msg_buf;
|
||||
ret = ipc_dat_copy_raw(&cur_task->obj_space, &old_task->obj_space, cur_task->lim,
|
||||
dst_ipc, src_ipc, in_tag, FALSE);
|
||||
if (ret < 0)
|
||||
{
|
||||
mutex_unlock(&old_task->nofity_lock);
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
mutex_unlock(&old_task->nofity_lock);
|
||||
pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1;
|
||||
|
||||
cur_pf->regs[5] = (umword_t)(thread_get_current_task()->mm_space.mm_block);
|
||||
cur_pf->regs[5] = (umword_t)(cur_task->mm_space.mm_block);
|
||||
extern void mpu_switch_to_task(struct task * tk);
|
||||
mpu_switch_to_task(thread_get_current_task());
|
||||
|
||||
return msg_tag_init4(0, 0, 0, 0);
|
||||
mpu_switch_to_task(cur_task);
|
||||
ref_counter_dec_and_release(&old_task->ref_cn, &old_task->kobj);
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
break;
|
||||
case IPC_FAST_CALL:
|
||||
{
|
||||
// 线程中的task
|
||||
// 内核栈返回需要修改r9
|
||||
// 还原用户站
|
||||
msg_tag_t in_tag = msg_tag_init(f->regs[0]);
|
||||
// 1.需要切换的资源有r9,task,和用户栈
|
||||
// 2.在对方进程中被杀死,需要还原当前线程的状态,并返回一个错误
|
||||
// 3.多线程访问时,服务端提供一个小的用户线程栈,然后内核到用户部分为临界区域,在服务端重新分配用户栈用,使用新的用户栈。
|
||||
// 4.fastipc嵌套访问会有问题,内核必须要提供一个软件上的调用栈。
|
||||
task_t *to_task = thread_get_bind_task(to_th);
|
||||
|
||||
if (to_task->nofity_point == NULL)
|
||||
{
|
||||
return msg_tag_init4(0, 0, 0, -EIO);
|
||||
}
|
||||
|
||||
thread_set_task_and_backup(cur_th, to_task); //!< 切换task到目的task,并且进行备份
|
||||
|
||||
_to_unlock:
|
||||
if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len))
|
||||
{
|
||||
thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/
|
||||
preemption();
|
||||
goto _to_unlock;
|
||||
}
|
||||
mutex_lock(&to_task->nofity_lock);
|
||||
if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len))
|
||||
{
|
||||
mutex_unlock(&to_task->nofity_lock);
|
||||
thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/
|
||||
preemption();
|
||||
goto _to_unlock;
|
||||
}
|
||||
ref_counter_inc((&to_task->ref_cn));
|
||||
//!< 执行目标线程时用的是当前线程的资源,这里还需要备份当前线程的上下文。
|
||||
void *prev_usp = (void *)arch_get_user_sp();
|
||||
ret = thread_fast_ipc_save(cur_th, to_task, (void *)(to_task->nofity_stack - 4 * 8)); //!< 备份栈和usp
|
||||
if (ret >= 0)
|
||||
{
|
||||
ipc_msg_t *dst_ipc = (void *)to_task->nofity_msg_buf;
|
||||
ipc_msg_t *src_ipc = (void *)cur_th->msg.msg;
|
||||
ret = ipc_dat_copy_raw(&to_task->obj_space, &cur_task->obj_space, to_task->lim,
|
||||
dst_ipc, src_ipc, in_tag, FALSE);
|
||||
if (ret >= 0)
|
||||
{
|
||||
dst_ipc->user[2] = task_pid_get(cur_task); // 设置pid
|
||||
|
||||
slist_add(&to_task->nofity_theads_head, &cur_th->fast_ipc_node);
|
||||
|
||||
cur_th->usp_backup = prev_usp;//!<保存之前的用户栈
|
||||
arch_set_user_sp(to_task->nofity_stack - 32); //!<重新设置
|
||||
pf_s_t *usr_stask_point = (void *)arch_get_user_sp();
|
||||
|
||||
// usr_stask_point->rg0[0] = 0x1111;
|
||||
// usr_stask_point->rg0[1] = 0x2222;
|
||||
// usr_stask_point->rg0[2] = 0x3333;
|
||||
// usr_stask_point->rg0[3] = 0x4444;
|
||||
usr_stask_point->r12 = 0x12121212;
|
||||
usr_stask_point->xpsr = 0x01000000L;
|
||||
usr_stask_point->lr = (umword_t)NULL; //!< 线程退出时调用的函数
|
||||
@@ -1270,10 +1322,28 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1; //!< 获得内核栈栈顶
|
||||
cur_pf->regs[5] = (umword_t)(to_task->mm_space.mm_block); // 重新设置r9寄存器
|
||||
|
||||
//! 寄存器传参数
|
||||
f->regs[0] = in_tag.raw;
|
||||
f->regs[1] = f->regs[2];
|
||||
f->regs[2] = f->regs[3];
|
||||
f->regs[3] = f->regs[4];
|
||||
|
||||
extern void mpu_switch_to_task(struct task * tk);
|
||||
mpu_switch_to_task(to_task);
|
||||
|
||||
return msg_tag_init4(0, 0, 0, 0);
|
||||
return in_tag;
|
||||
}
|
||||
else
|
||||
{
|
||||
ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj);
|
||||
mutex_unlock(&to_task->nofity_lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj);
|
||||
mutex_unlock(&to_task->nofity_lock);
|
||||
}
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
break;
|
||||
case IPC_CALL:
|
||||
@@ -1376,14 +1446,7 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p,
|
||||
{
|
||||
case SET_EXEC_REGS:
|
||||
{
|
||||
umword_t stack_bottom = 0;
|
||||
|
||||
if (f->regs[4]) //!< cp_stack
|
||||
{
|
||||
stack_bottom = (umword_t)(thread_get_msg_buf(cur_th));
|
||||
}
|
||||
thread_set_exc_regs(tag_th, f->regs[1], f->regs[2], f->regs[3],
|
||||
stack_bottom);
|
||||
thread_set_exc_regs(tag_th, f->regs[1], f->regs[2], f->regs[3]);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -72,9 +72,15 @@ static void knl_main(void)
|
||||
msg_tag_t tag;
|
||||
umword_t user_id;
|
||||
ipc_msg_t *msg = (ipc_msg_t *)knl_msg_buf;
|
||||
|
||||
if (pos->pid != 0)
|
||||
{
|
||||
msg->msg_buf[0] = 1; /*KILL_TASK*/
|
||||
msg->msg_buf[1] = pos->pid;
|
||||
msg->msg_buf[2] = 0;
|
||||
|
||||
if (thread_get_ipc_state(init_thread) != THREAD_IPC_ABORT)
|
||||
{
|
||||
int ret = thread_ipc_call(init_thread, msg_tag_init4(0, 3, 0, 0x0005 /*PM_PROT*/),
|
||||
&tag, ipc_timeout_create2(3000, 3000), &user_id, TRUE);
|
||||
|
||||
@@ -83,6 +89,8 @@ static void knl_main(void)
|
||||
printk("%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
task_kill(pos);
|
||||
pos = next;
|
||||
}
|
||||
@@ -151,7 +159,7 @@ static void knl_init_2(void)
|
||||
cpio_get_size(cpio_images), (paddr_t)cpio_images, 0) >= 0);
|
||||
thread_set_msg_buf(init_thread, (void *)init_msg_buf, (void *)CONFIG_MSG_BUF_VADDR);
|
||||
thread_user_pf_set(init_thread, (void *)(entry), (void *)0xdeaddead,
|
||||
NULL, 0);
|
||||
NULL);
|
||||
#else
|
||||
app_info_t *app;
|
||||
|
||||
@@ -167,7 +175,7 @@ static void knl_init_2(void)
|
||||
|
||||
thread_set_msg_buf(init_thread, (char *)(init_task->mm_space.mm_block) + app->i.ram_size, (char *)(init_task->mm_space.mm_block) + app->i.ram_size);
|
||||
thread_user_pf_set(init_thread, (void *)(app), (void *)((umword_t)sp_addr_top - 8),
|
||||
init_task->mm_space.mm_block, 0);
|
||||
init_task->mm_space.mm_block);
|
||||
#endif
|
||||
thread_bind(init_thread, &init_task->kobj);
|
||||
assert(obj_map_root(&init_thread->kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, THREAD_PROT)));
|
||||
@@ -180,7 +188,7 @@ static void knl_init_2(void)
|
||||
assert(obj_map_root(kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, i)));
|
||||
}
|
||||
}
|
||||
init_thread->sche.prio = 2;
|
||||
init_thread->sche.prio = 15;
|
||||
init_task->pid = 0;
|
||||
thread_ready(init_thread, FALSE);
|
||||
#endif
|
||||
@@ -197,6 +205,7 @@ void task_knl_kill(thread_t *kill_thread, bool_t is_knl)
|
||||
|
||||
status2 = spinlock_lock(&del_lock);
|
||||
thread_suspend(kill_thread);
|
||||
kill_thread->ipc_status = THREAD_IPC_ABORT;
|
||||
slist_add_append(&del_task_head, &task->del_node);
|
||||
spinlock_set(&del_lock, status2);
|
||||
}
|
||||
|
||||
37
mkrtos_knl/lib/stack.c
Normal file
37
mkrtos_knl/lib/stack.c
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
#include "types.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "stack.h"
|
||||
|
||||
void stack_init(stack_t *stack, void *stack_data, int len, int item_size)
|
||||
{
|
||||
assert(stack);
|
||||
assert(stack_data);
|
||||
memset(stack_data, 0, len * item_size);
|
||||
stack->top = -1;
|
||||
stack->len = len;
|
||||
stack->item_size = item_size;
|
||||
stack->data = stack_data;
|
||||
}
|
||||
int stack_push(stack_t *stack, void *item)
|
||||
{
|
||||
if (stack->top < stack->len)
|
||||
{
|
||||
++(stack->top);
|
||||
memcpy((uint8_t *)(stack->data) + stack->top * stack->item_size,
|
||||
item, stack->item_size);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int stack_pop(stack_t *stack, void *item)
|
||||
{
|
||||
if (stack->top != -1)
|
||||
{
|
||||
memcpy(item, (uint8_t *)(stack->data) + stack->top * stack->item_size, stack->item_size);
|
||||
stack->top--;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -16,4 +16,9 @@ msg_tag_t task_unmap(obj_handler_t task_han, vpage_t vpage);
|
||||
msg_tag_t task_alloc_ram_base(obj_handler_t task_han, umword_t size, addr_t *alloc_addr);
|
||||
msg_tag_t task_copy_data(obj_handler_t task_obj, void *st_addr, umword_t size);
|
||||
msg_tag_t task_copy_data_to(obj_handler_t task_obj, obj_handler_t dst_task_obj, void *st_addr, void *dst_addr, umword_t size);
|
||||
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func, addr_t stack);
|
||||
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func,
|
||||
addr_t stack, umword_t stack_size,
|
||||
void *bitmap, int bitmap_len,
|
||||
void *msg_buf);
|
||||
msg_tag_t task_com_unlock(obj_handler_t task_obj);
|
||||
msg_tag_t task_com_lock(obj_handler_t task_obj);
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#define MSG_BUF_RECV_R_FLAGS 0x02U //!< 接收上次发送数据的接收者
|
||||
#define MSG_BUF_REPLY_FLAGS 0x04U //!<
|
||||
|
||||
#define IPC_MSG_SIZE (CONFIG_THREAD_IPC_MSG_LEN * sizeof(void*))
|
||||
#define MAP_BUF_SIZE (CONFIG_THREAD_MAP_BUF_LEN * sizeof(void*))
|
||||
#define IPC_USER_SIZE (CONFIG_THREAD_USER_BUF_LEN * sizeof(void*))
|
||||
#define IPC_MSG_SIZE (CONFIG_THREAD_IPC_MSG_LEN * sizeof(void *))
|
||||
#define MAP_BUF_SIZE (CONFIG_THREAD_MAP_BUF_LEN * sizeof(void *))
|
||||
#define IPC_USER_SIZE (CONFIG_THREAD_USER_BUF_LEN * sizeof(void *))
|
||||
|
||||
#if IS_ENABLED(CONFIG_VCPU)
|
||||
#define IPC_VPUC_MSG_OFFSET (3 * 1024) //!< vcpu 传递消息的偏移量
|
||||
@@ -71,8 +71,8 @@ msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj, obj_handler_t ip
|
||||
msg_tag_t thread_ipc_reply(msg_tag_t in_tag, ipc_timeout_t timeout);
|
||||
msg_tag_t thread_ipc_send(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout);
|
||||
msg_tag_t thread_ipc_call(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout);
|
||||
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj);
|
||||
msg_tag_t thread_ipc_fast_replay(obj_handler_t target_obj);
|
||||
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj, umword_t arg0, umword_t arg1, umword_t arg2);
|
||||
msg_tag_t thread_ipc_fast_replay(msg_tag_t in_tag, obj_handler_t target_obj, int unlock_bitmap);
|
||||
|
||||
static inline ipc_msg_t *thread_get_cur_ipc_msg(void)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,9 @@ enum task_op_code
|
||||
TASK_COPY_DATA,
|
||||
TASK_SET_OBJ_NAME,
|
||||
TASK_COPY_DATA_TO, //!< 从当前task拷贝数据到目的task
|
||||
TASK_SET_COM_POINT
|
||||
TASK_SET_COM_POINT,
|
||||
TASK_COM_UNLOCK,
|
||||
TASK_COM_LOCK,
|
||||
};
|
||||
|
||||
msg_tag_t task_set_obj_name(obj_handler_t dst_task, obj_handler_t obj, const char *name)
|
||||
@@ -196,13 +198,50 @@ msg_tag_t task_copy_data_to(obj_handler_t task_obj, obj_handler_t dst_task_obj,
|
||||
|
||||
return msg_tag_init(r0);
|
||||
}
|
||||
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func, addr_t stack)
|
||||
msg_tag_t task_set_com_point(obj_handler_t task_obj, void *com_point_func, addr_t stack, umword_t stack_size, void *bitmap, int bitmap_len, void *msg_buf)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
|
||||
mk_syscall(syscall_prot_create(TASK_SET_COM_POINT, TASK_PROT, task_obj).raw,
|
||||
com_point_func,
|
||||
stack,
|
||||
stack_size,
|
||||
bitmap,
|
||||
bitmap_len,
|
||||
msg_buf);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
: ARCH_REG_0, ARCH_REG_1);
|
||||
|
||||
return msg_tag_init(r0);
|
||||
}
|
||||
msg_tag_t task_com_unlock(obj_handler_t task_obj)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
|
||||
mk_syscall(syscall_prot_create(TASK_COM_UNLOCK, TASK_PROT, task_obj).raw,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
: ARCH_REG_0, ARCH_REG_1);
|
||||
|
||||
return msg_tag_init(r0);
|
||||
}
|
||||
|
||||
msg_tag_t task_com_lock(obj_handler_t task_obj)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
|
||||
mk_syscall(syscall_prot_create(TASK_COM_LOCK, TASK_PROT, task_obj).raw,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -92,15 +92,15 @@ msg_tag_t thread_ipc_call(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_tim
|
||||
: ARCH_REG_0);
|
||||
return msg_tag_init(r0);
|
||||
}
|
||||
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj)
|
||||
msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj, umword_t arg0, umword_t arg1, umword_t arg2)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, target_obj, TRUE).raw,
|
||||
in_tag.raw,
|
||||
IPC_FAST_CALL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
arg0,
|
||||
arg1,
|
||||
arg2,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
@@ -108,13 +108,13 @@ msg_tag_t thread_ipc_fast_call(msg_tag_t in_tag, obj_handler_t target_obj)
|
||||
: ARCH_REG_0);
|
||||
return msg_tag_init(r0);
|
||||
}
|
||||
msg_tag_t thread_ipc_fast_replay(obj_handler_t target_obj)
|
||||
msg_tag_t thread_ipc_fast_replay(msg_tag_t in_tag, obj_handler_t target_obj, int unlock_bitmap)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
mk_syscall(syscall_prot_create4(DO_IPC, THREAD_PROT, target_obj, TRUE).raw,
|
||||
0,
|
||||
in_tag.raw,
|
||||
IPC_FAST_REPLAY,
|
||||
0,
|
||||
unlock_bitmap,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
@@ -147,7 +147,7 @@ msg_tag_t thread_msg_buf_set(obj_handler_t obj, void *msg)
|
||||
register volatile umword_t r1 asm(ARCH_REG_1);
|
||||
register volatile umword_t r2 asm(ARCH_REG_2);
|
||||
|
||||
mk_syscall(syscall_prot_create(MSG_BUG_SET, THREAD_PROT, obj).raw,
|
||||
mk_syscall(syscall_prot_create4(MSG_BUG_SET, THREAD_PROT, obj, TRUE).raw,
|
||||
0,
|
||||
msg,
|
||||
0,
|
||||
|
||||
@@ -29,26 +29,81 @@
|
||||
#include "parse_cfg.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
static ATTR_ALIGN(8) uint8_t cons_stack[2048];
|
||||
#include <string.h>
|
||||
#define DEFAULT_INIT_CFG "init.cfg"
|
||||
static void init_com_point_test_func(int r0,int r1,int r2,int r3)
|
||||
|
||||
#define STACK_SIZE 2048
|
||||
#define STASCK_NUM 4
|
||||
static ATTR_ALIGN(8) uint8_t com_stack[512];
|
||||
static ATTR_ALIGN(8) uint8_t cons_stack[STASCK_NUM][STACK_SIZE];
|
||||
static uint8_t cons_msg_buf[STASCK_NUM][MSG_BUG_LEN];
|
||||
static umword_t cons_stack_bitmap;
|
||||
static uint8_t cons_msg_buf_main[MSG_BUG_LEN];
|
||||
static inline umword_t arch_get_sp(void)
|
||||
{
|
||||
printf("comm r0:%d r1:%d r2:%d r3:%d\n", r0, r1, r2, r3);
|
||||
printf("comm\n");
|
||||
printf("comm\n");
|
||||
printf("comm\n");
|
||||
printf("comm\n");
|
||||
thread_ipc_fast_replay(-1);
|
||||
umword_t ret;
|
||||
__asm__ __volatile__(
|
||||
"mov %0, sp\n"
|
||||
: "=r"(ret)
|
||||
:
|
||||
:);
|
||||
return ret;
|
||||
}
|
||||
#define SET_SP(sp) \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__("mov sp, %0" ::"r"(sp)); \
|
||||
__asm__ __volatile__("" \
|
||||
: \
|
||||
: \
|
||||
: "sp"); \
|
||||
} while (0)
|
||||
|
||||
int setsp(int i, void *stack, msg_tag_t tag, int arg0, int arg1);
|
||||
|
||||
void last_process(int j, msg_tag_t tag, int arg0, int arg1)
|
||||
{
|
||||
thread_msg_buf_set(-1, (void *)(cons_msg_buf[j]));
|
||||
task_com_unlock(TASK_THIS);
|
||||
|
||||
// printf("j:%d sp:0x%x\n", j, arch_get_sp());
|
||||
// printf("j:%d comm tag:%x r0:%d r1:%d\n", j, tag.raw, arg0, arg1);
|
||||
// printf("%s\n", cons_msg_buf[j]);
|
||||
// strcpy((void *)cons_msg_buf[j], "okay");
|
||||
|
||||
// u_sleep_ms(100);
|
||||
|
||||
// *((uint8_t *)0) = 0;
|
||||
task_com_lock(TASK_THIS);
|
||||
memcpy(cons_msg_buf_main, cons_msg_buf[j], MSG_BUG_LEN);
|
||||
tag = msg_tag_init4(0, 2, 0, 0);
|
||||
thread_ipc_fast_replay(tag, -1, j);
|
||||
}
|
||||
static void init_com_point_test_func(msg_tag_t tag, int arg0, int arg1, int arg2)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < STASCK_NUM; i++)
|
||||
{
|
||||
if ((cons_stack_bitmap & (1 << i)) == 0)
|
||||
{
|
||||
cons_stack_bitmap |= (1 << i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
memcpy(cons_msg_buf[i], cons_msg_buf_main, MSG_BUG_LEN);
|
||||
setsp(i, &cons_stack[i][STACK_SIZE - 8], tag, arg0, arg1);
|
||||
}
|
||||
|
||||
int main(int argc, char *args[])
|
||||
{
|
||||
int ret;
|
||||
uenv_t *env;
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
thread_run(-1, 4);
|
||||
#endif
|
||||
task_set_com_point(TASK_THIS,&init_com_point_test_func, (addr_t)(cons_stack + sizeof(cons_stack) - 8));
|
||||
task_set_com_point(TASK_THIS, &init_com_point_test_func, (addr_t)com_stack,
|
||||
sizeof(com_stack), &cons_stack_bitmap, STASCK_NUM, cons_msg_buf_main);
|
||||
|
||||
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_init");
|
||||
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_init");
|
||||
|
||||
12
mkrtos_user/server/init/src/setsp.S
Normal file
12
mkrtos_user/server/init/src/setsp.S
Normal file
@@ -0,0 +1,12 @@
|
||||
.syntax unified
|
||||
@ .cpu cortex-m3
|
||||
.thumb
|
||||
.global setsp
|
||||
.global last_process
|
||||
/**
|
||||
* @brief syscall结束时到这儿
|
||||
*/
|
||||
.type setsp, %function
|
||||
setsp:
|
||||
mov sp, r1
|
||||
bl last_process
|
||||
@@ -9,14 +9,47 @@
|
||||
#include <u_task.h>
|
||||
#include <u_thread.h>
|
||||
#include <u_env.h>
|
||||
#include <pthread.h>
|
||||
void *test_func(void *arg)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
ipc_msg_t *msg;
|
||||
|
||||
tag = thread_msg_buf_get(-1, (void *)(&msg), NULL);
|
||||
strcpy((void *)msg->msg_buf, "hello");
|
||||
|
||||
for (int i = 0; i < 10000; i++)
|
||||
{
|
||||
|
||||
thread_ipc_fast_call(msg_tag_init4(0, 2, 0, 0), u_get_global_env()->ns_hd, 1111, 2222, 3333);
|
||||
// printf("%s\n", (void *)msg->msg_buf);
|
||||
}
|
||||
// while (1)
|
||||
// {
|
||||
// u_sleep_ms(100000);
|
||||
// }
|
||||
return NULL;
|
||||
}
|
||||
pthread_t pth1;
|
||||
pthread_t pth2;
|
||||
pthread_t pth3;
|
||||
pthread_t pth4;
|
||||
void fast_ipc_test(void)
|
||||
{
|
||||
pthread_create(&pth1, NULL, test_func, NULL);
|
||||
pthread_create(&pth2, NULL, test_func, NULL);
|
||||
pthread_create(&pth3, NULL, test_func, NULL);
|
||||
pthread_create(&pth4, NULL, test_func, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char *args[])
|
||||
{
|
||||
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_sh");
|
||||
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_sh");
|
||||
#if 1
|
||||
#if 0
|
||||
thread_run(-1, 3);
|
||||
#endif
|
||||
// thread_ipc_fast_call(msg_tag_init(0), u_get_global_env()->ns_hd);
|
||||
fast_ipc_test();
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
printf("args[%d]:%s\n", i, args[i]);
|
||||
|
||||
Reference in New Issue
Block a user