RTX RTOS 操作实例分析之---线程(thread)

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();
    }
}

1.3.1 app_mailbox_get(consumer,分发消息)

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;
}

运行逻辑:

NOTE:消息生产者通过调用app_mailbox_put 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/597736.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开启虚拟机时出现此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态怎么解决

问题描述 虚拟机安装完成后,点击开启此虚拟机弹出系统提示 原因分析: Intel VT-x 处于禁用状态,需要开启。 解决方案: 以联系小新笔记本电脑为例,进入BIOS界面,将Intel Virtual Technology设置成Enabl…

什么是物联网云平台

在信息化和智能化浪潮的推动下,物联网云平台作为连接物理世界与数字世界的桥梁,正日益成为企业数字化转型的关键支撑。物联网云平台通过集成先进的云计算、大数据分析和人工智能等技术,为企业提供了高效、安全、智能的数据处理和应用服务&…

主食冻干哪个牌子好?热门大牌真实实测分享,轻松避雷!

在选购主食冻干时,很多铲屎官都面临着选进口还是国产的难题。很多铲屎官认为进口产品在品控和配方上更优秀,但实际营养指标却逊于国产,价格也不菲。所以不免选购时会犹豫,最后抱着试一试的心态盲入主食冻干,运气好&…

【C语言】_文件类型,结束判定与文件缓冲区

目录 1. 文本文件和二进制文件 2. 文件读取结束的判定 3. 文件缓冲区 1. 文本文件和二进制文件 根据数据的组织形式,数据文件被称为文本文件或二进制文件; 数据在内存中以二进制的形式存储,如果不加转换地输出到外存,就是二进…

体验OceanBase 的binlog service

OceanBase对MySQL具备很好的兼容性。目前,已经发布了开源版的binlog service工具,该工具能够将OceanBase特有的clog模式转换成binlog模式,以便下游工具如canal、flink cdc等使用。今天,我们就来简单体验一下这个binlog service的功…

Bigtable [OSDI‘06] 论文阅读笔记

原论文:Bigtable: A Distributed Storage System for Structured Data (OSDI’06) 1. Introduction Bigtable 是一种用于管理结构化数据的分布式存储系统,可扩展到非常大的规模:数千台服务器上的数据量可达 PB 级别,同时保证可靠…

外汇110:外汇交易不同货币类别及交易注意事项!

外汇市场是一个庞大而复杂的市场,其中有各种各样的货币品种。对于外汇投资者来说,了解外汇品种的特性和走势是比较重要的。1. 货币种类 外汇市场中的货币品种可以分为主要货币、次要货币和外围货币。 主要货币:主要指美元、欧元、英镑、日元、…

(免费分享)基于springboot,vue问卷调查系统

用户注册、用户登录、创建调查问卷、编辑问卷问题和选型(支持题型:单选、多选、单行文本、多行文本、数字、评分、日期、文本描述)、保存和发布问卷、停止问卷调查、游客填写调查问卷(一个IP地址只能填写一次) 技术&a…

Jmeter/postman/python三大主流技术如何操作数据库?

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号【互联网杂货铺】,回复 1 ,免费获取软件测试全套资料,资料在手,涨薪更快 1、前言 只要是做测试工作的,必然会接触到数据库&a…

【微服务】SpringCloud之Feign远程调用

🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 🛸学无止境,不骄不躁,知行合一 文章目录 …

【已解决】HalconDotNet.HOperatorException:“HALCON error #1201: Wrong type of control

前言 最近在学习Halcon视觉和C#的联合开发,碰到一个比较有意思的问题记录一下,大致的报错信息是说我用的halcondotnet版本和我在halcon导出的使用的halcondotnet.dll版本不一致,所以才报错的! 解决 首先你得找到你安装halcon的…

流程表单平台优势明显,助力企业流程化办公!

要想提升办公效率,实现流程化办公,可以了解低代码技术平台、流程表单平台的应用价值和优势特点。在科技越来越发达和先进的今天,采用专业的平台和软件可以为企业带来超前的发展态势,创造更多市场价值。流辰信息为广大用户提供的流…