STM32F4X UCOSIII 互斥量

news2024/11/17 7:53:27

STM32F4X UCOSIII 互斥量

  • 互斥量的概念
  • 互斥量的工作机制
    • 洗手间问题
    • 互斥量优先级继承
      • 没有优先级继承
      • 优先级继承
  • UCOSIII互斥量API
    • 互斥量创建函数
    • 互斥量删除函数
    • 互斥量申请函数
    • 互斥量释放函数
  • UCOSIII 互斥量例程

互斥量的概念

UCOSIII中的互斥量是一种特殊的信号量,它的本质也是一种信号量,不具备信息传递的功能。互斥量的主要作用是可以实现共享资源的互斥访问,提供优先级翻转机制。当一个任务持有互斥量时,除非该任务主动释放互斥量,否则其他任务都申请不到该互斥量。

互斥量的工作机制

洗手间问题

我们可以用一个实际的例子来说明一下互斥量的应用场景。假设有一个洗手间,洗手间里面有一把锁,假如现在游客A要进入洗手间,进入洗手间之后把锁锁上了,这时游客B也想进入洗手间,但是因为此时已经有人在洗手间,所以游客B无法进入,所以此时游客B只能在门外等,一直等待游客A上完洗手间之后,把锁打开,游客B才可以进入。
在上面的例子中,洗手间是共享资源,洗手间里面的锁是互斥量,游客A和游客B是两个任务。游客A上锁相当于是任务A申请互斥量,游客B等待相当于是任务B阻塞,游客A打开锁相当于是任务A解锁。

互斥量优先级继承

互斥量跟信号量非常类似,但是互斥量比信号量多了一个优先级继承的机制,下面可以通过一个例子来进行说明。

没有优先级继承

假设系统中有3个任务,分别是低优先级任务L,中优先级任务M和高优先级任务H。
在这里插入图片描述

  1. 任务L在使用共享资源,此时任务H被唤醒,开始执行,但是任务L还没释放共享资源。
  2. 任务H也要使用共享资源,但是任务L还没释放,所以任务H在阻塞等待。
  3. 任务M被唤醒,任务M优先级比任务L要高,任务M被执行,任务L还没有释放资源
  4. 任务M执行完毕,归还CPU资源,任务L继续执行
  5. 任务L执行完毕,释放资源,此时任务H获取资源,开始执行。
    从上面的例子可以看到,任务H是高优先级任务,但是等待时间过长,这对系统的实时性会造成一定的影响。

优先级继承

下面来看一下有优先级继承的效果,同样地也是假设系统中有3个任务,分别是低优先级任务L,中优先级任务M和高优先级任务H。
在这里插入图片描述

  1. 任务L在使用共享资源,此时任务H被唤醒,开始执行,但是任务L还没释放共享资源。
  2. 任务H也要使用共享资源,但是任务L还没释放,此时因为互斥量的优先级继承机制,任务L的优先级会被临时提升到跟任务H相同的优先级。
  3. 任务M被唤醒,但是因为任务M的优先级要比任务L的低,所以任务M处于就绪状态,没有被执行。
  4. 任务L运行完毕,释放资源,此时任务L的优先级会变成原来的优先级,任务H获取资源,开始运行。
  5. 任务H运行完成,释放资源,任务M开始运行。
  6. 任务M运行完毕,系统正常运行,按照设定好的优先级运行。
    可以看到,当使用互斥量时,任务L的优先级会被临时提高,这样就可以保证一些高优先级的任务能够尽快运行,尽可能提高系统的实时性。

UCOSIII互斥量API

互斥量创建函数

/*
	* p_mutex:互斥量对象
	* p_name:互斥量名字
	* p_err:错误代码
*/
void  OSMutexCreate (OS_MUTEX  *p_mutex,
                     CPU_CHAR  *p_name,
                     OS_ERR    *p_err)

互斥量删除函数

/*
	* p_mutex:要删除的互斥量对象
	* opt:用户选项
	* p_err:错误代码
返回值: 等于0:删除成功
	   大于0:互斥量上有等待的任务
*/
OS_OBJ_QTY  OSMutexDel (OS_MUTEX  *p_mutex,
                        OS_OPT     opt,
                        OS_ERR    *p_err)

其中opt可以选择OS_OPT_DEL_NO_PEND和OS_OPT_DEL_ALWAYS。

  • OS_OPT_DEL_NO_PEND:删除互斥量如果该互斥量上有挂起的任务,则等待挂起的任务恢复才删除。

  • OS_OPT_DEL_ALWAYS:不管该互斥量上是否有挂起的任务,直接删除互斥量

互斥量申请函数

/*
	* p_mutex:互斥量对象
	* timeout:超时时间
	* opt:用户选项
	* p_ts:时间戳
	* p_err:错误代码
*/
void  OSMutexPend (OS_MUTEX  *p_mutex,
                   OS_TICK    timeout,
                   OS_OPT     opt,
                   CPU_TS    *p_ts,
                   OS_ERR    *p_err)

opt选项可以选择OS_OPT_PEND_BLOCKING、OS_OPT_PEND_NON_BLOCKING

  • OS_OPT_PEND_BLOCKING:阻塞等待互斥量。
  • OS_OPT_PEND_NON_BLOCKING:不阻塞等待互斥量,如果任务等待时间超过设定的超时时间,任务会恢复并返回一个错误代码。

互斥量释放函数

/*
	* p_mutex:互斥量对象
	* opt:用户选项
	* p_err:错误代码
*/
void  OSMutexPost (OS_MUTEX  *p_mutex,
                   OS_OPT     opt,
                   OS_ERR    *p_err)

opt选项可以选择OS_OPT_POST_NONE和OS_OPT_POST_NO_SCHED。

  • OS_OPT_POST_NONE:释放互斥量不任何操作
  • OS_OPT_POST_NO_SCHED:释放互斥量的同时不进行调度

UCOSIII 互斥量例程

/*
*********************************************************************************************************
*                                              EXAMPLE CODE
*
*                             (c) Copyright 2013; Micrium, Inc.; Weston, FL
*
*                   All rights reserved.  Protected by international copyright laws.
*                   Knowledge of the source code may not be used to write a similar
*                   product.  This file may only be used in accordance with a license
*                   and should not be redistributed in any way.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*
*                                            EXAMPLE CODE
*
*                                       IAR Development Kits
*                                              on the
*
*                                    STM32F429II-SK KICKSTART KIT
*
* Filename      : app.c
* Version       : V1.00
* Programmer(s) : YS
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/

#include  <includes.h>

/*
*********************************************************************************************************
*                                            LOCAL DEFINES
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                       LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/

                                                                /* ----------------- APPLICATION GLOBALS -------------- */
static  OS_TCB   AppTaskStartTCB;
static  CPU_STK  AppTaskStartStk[APP_CFG_TASK_START_STK_SIZE];

#define APPTASK1NAME    "App Task1"
#define APP_TASK1_PRIO          3   
#define APP_TASK1_STK_SIZE 1024
static OS_TCB AppTask1TCB;
static void  AppTask1  (void *p_arg);
static CPU_STK AppTask1Stk[APP_TASK1_STK_SIZE];

#define APPTASK2NAME    "App Task2"
#define APP_TASK2_PRIO          4   
#define APP_TASK2_STK_SIZE 1024
static OS_TCB AppTask2TCB;
static void  AppTask2  (void *p_arg);
static CPU_STK AppTask2Stk[APP_TASK2_STK_SIZE];

#define APPTASK3NAME    "App Task3"
#define APP_TASK3_PRIO          5   
#define APP_TASK3_STK_SIZE 1024
static OS_TCB AppTask3TCB;
static void  AppTask3  (void *p_arg);
static CPU_STK AppTask3Stk[APP_TASK3_STK_SIZE];

static OS_MUTEX  mutex;

/*
*********************************************************************************************************
*                                         FUNCTION PROTOTYPES
*********************************************************************************************************
*/

static  void  AppTaskStart          (void     *p_arg);


/*
*********************************************************************************************************
*                                                main()
*
* Description : This is the standard entry point for C code.  It is assumed that your code will call
*               main() once you have performed all necessary initialization.
*
* Arguments   : none
*
* Returns     : none
*********************************************************************************************************
*/

int main(void)
{

    OS_ERR  err;


    OSInit(&err);                                               /* Init uC/OS-III.                                      */
   
    OSTaskCreate((OS_TCB       *)&AppTaskStartTCB,              /* Create the start task                                */
                 (CPU_CHAR     *)"App Task Start",
                 (OS_TASK_PTR   )AppTaskStart,
                 (void         *)0u,
                 (OS_PRIO       )APP_CFG_TASK_START_PRIO,
                 (CPU_STK      *)&AppTaskStartStk[0u],
                 (CPU_STK_SIZE  )AppTaskStartStk[APP_CFG_TASK_START_STK_SIZE / 10u],
                 (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE,
                 (OS_MSG_QTY    )0u,
                 (OS_TICK       )0u,
                 (void         *)0u,
                 (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                 (OS_ERR       *)&err);

    OSStart(&err);                                              /* Start multitasking (i.e. give control to uC/OS-III). */


}


/*
*********************************************************************************************************
*                                          STARTUP TASK
*
* Description : This is an example of a startup task.  As mentioned in the book's text, you MUST
*               initialize the ticker only once multitasking has started.
*
* Arguments   : p_arg   is the argument passed to 'AppTaskStart()' by 'OSTaskCreate()'.
*
* Returns     : none
*
* Notes       : 1) The first line of code is used to prevent a compiler warning because 'p_arg' is not
*                  used.  The compiler should not generate any code for this statement.
*********************************************************************************************************
*/

static  void  AppTaskStart (void *p_arg)
{
    CPU_INT32U  cpu_clk_freq;
    CPU_INT32U  cnts;
    OS_ERR      err;


   (void)p_arg;

    BSP_Init();                      
    CPU_Init();                                                 /* Initialize the uC/CPU services                       */

    cpu_clk_freq = BSP_CPU_ClkFreq();                           /* Determine SysTick reference freq.                    */
    cnts         = cpu_clk_freq                                 /* Determine nbr SysTick increments                     */
                 / (CPU_INT32U)OSCfg_TickRate_Hz;

    OS_CPU_SysTickInit(cnts);                                   /* Init uC/OS periodic time src (SysTick).              */

    Mem_Init();                                                 /* Initialize memory managment module                   */
    Math_Init();                                                /* Initialize mathematical module                       */


#if OS_CFG_STAT_TASK_EN > 0u
    OSStatTaskCPUUsageInit(&err);                               /* Compute CPU capacity with no task running            */
#endif

#ifdef CPU_CFG_INT_DIS_MEAS_EN
    CPU_IntDisMeasMaxCurReset();
#endif


#if (APP_CFG_SERIAL_EN == DEF_ENABLED)
    App_SerialInit();                                           /* Initialize Serial communication for application ...  */
#endif
	

	OSTaskCreate((OS_TCB     *)&AppTask1TCB,  // 线程TCB              
			 (CPU_CHAR   *)APPTASK1NAME, // 线程名字
			 (OS_TASK_PTR ) AppTask1, // 线程入口函数
			 (void       *) "TASK1", // 线程参数
			 (OS_PRIO     ) APP_TASK1_PRIO, // 线程优先级
			 (CPU_STK    *)&AppTask1Stk[0], // 线程栈起始地址
			 (CPU_STK_SIZE) APP_TASK1_STK_SIZE / 10, // 栈深度的限制位置
			 (CPU_STK_SIZE) APP_TASK1_STK_SIZE, // 栈大小
			 (OS_MSG_QTY  ) 5u, // 最大的消息个数
			 (OS_TICK     ) 0u, // 时间片
			 (void       *) 0, // 向用户提供的内存位置的指针
			 (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), // 线程特定选项
			 (OS_ERR     *)&err); // 错误标志
	if(OS_ERR_NONE == err)
		printf("%s Create Success\r\n",APPTASK1NAME);
	else
		printf("%s Create Error\r\n",APPTASK1NAME);
	
			 
	OSTaskCreate((OS_TCB     *)&AppTask2TCB,  // 线程TCB              
			 (CPU_CHAR   *)APPTASK2NAME, // 线程名字
			 (OS_TASK_PTR ) AppTask2, // 线程入口函数
			 (void       *) "TASK2", // 线程参数
			 (OS_PRIO     ) APP_TASK2_PRIO, // 线程优先级
			 (CPU_STK    *)&AppTask2Stk[0], // 线程栈起始地址
			 (CPU_STK_SIZE) APP_TASK2_STK_SIZE / 10, // 栈深度的限制位置
			 (CPU_STK_SIZE) APP_TASK2_STK_SIZE, // 栈大小
			 (OS_MSG_QTY  ) 5u, // 最大的消息个数
			 (OS_TICK     ) 0u, // 时间片
			 (void       *) 0, // 向用户提供的内存位置的指针
			 (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), // 线程特定选项
			 (OS_ERR     *)&err); // 错误标志
	if(OS_ERR_NONE == err)
		printf("%s Create Success\r\n",APPTASK2NAME);
	else
		printf("%s Create Error\r\n",APPTASK2NAME);
		

	OSTaskCreate((OS_TCB     *)&AppTask3TCB,  // 线程TCB              
			 (CPU_CHAR   *)APPTASK3NAME, // 线程名字
			 (OS_TASK_PTR ) AppTask3, // 线程入口函数
			 (void       *) "TASK3", // 线程参数
			 (OS_PRIO     ) APP_TASK3_PRIO, // 线程优先级
			 (CPU_STK    *)&AppTask3Stk[0], // 线程栈起始地址
			 (CPU_STK_SIZE) APP_TASK3_STK_SIZE / 10, // 栈深度的限制位置
			 (CPU_STK_SIZE) APP_TASK3_STK_SIZE, // 栈大小
			 (OS_MSG_QTY  ) 5u, // 最大的消息个数
			 (OS_TICK     ) 0u, // 时间片
			 (void       *) 0, // 向用户提供的内存位置的指针
			 (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), // 线程特定选项
			 (OS_ERR     *)&err); // 错误标志
	if(OS_ERR_NONE == err)
		printf("%s Create Success\r\n",APPTASK3NAME);
	else
		printf("%s Create Error\r\n",APPTASK3NAME);
	
	
	OSMutexCreate(&mutex,"mutex",&err);
	if(OS_ERR_NONE == err)
		printf("Create Mutex Success\r\n");
	else
		printf("Create Mutex Error\r\n");

	
	OSTaskDel ( & AppTaskStartTCB, & err );		 

}

static void  AppTask1  (void *p_arg)
{
    OS_ERR      err;
	while(DEF_TRUE)
	{

		printf("APP1 获取互斥量 \r\n");

		OSMutexPend(&mutex,0,OS_OPT_PEND_BLOCKING,0,&err);
		printf("APP1 释放互斥量 \r\n");
		OSMutexPost(&mutex,OS_OPT_POST_NONE,&err);
		OSTimeDly ( 1000, OS_OPT_TIME_DLY, & err ); // 1s运行一次
	}
	
}
static void  AppTask2  (void *p_arg)
{
    OS_ERR      err;
	while(DEF_TRUE)
	{
		printf("Task1 Runing  Task2 Arg %s\r\n",p_arg);
		OSTimeDly ( 200, OS_OPT_TIME_DLY, & err ); // 200ms运行一次
	}
	
}
static void  AppTask3  (void *p_arg)
{
    OS_ERR      err;
	static CPU_INT32U i;
	while(DEF_TRUE)
	{
		printf("APP3 获取互斥量 \r\n");
		OSMutexPend(&mutex,0,OS_OPT_PEND_BLOCKING,0,&err);
		
		for (i=0; i<600000; i++) //模拟低优先级任务占用信号量
		 {
		 OSSched();//发起任务调度
		 }
		 printf("APP3 释放互斥量 \r\n");

		OSMutexPost(&mutex,OS_OPT_POST_NONE,&err);
		OSTimeDly ( 1000, OS_OPT_TIME_DLY, & err ); // 1s运行一次
	}
	
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重磅!这本SSCI期刊已解除On Hold状态!警惕目前6本SCIE/ESCI期刊被标记!

期刊动态&#xff1a;新增一本SSCI解除“On Hold” 最新消息&#xff0c;SSCI期刊Transformations in Business & Economics在之前被标记为On Hold&#xff0c;目前该标识已取消&#xff01;表示目前该期刊被SSCI数据库正常收录检索。 往期期刊On Hold情况&#xff1a; …

云服务器CVM_云主机_云计算服务器_弹性云服务器-腾讯云

腾讯云服务器CVM提供安全可靠的弹性计算服务&#xff0c;腾讯云明星级云服务器&#xff0c;弹性计算实时扩展或缩减计算资源&#xff0c;支持包年包月、按量计费和竞价实例计费模式&#xff0c;CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格&#xff0c;提供9个9的数…

递归解析Json,实现生成可视化Tree+快速获取JsonPath | 京东云技术团队

内部平台的一个小功能点的实现过程&#xff0c;分享给大家&#xff1a; 递归解析Json&#xff0c;可以实现生成可视化Tree快速获取JsonPath。 步骤&#xff1a; 1.利用JsonPath读取根&#xff0c;获取JsonObject 2.递归层次遍历JsonObjec&#xff0c;保存结点信息 3.利用z…

钡铼BL124EC实现EtherCAT转Ethernet/IP的优势

钡铼技术的BL124EC是一款用于将EtherCAT从站转换为Ethernet/IP从站的网关设备。它是钡铼技术开发的高性能、可靠的工业自动化通信解决方案之一。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; BL124EC网关可以应用于多种工业自动化场景&#xff0c;以下…

1.6 IntelliJ IDEA开发工具

前言&#xff1a; ### 1.6 IntelliJ IDEA开发工具笔记 - **背景**&#xff1a; - 使用基础文本编辑器如记事本编写Java代码虽然可行&#xff0c;但存在效率低下且难以调试的问题。 - 集成开发环境 (IDE) 可以有效地提高Java程序的开发效率。 - **常见Java IDE**&#xf…

解决docker开启MySQL的binlog无法成功。docker内部报错:mysql: [ERROR] unknown variable

1. 报错信息 2. 操作流程 整个流程是这样的&#xff1a; 我愉快的输入docker ps&#xff0c;查看MySQL的docker 容器id 执行指令docker exec -it 8a \bin\bash进入容器内部执行vim /etc/my.cnf&#xff0c;打开配置文件按照网上说的&#xff0c;添加如下配置信息退出docker容…

韦东山老师 RTOS 入门课程(二)理解任务的创建,切换过程

RTOS 的核心实现&#xff1a;保存&#xff0c;恢复现场 接下来开始尝试实现 RTOS。当然我们开发的时候其实不用这样做&#xff0c;现在尝试实现只是为了更好地理解原理。 RTOS 的核心就是刚才在研究的问题&#xff1a;保存和恢复现场。再追其本质&#xff0c;其实就是所有寄存…

【Linux】 文件类型和访问权限

执行 ls -l &#xff08;或者&#xff1a;ll &#xff09; 指令查看文件的具体属性。 示例&#xff1a; drwxr-xr-x. 2 root root 33 10月 7 11:27 test2 看图说话&#xff1a; 下面是示例分解图 第一列的字符表示文件或目录的类型和权限。 第一个字符表示文件类型 例如&…

局域网内网管理软件有哪些功能?(局域网内网管理软件有哪些)

局域网&#xff08;LAN&#xff09;是指在一个小范围内&#xff08;如一个办公室、一个楼层或者一个大楼&#xff09;的计算机网络。随着互联网和科技的快速发展&#xff0c;局域网在企业、学校和个人生活中的应用越来越广泛。局域网内网管理软件是一种专门用于监控和控制局域网…

「天锐绿盾」——数据防泄露(智能透明加密保护)企业加密软件

天锐绿盾是一款专业的企业级加密软件&#xff0c;提供专业版、行业增强版和旗舰版&#xff0c;分别针对不同的用户需求。 PC访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 天锐绿盾数据防泄密模块&#xff0c;采取系统底…

【手绘 | 日漫风】从临摹开始控笔,线条,再到人体

博主&#xff1a;_LJaXi 专栏&#xff1a; Unity | 横版游戏开发 手绘入门 控笔 排线起稿方式九宫格起稿五官起稿专业起稿 握笔姿势三角握持姿势拇指指握姿势 勾线建议注意对于人体 控笔 排线 在绘画过程中&#xff0c;可以使用铅笔控制笔触的方向、压力和角度&#xff0c;以获…

tf卡损坏怎么修复恢复?

TF卡是一种极其微小的数据储存卡&#xff0c;常见于手机、行车记录仪、微型相机中。因为TF卡不具备读写保护功能&#xff0c;所以一旦发生损坏就会非常麻烦。今天小编就给大家介绍一下&#xff0c;TF卡突然损坏什么原因&#xff0c;TF卡损坏怎么办一招帮你修复。 一、TF卡突然损…

upload-labs靶场通关

文章目录 Pass-01 前端检测&#xff08;JS检测&#xff09;1.1 原理分析1.2 具体问题具体分析1.3 实验 Pass-02 后端检测&#xff08;MIME检测&#xff09;2.1 原理分析2.2 具体问题具体分析2.3 实验 Pass-03 后端检测&#xff08;黑名单绕过&#xff0c;特殊后缀名&#xff09…

DataX和dataX-web 集群部署及使用

&#x1f4d1; DataX和dataX-web 集群部署及使用 一 . 安装前准备 DataX 是一个异构数据源离线同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 DataX 采用 框架 插件 的模式…

【Proteus仿真】【STM32单片机】智能饮水机

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用OLED液晶、按键、语音播放模块、DS18B20温度传感器、加热器和水泵等。 主要功能&#xff1a; 系统运行后&#xff0c;OLED显示温度、温度阈值&a…

【Linux】 ls命令使用

ls&#xff08;英文全拼&#xff1a; list directory contents&#xff09;命令用于显示指定工作目录下之内容&#xff08;列出目前工作目录所含的文件及子目录)。 ls命令 -Linux手册页 著者 由Richard M.Stallman和David MacKenzie撰写。 语法 ls [-alrtAFR] [name...] ls命…

众佰诚:抖音开网店新手怎么做才能做起来

抖音作为国内最热门的短视频平台&#xff0c;其商业价值也日渐凸显。许多商家和个体经营者开始在抖音上开设网店&#xff0c;以此为新的销售渠道。那么&#xff0c;对于新手来说&#xff0c;如何才能在抖音上成功运营网店呢? 首先&#xff0c;明确经营定位。每个电商平台都有其…

云服务器可以做什么?分享阿里云服务器的十种玩法

阿里云服务器可以干什么&#xff1f;服务器的用途有很多&#xff0c;常见的有网站、小程序、视频服务器、手机APP等&#xff0c;例如微信基于腾讯云服务器&#xff0c;淘宝基于阿里云服务器&#xff0c;阿里云百科aliyunbaike.com来说下阿里云服务器十大用途&#xff1a; 目录…

理解C++四种强制类型转换

理解C强制类型转换 文章目录 理解C强制类型转换理解C强制转换运算符1 static_cast1.1. static_cast用于内置数据类型之间的转换1.2 用于指针之间的转换1.3 用于基类与派生类之间的转换 2. const_cast2.1示例12.2 示例2——this指针 3.reinterpret_cast3.1 示例1 4.dynamic_cast…

slamplay:用C++实现的SLAM工具集

0. 项目简介 slamplay 是一个功能强大的工具集合&#xff0c;可用于开始使用 C 来玩和试验 SLAM。这是一项正在进行的工作。它在单个 cmake 框架中安装并提供一些最重要的功能 后端框架&#xff08;g2o、gtsam、ceres、se-sync 等&#xff09;、 前端工具&#xff08;opencv、…