一、rt_application_init函数调用
二、函数分析
void rt_application_init(void)
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(tid != RT_NULL);
#else
rt_err_t result;
tid = &main_thread;
result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(result == RT_EOK);
(void)result;
#endif
rt_thread_startup(tid);
}
1、rt_thread_create
rt_thread_t rt_thread_create(const char *name,
void (*entry)(void *parameter),
void *parameter,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
{
struct rt_thread *thread;
void *stack_start;
thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread,
name);
if (thread == RT_NULL)
return RT_NULL;
stack_start = (void *)RT_KERNEL_MALLOC(stack_size);
if (stack_start == RT_NULL)
{
rt_object_delete((rt_object_t)thread);
return RT_NULL;
}
_rt_thread_init(thread,
name,
entry,
parameter,
stack_start,
stack_size,
priority,
tick);
return thread;
}
RTM_EXPORT(rt_thread_create);
1、rt_object_allocate
1、rt_object_get_information
type = RT_Object_Class_Thread;
information = rt_object_get_information(type);
2、RT_KERNEL_MALLOC
分配rt_thread 结构体大小空间。
object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
等价于
object = (struct rt_object *)rt_malloc(information->object_size);
调用后,堆使用情况如下:
3、初始化
rt_memset(object, 0x0, information->object_size);
object->type = type;
object->flag = 0;
rt_strncpy(object->name, name, RT_NAME_MAX);
4、rt_list_insert_after
将新分配空间插入到rt_object_container[RT_Object_Class_Thread] 列表中。
2、RT_KERNEL_MALLOC
stack_start = (void *)RT_KERNEL_MALLOC(stack_size);
为main 线程分配栈空间。
3、_rt_thread_init
1、rt_list_init
rt_list_init(&(thread->tlist));
2、初始化 - 01
thread->entry = (void *)entry;
thread->parameter = parameter;
thread->stack_addr = stack_start;
thread->stack_size = stack_size;
3、rt_memset
rt_memset(thread->stack_addr, '#', thread->stack_size);
设置栈空间数据为"#"。
4、rt_hw_stack_init
rt_uint8_t *rt_hw_stack_init(void *tentry,
void *parameter,
rt_uint8_t *stack_addr,
void *texit)
{
struct stack_frame *stack_frame;
rt_uint8_t *stk;
unsigned long i;
stk = stack_addr + sizeof(rt_uint32_t);
stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
stk -= sizeof(struct stack_frame);
stack_frame = (struct stack_frame *)stk;
for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
{
((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
}
stack_frame->exception_stack_frame.r0 = (unsigned long)parameter;
stack_frame->exception_stack_frame.r1 = 0;
stack_frame->exception_stack_frame.r2 = 0;
stack_frame->exception_stack_frame.r3 = 0;
stack_frame->exception_stack_frame.r12 = 0;
stack_frame->exception_stack_frame.lr = (unsigned long)texit;
stack_frame->exception_stack_frame.pc = (unsigned long)tentry;
stack_frame->exception_stack_frame.psr = 0x01000000L;
return stk;
}
设置栈初始值,并返回栈顶地址。
5、初始化 - 02
RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);
thread->init_priority = priority;
thread->current_priority = priority;
thread->number_mask = 0;
thread->init_tick = tick;
thread->remaining_tick = tick;
thread->error = RT_EOK;
thread->stat = RT_THREAD_INIT;
thread->cleanup = 0;
thread->user_data = 0;
6、rt_timer_init
void rt_timer_init(rt_timer_t timer,
const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag)
{
RT_ASSERT(timer != RT_NULL);
rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);
_rt_timer_init(timer, timeout, parameter, time, flag);
}
RTM_EXPORT(rt_timer_init);
rt_timer_init(&(thread->thread_timer),
thread->name,
rt_thread_timeout,
thread,
0,
RT_TIMER_FLAG_ONE_SHOT);
1、rt_object_init
void rt_object_init(struct rt_object *object,
enum rt_object_class_type type,
const char *name)
{
register rt_base_t temp;
struct rt_object_information *information;
#ifdef RT_USING_MODULE
struct rt_dlmodule *module = dlmodule_self();
#endif
information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL);
object->type = type | RT_Object_Class_Static;
rt_strncpy(object->name, name, RT_NAME_MAX);
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
temp = rt_hw_interrupt_disable();
#ifdef RT_USING_MODULE
if (module)
{
rt_list_insert_after(&(module->object_list), &(object->list));
object->module_id = (void *)module;
}
else
#endif
{
rt_list_insert_after(&(information->object_list), &(object->list));
}
rt_hw_interrupt_enable(temp);
}
rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);
1、获取rt_object_container[RT_Object_Class_Timer] 元素。 2、初始化thread->thread_timer 。 3、调用rt_list_insert_after 函数将thread->thread_timer 插入到链表中。
2、_rt_timer_init
static void _rt_timer_init(rt_timer_t timer,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag)
{
int i;
timer->parent.flag = flag;
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
timer->timeout_func = timeout;
timer->parameter = parameter;
timer->timeout_tick = 0;
timer->init_tick = time;
for (i = 0; i < RT_TIMER_SKIP_LIST_LEVEL; i++)
{
rt_list_init(&(timer->row[i]));
}
}
_rt_timer_init(timer, timeout, parameter, time, flag);
1、初始化thread->thread_timer 。 2、初始化timer->row[i] 。
7、初始化 - 03
#ifdef RT_USING_SIGNALS
thread->sig_mask = 0x00;
thread->sig_pending = 0x00;
thread->sig_ret = RT_NULL;
thread->sig_vectors = RT_NULL;
thread->si_list = RT_NULL;
#endif
8、_rt_thread_init执行结果
2、rt_thread_startup
rt_err_t rt_thread_startup(rt_thread_t thread)
{
RT_ASSERT(thread != RT_NULL);
RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
thread->current_priority = thread->init_priority;
#if RT_THREAD_PRIORITY_MAX > 32
thread->number = thread->current_priority >> 3;
thread->number_mask = 1L << thread->number;
thread->high_mask = 1L << (thread->current_priority & 0x07);
#else
thread->number_mask = 1L << thread->current_priority;
#endif
RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%d\n",
thread->name, thread->init_priority));
thread->stat = RT_THREAD_SUSPEND;
rt_thread_resume(thread);
if (rt_thread_self() != RT_NULL)
{
rt_schedule();
}
return RT_EOK;
}
RTM_EXPORT(rt_thread_startup);
rt_thread_startup(tid);
三、总结
|