0 Preface/Foreword
1 线程(thread)
1.1 线程定义
1.1.1 USE_BASIC_THREADS(宏定义)
经过以上步骤(makefile包含),USE_BASIC_THREADS在编译阶段被定义到相应的模块中。
1.1.2 定义线程ID变量
osThreadId app_thread_tid;
1.1.3 线程入口函数(entry point)
static void app_thread(void const *argument);
static void app_thread(void const *argument)
{
while(1){
app_mailbox_get();
}
}
1.1.4 定义线程结构体变量 (osThreadDef)
osThreadDef含有5个参数:
- name,线程入口地址,即线程函数入口
- priority,线程的优先级
- instances,该参数,在宏展开时没有实际作用。(一般使用时改值设置为1,为什么呢?)
- stacksz,线程堆栈大小
- task_name,其实就是线程入口地址名字的字符串
注意,thread堆栈的大小由makefile文件控制,thread堆栈的地址为一个数组首地址(转换很有意思,可以参考cmsis_os.h文件),该数组的类似是unit64。
osThreadDef(app_thread, osPriorityAboveNormal, 1, APP_THREAD_STACK_SIZE, "app_thread");
APP_THREAD_STACK_SIZE的值为:1024 * 2
根据以下设置可知APP_THREAD_STACK_SIZE的值。
1.2 创建线程对象(object)
app_thread_tid = osThreadCreate(osThread(app_thread), NULL);
osThreadCreate:该函数的接口在cmsis_os1.c中定义(为了满足向后兼容性),定义中最终调用的函数还是: osThreadNew(具体实现在库中)
// Thread
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) {if (thread_def == NULL) {
return (osThreadId)NULL;
}
return osThreadNew((osThreadFunc_t)thread_def->pthread, argument, &thread_def->attr);
}
/// Create a thread and add it to Active Threads.
osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
osThreadId_t thread_id;EvrRtxThreadNew(func, argument, attr);
if (IsIrqMode() || IsIrqMasked()) {
EvrRtxThreadError(NULL, (int32_t)osErrorISR);
thread_id = NULL;
} else {
thread_id = __svcThreadNew(func, argument, attr);
}
return thread_id;
}
1.3 线程运行
static void app_thread(void const *argument)
{
while(1){
app_mailbox_get();
}
}int app_mailbox_get(void)
{
osEvent evt;
while(1){
evt = osMailGet(app_mailbox, millisec);
if (evt.status == osEventMail) {
millisec = 0;
APP_MESSAGE_BLOCK* msg_p = NULL;
if(((APP_MESSAGE_BLOCK *)evt.value.p)->mod_level == APP_MOD_LEVEL_0) {
msg_p = (APP_MESSAGE_BLOCK*)osMailAlloc(app_mailbox_level0, 0);
ASSERT(msg_p, "osMailAlloc error0 %p",msg_p);
memcpy((uint8_t*)msg_p,(uint8_t*)evt.value.p,sizeof(APP_MESSAGE_BLOCK));
osMailPut(app_mailbox_level0, msg_p);
}else if(((APP_MESSAGE_BLOCK *)evt.value.p)->mod_level == APP_MOD_LEVEL_1) {
msg_p = (APP_MESSAGE_BLOCK*)osMailAlloc(app_mailbox_level1, 0);
ASSERT(msg_p, "osMailAlloc error1 %p",msg_p);
memcpy((uint8_t*)msg_p,(uint8_t*)evt.value.p,sizeof(APP_MESSAGE_BLOCK));
osMailPut(app_mailbox_level1, msg_p);
}else {
msg_p = (APP_MESSAGE_BLOCK*)osMailAlloc(app_mailbox_level2, 0);
ASSERT(msg_p, "osMailAlloc error2 %p",msg_p);
memcpy((uint8_t*)msg_p,(uint8_t*)evt.value.p,sizeof(APP_MESSAGE_BLOCK));
osMailPut(app_mailbox_level2, msg_p);
}
osMailFree(app_mailbox, (APP_MESSAGE_BLOCK *)evt.value.p);
}else{
break;
}
}evt = osMailGet(app_mailbox_level0, 0);
if (evt.status == osEventMail) {
app_mailbox_process((APP_MESSAGE_BLOCK *)evt.value.p);
osMailFree(app_mailbox_level0, (APP_MESSAGE_BLOCK *)evt.value.p);
return 0;
}evt = osMailGet(app_mailbox_level1, 0);
if (evt.status == osEventMail) {
app_mailbox_process((APP_MESSAGE_BLOCK *)evt.value.p);
osMailFree(app_mailbox_level1, (APP_MESSAGE_BLOCK *)evt.value.p);
return 0;
}evt = osMailGet(app_mailbox_level2, 0);
if (evt.status == osEventMail) {
app_mailbox_process((APP_MESSAGE_BLOCK *)evt.value.p);
osMailFree(app_mailbox_level2, (APP_MESSAGE_BLOCK *)evt.value.p);
return 0;
}
millisec = osWaitForever;
return -1;
}