(学习日记)2024.03.18:UCOSIII第二十节:移植到STM32

写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。


标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。


点击此处进入学习日记的总目录

2024.03.18

  • 三十四、移植到STM32
    • 1、在工程中添加文件分组
    • 2、添加文件到对应分组
    • 3、添加头文件路径到工程中
    • 4、具体的工程文件修改
    • 5、修改源码中的bsp.c与bsp.h文件
    • 6、按需配置最适的工程
      • 1. os_cfg.h
      • 2. cpu_cfg.h
      • 3. os_cfg_app.h
    • 7、修改app.c

三十四、移植到STM32

在前一章节中,我们看到了μC/OS-III源码中那么多文件,一开始学我们根本看不过来那么多文件,我们需要提取源码中的最简洁的部分代码, 方便我们学习。
更何况我们学习的只是μC/OS-III的实时内核中的知识,因为这才是μC/OS-III的核心,那些demo都是基于此移植而来的。

上一章节我们只是将μC/OS-III的源码放到了本地工程目录下,还没有添加到开发环境里面的组文件夹里面,所以μC/OS-III也就没有移植到我们的工程中去。
现在开始讲μC/OS-III的源码添加到工程中。

1、在工程中添加文件分组

我们需要先在工程中创建一些分组,方便我们分模块管理μC/OS-III中的文件,就按照μC/OS-III官方的命名方式创建我们的文件分组即可
在这里插入图片描述

2、添加文件到对应分组

APP分组添加User->APP文件夹下的所有文件
在这里插入图片描述

BSP分组添加“User->BSP文件夹下的所有文件
在这里插入图片描述

μC/CPU分组添加User->uC-CPU文件夹下的所有文件 和 User->uC-CPU->ARM-Cortex-M3->RealView文件夹下的所有文件
在这里插入图片描述

μC/LIB分组添加User->uC-LIB文件夹下的所有文件 和User->uC-LIB->Ports->ARM-Cortex-M3->RealView文件夹下的所有文件
在这里插入图片描述

μC/OS-III Source分组添加User->μC/OS-III->Source文件夹下的所有文件
在这里插入图片描述

μC/OS-III Port分组添加User->μC/OS-III->Ports->ARM-Cortex-M3->Generic->RealView文件夹下的所有文件
在这里插入图片描述
至此,我们的源码文件就添加到工程中了,当然此时仅仅是添加而已,并不是移植成功了,如果你编译一下工程就会发现一大堆错误,所以还需努力移植工程才行。

3、添加头文件路径到工程中

μC/OS-III的源码已经添加到开发环境的组文件夹下面,编译的时候需要为这些源文件指定头文件的路径,不然编译会报错。
此时我们先将头文件添加到我们的 工程中,具体见图:
在这里插入图片描述

至此,μC/OS的整体工程基本移植完毕,我们需要修改μC/OS配置文件,按照我们的需求来进行修改。

4、具体的工程文件修改

添加完头文件路径后,我们可以编译一下整个工程,但肯定会有错误的, μC/OS-III 的移植尚未完毕,接下来需要对工程文件进行修改。

首先修改工程的启动文件“ startup_stm32f10x_hd.s”。
其中将PendSV_Handler 和 SysTick_Handler 分别改为OS_CPU_PendSVHandler 和OS_CPU_SysTickHandler,各三处共六处。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为μC/OS官方已经给我们处理好对应的中断函数,就无需我们自己处理与系统相关的中断了。

同时我们还需要将stm32f10x_it.c文件中的PendSV_Handler和SysTick_Handler函数注释掉(当然不注释掉也没问题的)

5、修改源码中的bsp.c与bsp.h文件

我们知道bsp就是板级相关的文件,也就是对应开发板的文件,而μC/OS-III源码的bsp肯定是与我们的板子不一样, 所以就需要进行修改。
而且以后我们的板级外设都在bsp.c文件进行初始化,所以按照我们修改好的源码进行修改即可

#define  BSP_MODULE
#include <bsp.h>CPU_INT32U  BSP_CPU_ClkFreq_MHz;#define  DWT_CR      *(CPU_REG32 *)0xE0001000
#define  DWT_CYCCNT  *(CPU_REG32 *)0xE0001004
#define  DEM_CR      *(CPU_REG32 *)0xE000EDFC
#define  DBGMCU_CR   *(CPU_REG32 *)0xE0042004#define  DBGMCU_CR_TRACE_IOEN_MASK       0x10
#define  DBGMCU_CR_TRACE_MODE_ASYNC      0x00
#define  DBGMCU_CR_TRACE_MODE_SYNC_01    0x40
#define  DBGMCU_CR_TRACE_MODE_SYNC_02    0x80
#define  DBGMCU_CR_TRACE_MODE_SYNC_04    0xC0
#define  DBGMCU_CR_TRACE_MODE_MASK       0xC0#define  DEM_CR_TRCENA                   (1 << 24)#define  DWT_CR_CYCCNTENA                (1 <<  0)void  BSP_Init (void)
{LED_Init ();}CPU_INT32U  BSP_CPU_ClkFreq (void)
{RCC_ClocksTypeDef  rcc_clocks;RCC_GetClocksFreq(&rcc_clocks);return ((CPU_INT32U)rcc_clocks.HCLK_Frequency);
}#if ((APP_CFG_PROBE_OS_PLUGIN_EN == DEF_ENABLED) && \(OS_PROBE_HOOKS_EN          == 1))
void  OSProbe_TmrInit (void)
{
}
#endif#if ((APP_CFG_PROBE_OS_PLUGIN_EN == DEF_ENABLED) && \(OS_PROBE_HOOKS_EN          == 1))
CPU_INT32U  OSProbe_TmrRd (void)
{return ((CPU_INT32U)DWT_CYCCNT);
}
#endif#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void  CPU_TS_TmrInit (void)
{CPU_INT32U  cpu_clk_freq_hz;DEM_CR         |= (CPU_INT32U)DEM_CR_TRCENA;DWT_CYCCNT      = (CPU_INT32U)0u;DWT_CR         |= (CPU_INT32U)DWT_CR_CYCCNTENA;cpu_clk_freq_hz = BSP_CPU_ClkFreq();CPU_TS_TmrFreqSet(cpu_clk_freq_hz);
}
#endif#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR  CPU_TS_TmrRd (void)
{return ((CPU_TS_TMR)DWT_CYCCNT);
}
#endif

bsp.h文件中需要添加我们自己的板级驱动头文件

#include"stm32f10x.h"// Modified by fire#include  <app_cfg.h>#include"bsp_led.h"// Modified by fire

6、按需配置最适的工程

虽然前面的编译是没有错误的,并且工程模板也是可用的,但是此时还不是我们最适合使用的工程模板。
最适合的工程往往是根据需要进行配置的,而μC/OS提供裁剪的功能,我们可以按需对系统进行裁剪。

1. os_cfg.h

os_cfg.h文件是系统的配置文件,主要是让用户自己配置一些系统默认的功能。
用户可以选择某些或者全部的功能, 比如消息队列、信号量、互斥量、事件标志位等,系统默认全部使用。
如果如果用户不需要的话,则可以直接关闭, 在对应的宏定义中设置为0即可,这样子就不会占用系统的SRAM,以节省系统资源

#ifndef OS_CFG_H
#define OS_CFG_H/* --- 其他配置 --- */
#define OS_CFG_APP_HOOKS_EN             1u/* 是否使用钩子函数     */
#define OS_CFG_ARG_CHK_EN               1u/* 是否使用参数检查     */
#define OS_CFG_CALLED_FROM_ISR_CHK_EN   1u/* 是否使用中断调用检查 */
#define OS_CFG_DBG_EN                   1u/* 是否使用debug        */
#define OS_CFG_ISR_POST_DEFERRED_EN     1u/* 是否使用中断延迟post操作*/
#define OS_CFG_OBJ_TYPE_CHK_EN          1u/* 是否使用对象类型检查   */
#define OS_CFG_TS_EN                    1u/*是否使用时间戳     */#define OS_CFG_PEND_MULTI_EN            1u/*是否使用支持多个任务pend操作*/#define OS_CFG_PRIO_MAX                32u/*定义任务的最大优先级 */#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN  1u/*是否使用支持测量调度器锁定时间 */
#define OS_CFG_SCHED_ROUND_ROBIN_EN     1u/* 是否支持循环调度         */
#define OS_CFG_STK_SIZE_MIN            64u/* 最小的任务栈大小        *//* ---------- 事件标志位---------- */
#define OS_CFG_FLAG_EN                  1u/*是否使用事件标志位    */
#define OS_CFG_FLAG_DEL_EN                  1u/*是否包含OSFlagDel()的代码 */
#define OS_CFG_FLAG_MODE_CLR_EN         1u/*是否包含清除事件标志位的代码*/
#define OS_CFG_FLAG_PEND_ABORT_EN       1u/*是否包含OSFlagPendAbort()的代码*//* --------- 内存管理 --- */
#define OS_CFG_MEM_EN                   1u/* 是否使用内存管理         *//* -------- 互斥量 ----- */
#define OS_CFG_MUTEX_EN                 1u/*是否使用互斥量 */
#define OS_CFG_MUTEX_DEL_EN             1u/*是否包含OSMutexDel()的代码*/
#define OS_CFG_MUTEX_PEND_ABORT_EN      1u/*是否包含OSMutexPendAbort()的代码*//* ------- 消息队列--------------- */
#define OS_CFG_Q_EN                     1u/* 是否使用消息队列       */
#define OS_CFG_Q_DEL_EN                 1u/* 是否包含OSQDel()的代码 */
#define OS_CFG_Q_FLUSH_EN               1u/* 是否包含OSQFlush()的代码 */
#define OS_CFG_Q_PEND_ABORT_EN          1u/* 是否包含OSQPendAbort()的代码*//* -------------- 信号量 --------- */
#define OS_CFG_SEM_EN                   1u/*是否使用信号量  */
#define OS_CFG_SEM_DEL_EN               1u/*是否包含OSSemDel()的代码*/
#define OS_CFG_SEM_PEND_ABORT_EN        1u/*是否包含OSSemPendAbort()的代码*/
#define OS_CFG_SEM_SET_EN               1u/*是否包含OSSemSet()的代码  *//* ----------- 任务管理 -------------- */
#define OS_CFG_STAT_TASK_EN             1u/* 是否使用任务统计功能 */
#define OS_CFG_STAT_TASK_STK_CHK_EN     1u/* 从统计任务中检查任务栈 */#define OS_CFG_TASK_CHANGE_PRIO_EN      1u/* 是否包含OSTaskChangePrio()的代码*/
#define OS_CFG_TASK_DEL_EN              1u/* 是否包含OSTaskDel()的代码*/
#define OS_CFG_TASK_Q_EN                1u/*是否包含OSTaskQXXXX()的代码*/
#define OS_CFG_TASK_Q_PEND_ABORT_EN     1u/* 是否包含OSTaskQPendAbort()的代码 */
#define OS_CFG_TASK_PROFILE_EN          1u/* 是否在OS_TCB中包含变量以进行性能分析 */
#define OS_CFG_TASK_REG_TBL_SIZE     1u/*任务特定寄存器的数量  */
#define OS_CFG_TASK_SEM_PEND_ABORT_EN   1u/* 是否包含OSTaskSemPendAbort()的代码 */
#define OS_CFG_TASK_SUSPEND_EN       1u/*是否包含OSTaskSuspend()和OSTaskResume()的代码*//* ------- 时间管理 ------- */
#define OS_CFG_TIME_DLY_HMSM_EN      1u/*是否包含OSTimeDlyHMSM()的代码*/
#define OS_CFG_TIME_DLY_RESUME_EN   1u/*是否包含OSTimeDlyResume()的代码*//* ---------- 定时器管理 ------- */
#define OS_CFG_TMR_EN                   1u/* 是否使用定时器        */
#define OS_CFG_TMR_DEL_EN               1u/* 是否支持OSTmrDel()  */#endif

2. cpu_cfg.h

cpu_cfg.h文件主要是配置CPU相关的一些宏定义,我们可以选择对不同的CPU进行配置。
当然,如果我们没有对CPU很熟悉的话, 就直接忽略这个文件即可。

在这里我们只需要注意关于时间戳与前导零指令相关的内容,我们使用的CPU是STM32,是32位的CPU, 那么时间戳我们使用32位的变量即可。
而且STM32支持前导零指令,可以使用它让系统进行寻找最高优先级的任务更加快捷

#ifndef  CPU_CFG_MODULE_PRESENT
#define  CPU_CFG_MODULE_PRESENT/*   是否使用CPU名字:DEF_ENABLED或者DEF_DISABLED       */
#define  CPU_CFG_NAME_EN                        DEF_ENABLED/* CPU名字大小(ASCII字符串形式)   */
#define  CPU_CFG_NAME_SIZE                     16u/* CPU时间戳功能配置(只能选择其中一个)  */
/*  是否使用32位的时间戳变量:DEF_ENABLED或者DEF_DISABLED             */
#define  CPU_CFG_TS_32_EN                       DEF_ENABLED
/*  是否使用64位的时间戳变量:DEF_ENABLED或者DEF_DISABLED             */
#define  CPU_CFG_TS_64_EN                       DEF_DISABLED
/* *配置CPU时间戳定时器字大小 */
#define  CPU_CFG_TS_TMR_SIZE                    CPU_WORD_SIZE_32/* 是否使用测量CPU禁用中断的时间  */
#if 0
#define  CPU_CFG_INT_DIS_MEAS_EN
#endif
/* 配置测量的次数*/
#define  CPU_CFG_INT_DIS_MEAS_OVRHD_NBR                    1u/* 是否使用CPU前导零指令(需要硬件支持,在stm32我们可以使用这个指令)  */
#if 1
#define  CPU_CFG_LEAD_ZEROS_ASM_PRESENT
#endif#endif

μC/OS支持两种方法选择下一个要执行的任务:

一个采用C语言实现前导零指令,这种方法我们通常称为通用方法, CPU_CFG_LEAD_ZEROS_ASM_PRESENT没有被定义的时候使用才使用通用方法获取下一个即将运行的任务。
通用方法可以用于所有μC/OS支持的硬件平台,因为这种方法是完全用C语言实现,所以效率略低于特殊方法, 但不强制要求限制最大可用优先级数目;

另一个是硬件方式查找下一个要运行的任务, 必须定义CPU_CFG_LEAD_ZEROS_ASM_PRESENT这个宏。
因为这种方法是必须依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令, 在M3、M4、M7内核中都有,这个指令是用来计算一个变量从最高位开始的连续零的个数),所以效率略高于通用方法,但受限于硬件平台。

3. os_cfg_app.h

os_cfg_app.h是系统应用配置的头文件,简单来说就是系统默认的任务配置,如任务的优先级、栈大小等基本信息。
但是有两个任务是必须开启的,一个就是空闲任务,另一个就是时钟节拍任务,这两个是让系统正常运行的最基本任务,而其他任务我们自己按需配置即可。

#ifndef OS_CFG_APP_H
#define OS_CFG_APP_H/* --------------------- MISCELLANEOUS ------------------ */
#define  OS_CFG_MSG_POOL_SIZE            100u/* 支持的最大消息数量 */
#define  OS_CFG_ISR_STK_SIZE             128u/*ISR栈的大小 */
#define  OS_CFG_TASK_STK_LIMIT_PCT_EMPTY  10u/*检查栈的剩余大小(百分百形式,此处是10%)*//* ---------------------- 空闲任务 --------------------- */
#define  OS_CFG_IDLE_TASK_STK_SIZE       128u/* 空闲任务栈大小    *//* ------------------ 中断处理任务------------------ */
#define  OS_CFG_INT_Q_SIZE                10u/*中断处理任务队列大小  */
#define  OS_CFG_INT_Q_TASK_STK_SIZE      128u/* 中断处理任务的栈大小*//* ------------------- 统计任务------------------- */
#define  OS_CFG_STAT_TASK_PRIO            11u/* 统计任务的优先级  */
#define  OS_CFG_STAT_TASK_RATE_HZ         10u/* 统计任务的指向频率(10HZ)*/
#define  OS_CFG_STAT_TASK_STK_SIZE       128u/*统计任务的栈大小*//* ------------------------ 时钟节拍任务 ----------------------- */
#define  OS_CFG_TICK_RATE_HZ       1000u/*系统的时钟节拍(一般为10 到 1000 Hz) */
#define  OS_CFG_TICK_TASK_PRIO            1u/*时钟节拍任务的优先级    */
#define  OS_CFG_TICK_TASK_STK_SIZE       128u/* 时钟节拍任务的栈大小*/
#define  OS_CFG_TICK_WHEEL_SIZE           17u/* 时钟节拍任务的列表大小 *//* ----------------------- 定时器任务 ----------------------- */
#define  OS_CFG_TMR_TASK_PRIO          11u/*定时器任务的优先级  */
#define  OS_CFG_TMR_TASK_RATE_HZ        10u/* 定时器频率(10 Hz是典型值) */
#define  OS_CFG_TMR_TASK_STK_SIZE      128u/* 定时器任务的栈大小    */
#define  OS_CFG_TMR_WHEEL_SIZE          17u/*定时器任务的列表大小  */#endif

此处要注意时钟节拍任务,μC/OS的时钟节拍任务是用于管理时钟节拍的,建议将其优先级设置更高一些。
这样子在调度的时候,时钟节拍任务 能抢占其他任务执行,从而能够更新任务。
相对于其他操作系统寻找处于最高优先级的就绪任务都是在中断中,μC/OS将其放于任务中能更好解决 关中断时间过长 的问题。

7、修改app.c

我们将原来裸机工程里面app.c的文件内容全部删除,新增如下内容

/*
*************************************************************************
*                             包含的头文件
*************************************************************************
*/
#include <includes.h>/*
*************************************************************************
*                               变量
*************************************************************************
*//*
*************************************************************************
*                             函数声明
*************************************************************************
*//*
*************************************************************************
*                             main 函数
*************************************************************************
*/
/**
* @brief  主函数
* @param  无
* @retval 无
*/
int main(void)
{/*暂时没有在main里面创建任务应用任务 */
}

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

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

相关文章

注册个人小程序

访问地址 https://mp.weixin.qq.com/ 立即注册 选择小程序 注册 填写信息 登录邮箱 访问邮箱的链接激活账号 选择个人&#xff0c;填写信息 注册完成&#xff0c;即可登录进入填写信息

使用jenkins-pipeline进行利用项目文件自动化部署到k8s上

Discard old builds:丢弃旧的构建,目的是管理存储空间、提升性能以及保持环境整洁 Do not allow concurrent builds: 禁止并发构建是指同一时间内只允许一个构建任务执行,避免多个构建同时运行可能带来的问题 Do not allow the pipeline to resume if the controller resta…

深度学习实战模拟——softmax回归(图像识别并分类)

目录 1、数据集&#xff1a; 2、完整代码 1、数据集&#xff1a; 1.1 Fashion-MNIST是一个服装分类数据集&#xff0c;由10个类别的图像组成&#xff0c;分别为t-shirt&#xff08;T恤&#xff09;、trouser&#xff08;裤子&#xff09;、pullover&#xff08;套衫&#xf…

蓝桥杯-24点-搜索

题目 思路 --暴力递归全组合的方法。只有4个数&#xff0c;4种计算方式&#xff0c;共有4 * 3 * 2 * 1 * 4种不同的情况&#xff0c;可以写递归来实现。 --每次计算都是两个数之间的运算&#xff0c;因此4个数需要3次计算&#xff0c;第一次计算前有4个数&#xff0c;第二次有…

面向对象【interface接口、抽象类与抽象方法】

文章目录 interface接口定义接口接口的格式与举例静态方法私有方法接口的多继承接口的默认方法冲突解决接口与抽象类之间的对比 抽象类与抽象方法抽象类抽象类的定义抽象方法使用抽象类 参考链接 interface接口 接口是一种抽象的数据类型&#xff0c;它定义了一组方法&#xff…

c语言基础~函数详解

前言 今天我们来学习一波函数的概念,帮助各位理解函数,本次博客取自一些书籍以及各大网站的讲解,把它整合在一起并且详细讲解 1函数的理解 我们得知道什么是函数&#xff0c;函数的作用是什么,好不会表述没关系&#xff0c;我们翻书 c primer plus 是这么说的"函数是指…

科技云报道:第五次工业革命,中国AI企业如何打造新质生产力?

科技云报道原创。 人类历史的叙述与技术进步的影响深深交织在一起。 迄今为止&#xff0c;每一次工业革命都彻底改变了我们社会的轮廓&#xff0c;引入了机械化、大规模生产和数字化&#xff0c;并重新定义了人类生存的规范。 自2022年11月30日OpenAI发布ChatGPT以来&#x…

C++Qt学习——QFile、QPainter、QChart

目录 1、QFile&#xff08;文本读写&#xff09;——概念 1.1、拖入三个控件&#xff0c;对pushButton进行水平布局&#xff0c;之后整体做垂直布局 1.2、按住控件&#xff0c;转到槽&#xff0c;写函数 1.3、打开文件控件 A、首先引入以下两个头文件 B、设置点击打开文件控…

C++进阶之路---手撕“红黑树”

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、红黑树的概念与性质 1.概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点…

多模态数据融合简介#翻译

翻译自—— 感谢外国友人分享&#xff0c;鄙人在此翻译分享给大家INTRODUCTION TO DATA FUSION. multi-modality | by Haylat T | Haileleol Tibebu | Medium 多模态梳理_多模态图像和多模态方法的区别-CSDN博客 #这个网u也写得不错&#xff01; 多模态 神经网络是最著名的机…

idea远程试调jar、远程试调war

idea远程试调jar、远程试调war 目的&#xff1a;测试运行时与ide开发时是否一致。 配置jar Maven中添加 <packaging>jar</packaging>将其打包为jar。 设置运行入口main 编译jar 看到jar输出 配置试调 添加jar运行 远程试调 先在源码中打好断点试调 debug运行…

React的基本使用

安装VSCode插件 ES7 Reactopen in browser React基本使用 基本使用步骤 引入两个JS文件&#xff08; 注意引入顺序 &#xff09; <!-- react库, 提供React对象 --> //本地 <script src"../js/react.development.js"></script> //线上 //<scr…

Python大数据实践:selenium爬取京东评论数据

准备工作 selenium安装 Selenium是广泛使用的模拟浏览器运行的库&#xff0c;用于Web应用程序测试。 Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样&#xff0c;并且支持大多数现代 Web 浏览器。 #终端pip安装 pip install selenium #清华镜像安装 p…

【Ubuntu】Ubuntu的安装和配置

下载ubuntu镜像 https://releases.ubuntu.com/22.04.4/ubuntu-22.04.4-desktop-amd64.iso 一、Ubuntu安装 1.新建虚拟机 1.1按照它的提示创建用户&#xff1b;后面一直下一步就好 2.启动Ubuntu虚拟机 2.1设置为中文键盘 2.2默认即可&#xff1b;若是有低需求也可以选择最小…

企业开展开源安全治理必要性及可行性详细分析

背景 开源软件安全威胁是近几年企业安全面临的主要威胁&#xff0c;也是企业应用安全方向讨论的热门话题&#xff0c;但是由于是新的需求新的方向&#xff0c;很多企业在观望&#xff0c;当前开展这项工作是否已经成熟&#xff0c;项目成功率如何&#xff1f; 当新鲜事物产生时…

【C语言】linux内核软中断

一、什么是软中断&#xff1f; 内核中的软中断&#xff08;Softirqs&#xff09;和任务下半部&#xff08;Tasklets&#xff09;是Linux内核中用于在中断上下文之外处理中断服务的一种底层机制。这些机制解决了不能在中断服务例程&#xff08;ISR&#xff09;中执行耗时操作或…

Apache Doris 2.1 核心特性 Variant 数据类型技术深度解析

在最新发布的 Apache Doris 2.1 新版本中&#xff0c;我们引入了全新的数据类型 Variant&#xff0c;对半结构化数据分析能力进行了全面增强。无需提前在表结构中定义具体的列&#xff0c;彻底改变了 Doris 过去基于 String、JSONB 等行存类型的存储和查询方式。为了让大家快速…

在IDEA中设置使用鼠标滚轮控制字体大小

IDEA是我们常用的程序编程工具&#xff0c;有时为了方便&#xff0c;我们需要随时的调整字体的大小 本篇文章我使用了两种方式来设置IDEA中的字体大小 方式一&#xff1a;使用传统的方式来设置 首先在IDEA顶部的菜单栏中选择“file”菜单 然后在“file”菜单中选择“Setting…

Gitlab-runner注册与配置

文章目录 概要操作流程获取HTTPS证书上传证书修改gitlab-runner dns配置文件gitlab-runner 注册 概要 本文主要介绍了Gitlab-runner在内网环境注册到gitlab的操作方式。内网环境如下&#xff1a; 1、gitlab-runner由docker镜像部署&#xff1b; 2、gitlab部署与内网&#xff0…

3D Tiles语义分割流水线

Dylan Chua 和 Anne Lee 开发了一个处理管线&#xff0c;用于对 3D Tiles 中包含的 GL 传输格式 (glTF) 模型进行语义分割。 该管道读取并遍历 3D Tileset&#xff0c;以输出包含元数据的经过转换的划分对象集。 该项目为 3D 语义分割器提供了最小可行产品&#xff0c;作为各种…