当前位置: 首页 > news >正文

RT_Thread——快速入门

文章目录

  • 一、RT-Thread 目录结构
  • 二、核心文件
  • 三、移植时涉及的文件
    • 3.1 CPU 部分
    • 3.2 BSP 部分
  • 四、内存管理
  • 五、启动流程及main函数
    • 5.1 启动流程
    • 5.2 关键函数速览
    • 5.3 main 函数示例
  • 六、数据类型和编程规范
    • 6.1 数据类型
    • 6.2 函数名
    • 6.3 结构体定义
    • 6.4 注释规范
  • 七、使用模拟器运行第1个程序
  • 八、使用逻辑分析仪
  • 九、与RTOS对比
  • 十、RTT栈回溯示例和栈大小的确认
    • 10.1 栈回溯示例和原理
    • 10.2 栈大小的确认

一、RT-Thread 目录结构

以RT-Thread 源码(V3.1.5)为例,它的目录如下:

在这里插入图片描述

主要涉及3个目录:

  • bsp
    • bsp目录下是各单板的板级支持包(Board support package),即针对某个特定单板兼容适配的工程。比如ST官方公板:stm32f407-st-discovery
    • 移植时,需要针对特定单板适配串口端口、GPIO等
  • libcpu
    • 为了在不同CPU架构芯片上运行,RT-Thread提供libcpu 抽象层对内核提供统一接口,包括全局中断开关、线程栈初始化等
    • 移植时,需要针对特地CPU架构实现全局中断开关、线程上下文切换等
  • src
    • RT-Thread 的核心文件

二、核心文件

以理解、使用RT-Thread 为目标的话,最核心的文件只有5个:

  • src\thread.c
  • src\timer.c.
  • src\scheduler.c
  • src\ipc.c
  • include\rtservice.h

这些文件的作用列表如下:

在这里插入图片描述

三、移植时涉及的文件

移植RT-Thread,包含CPU 部分移植和BSP 部分移植。

3.1 CPU 部分

CPU 部分移植就是移植libcpu 目录,主要涉及cpuport.ccontext_xx.S

比如:libcpu/arm/cortex-m3/cpuport.ccontext_rvds.S,这表示 Cortex-M3 架构在 RVDS 或Keil 工具上的移植文件

  • cpuport.c:主要用来初始化线程的栈
  • context_rvds.S:主要线程切换、全局中断开关

如果RT-Thread 还没支持你使用的CPU,你才需要实现这两个文件。

一般来说,对于大部分的CPU, RT-Thread都已经支持,不需要我们移植。

3.2 BSP 部分

BSP 就是Board Support Packet,板级支持包,就是开发板的相关文件。

BSP 部分主要涉及 main.cboard.crtconfig.h

比如:bsp/stm32/stm32f103-simulator 目录下,包含 applications/main.cboard/board.crtconfig.h

  • main.c:工程的主函数入口
  • board.c:该单板的系统时钟相关配置
  • rtconfig.h:内核配置文件,配置裁剪系统功能

四、内存管理

RT-Thread 操作系统在内存管理上,根据上层应用及系统资源的不同,有针对性地提供了不同的内存分配管理算法。

总体上可分为两类:内存堆管理与内存池管理,而内存堆管理又根据具体内存设备划分为三种情况。

总结起来就是:

  • 内存堆管理:它可以分为下面三种,三种只能选择一种
    • 针对小内存块的分配管理(小内存管理算法):src\mem.c
    • 针对大内存块的分配管理(slab 管理算法):src\slab.c
    • 针对多内存堆的分配情况(memheap 管理算法):src\memheap.c
  • 内存池管理:先从内存堆里申请空间,然后进行二次管理,对应文件: src\mempool.c

注意:

  • src\mem.c、src\slab.c、src\memheap.c 这三个文件只能选择一个文件
  • src\mempool.c:先从堆里分配得到一块内存,把这块内存当做内存池

五、启动流程及main函数

5.1 启动流程

我们习惯从 main 函数开始阅读源码,但是RT-Thread 的主要启动流程反而不在 main 函数里。

以工程 RT-Thread_01_create_task 为例:

  • 第1个文件:startup_stm32f103xe.s
    • 调用 SystemInit :系统初始化,比如初始化时钟
    • 调用 __main:重定位,比如把代码段从 Flash 复制到内存,然后执行 $Sub$$main
  • 第2个文件:src\components.c
    • 执行一系列的初始化
    • 调用 rt_application_init
      • 初始化RTT 组件(包括创建SHELL 线程):因为有SHELL 线程,所以即使 main 函数为空,也是可以操作开发板的
      • 调用 main 函数:可以写为空函数
    • 启动调度器:rt_system_scheduler_start

启动过程如下图所示:

在这里插入图片描述

上图中,位置①处创建了SHELL线程,用户可以在串口上输入各种命令;所以位置②的main函数写为空函数也是可以的。

5.2 关键函数速览

  • $ Sub $$main 函数
int $Sub$$main(void) 
{ rtthread_startup(); return 0; 
} 
  • rtthread_startup 函数
    • 初始化单板
    • 初始化定时器、调度器、信号
    • 创建用户进程:rt_application_init
    • 启动调度器
  • rt_application_init 函数
tid = rt_thread_create("main", main_thread_entry, RT_NULL, RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20); 
  • main_thread_entry 函数做两件事
    • 调用rt_components_init函数:这会初始化一系列的组件,比如创建SHELL线程
    • 调用$ Super $$main函数:就是调用main函数
void main_thread_entry(void *parameter) 
{ extern int main(void); extern int $Super$$main(void); #ifdef RT_USING_COMPONENTS_INIT /* RT-Thread components initialization */ rt_components_init(); #endif /* invoke system main function */ #if defined(__CC_ARM) || defined(__CLANG_ARM) $Super$$main(); /* for ARMCC. */ #elif defined(__ICCARM__) || defined(__GNUC__) main(); #endif 
} 
  • $ Sub $$mainmain的调用过程如下
$Sub$$main() rtthread_startup() rt_application_init() main_thread_entry() $Super$$main() main() 

5.3 main 函数示例

rt_components_init函数中已经创建了SHELL 线程,用户可以通过串口跟它交互。

所以,即使main函数为空,我们还是可以通过串口操作开发板的。

每个工程都有一个main.c文件:

  • 可以把main函数写为空函数
  • 可以在main函数里面创建线程
  • 也可以在main.c任意位置使用宏MSH_CMD_EXPORT定义命令,然后在串口中执行这个命令

main.c示例代码如下:

在这里插入图片描述

六、数据类型和编程规范

6.1 数据类型

RT-Thread的数据类型定义在rtdef.h中,如下所示,涉及8位、16位、32位、64位的定义。

格式为都以rt_开头,然后指明是否是有符号类型和位数,最后以_t结尾。

/* RT-Thread basic data type definitions */ 
##ifndef RT_USING_ARCH_DATA_TYPE 
typedef signed   char                   rt_int8_t;      /**<  8bit integer type */ 
typedef signed   short                  rt_int16_t;     /**< 16bit integer type */ 
typedef signed   int                    rt_int32_t;     /**< 32bit integer type */ 
typedef unsigned char                   rt_uint8_t;     /**<  8bit unsigned integer type */ 
typedef unsigned short                  rt_uint16_t;    /**< 16bit unsigned integer type */ 
typedef unsigned int                    rt_uint32_t;    /**< 32bit unsigned integer type */ ##ifdef ARCH_CPU_64BIT 
typedef signed long                     rt_int64_t;     /**< 64bit integer type */ 
typedef unsigned long                   rt_uint64_t;    /**< 64bit unsigned integer type */ 
##else 
typedef signed long long                rt_int64_t;     /**< 64bit integer type */ 
typedef unsigned long long              rt_uint64_t;    /**< 64bit unsigned integer type */ 
##endif 
##endif 

随后还定义特殊数据类型。

比如rt_base_t是基础数据类型,和芯片位数相关,在Cortex-M3等32位架构中,它就是32位的;在A57等64位架构中,它就是64位的。

rt_err_t用于记录错误编号rt_time_t用于时间戳rt_tick_t用于周期性时钟tick计数

typedef int                             rt_bool_t;      /**< boolean type */ 
typedef long                            rt_base_t;      /**< Nbit CPU related date type */ 
typedef unsigned long                   rt_ubase_t;     /**< Nbit unsigned CPU related data type */ typedef rt_base_t                       rt_err_t;       /**< Type for error number */ 
typedef rt_uint32_t                     rt_time_t;      /**< Type for time stamp */ 
typedef rt_uint32_t                     rt_tick_t;      /**< Type for tick count */ 
typedef rt_base_t                       rt_flag_t;      /**< Type for flags */ 
typedef rt_ubase_t                      rt_size_t;      /**< Type for size number */ 
typedef rt_ubase_t                      rt_dev_t;       /**< Type for device */ 
typedef rt_base_t                       rt_off_t;       /**< Type for offset */ 

6.2 函数名

函数名使用英文小写,单词之间使用 _ 连接,通常以rt_开头,比如:

int rt_hw_spi_init(void) 

如果函数入口参数是空,必须使用 void 作为入口参数。

内部静态函数,则以 _ 开头,不用rt_开头,比如:

static rt_err_t _uart_configure()

6.3 结构体定义

函数名使用英文小写,单词之间使用_连接,比如:

struct rt_list_node 
{ struct rt_list_node *next; struct rt_list_node *prev; 
};

结构体的类型定义,使用结构体名称加上 _t 的形式,例如:

typedef struct rt_list_node rt_list_t;

6.4 注释规范

注释以 /** 开头,以 */ 结尾,中间写入函数注释,组成元素如下,每个元素描述之间空一行,且首列对齐。

  • @brief + 简述函数作用。在描述中,着重说明该函数的作用
  • @note + 函数说明。在上述简述中未能体现到的函数功能或作用的一些点,可以做解释说明
  • @see + 相关 API 罗列。若有与当前函数相关度较高的 API,可以进行列举
  • @param + 以参数为主语 + be 动词 + 描述,说明参数的意义或来源
  • @return + 枚举返回值 + 返回值的意思,若返回值为数据,则直接介绍数据的功能
  • @warning + 函数使用注意要点。在函数使用时,描述需要注意的事项,如使用环境、使用方式
    注释模版请参见:rt-thread/src/ipc.c 源码文件。

七、使用模拟器运行第1个程序

双击"RT-Thread_01_create_task\bsp\stm32\stm32f103-simulator\project.uvprojx"打开第一个示例。

打开之后,首先要编译工程,才能使用模拟器运行,点击"Build"图标进行编译,如下图所示:
在这里插入图片描述
编译完成后,点击"Debug"按钮进行仿真,如下图所示:
在这里插入图片描述
第一个程序里面创建了两个任务,两个任务一直打印各自的信息。

这里需要打开串口显示模拟窗口,显示任务的打印内容。

点击左上角菜单的“View”,然后选择“Serial Windows”,点击“UART #1”,如下图所示:

在这里插入图片描述

最后,点击“Run”运行程序,右下角串口显示窗口将打印两个任务的信息。

在这里插入图片描述

如果想退出模拟器仿真,再次"Debug"按钮退出,如下图所示:

在这里插入图片描述

八、使用逻辑分析仪

此程序有两种输出方式:

  • 串口:查看打印信息
  • 逻辑分析仪:观察全局变量的波形,根据波形解析任务调度情况 下面举例说明逻辑分析仪的用法。

双击"RT-Thread_06_taskdelay\bsp\stm32\stm32f103-simulator\project.uvprojx"打开该示例。

打开之后,首先要编译工程,点击"Build"图标进行编译。

编译完成后,点击"Debug"按钮进行仿真。

本实例使用模拟器的逻辑分析仪观察现象。

首先在“main.c”的主函数加入断点,在代码行前的灰色处,点击一下就会有一个红色小点,就是设置的“断点”。

在这里插入图片描述
然后点击“Run”运行,程序运行到断点位置,就会停下来等待下一步操作:

  • 在代码中找到全局变量flag
  • 鼠标选中flag,然后点击鼠标右键,在弹出的菜单里选择"Add ‘flag’ to…",选择“Analyzer”,如下图所示:

在这里插入图片描述
此时在代码框上面,就会出现逻辑分析仪“Logic Analyzer”显示窗口,里面分析的就是变量flag。

点击这个flag,然后右键,选择“Bit”,以便观察,如下图所示:

在这里插入图片描述

再点击一下“Run”,继续运行,此时逻辑分析仪窗口显示变量flag 的bit 值变化,如下图所示:

在这里插入图片描述

在逻辑分析仪窗口,可以使用鼠标滚轮放大、缩小波形。

九、与RTOS对比

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

A执行一半轮到B执行,B一开始执行发现获得不到信号量就会从就绪链表中退出进入休眠状态,导致定时器中断时无法让B运行,所以在后续会一直执行A,直到A运行完毕释放信号量,B才会被唤醒,才能够正常运行。

在这里插入图片描述

在RTOS中,prvSetupHardware()会先去完成硬件相关初始化,接着创建任务,此时创建任务后会将任务放入一个就绪链表中,并去启动调度器;而在RTT中,在main函数前就完成硬件相关初始化,并去创建任务,注意此时与RTOS不一样的是它创建完任务并没有直接将任务放入就绪链表中,而是通过启动线程才能将任务放入就绪链表中,最后在其他地方去启动调度器。

在这里插入图片描述

由上图可知,RTOS中启动后会运行main函数,main函数再去启动调度器;而RTT是在启动后创建了一个线程,线程会启动调度器,该线程才能得以运行,接着去运行main函数

十、RTT栈回溯示例和栈大小的确认

10.1 栈回溯示例和原理

在这里插入图片描述
在这里插入图片描述

在执行上述函数时,发现串口打印到PC地址时会奔溃,要想找到发生奔溃的位置,我们首先需要找到错误位置。由于是在打印PC地址时发生奔溃,说明PC地址对应的函数中出现问题,接下来我们就需要去查看反汇编,找到改地址对应的函数:

在这里插入图片描述

接着我们需要去分析栈,我们需要去改下部分代码,去打印正常栈的地址,以便区别异常栈:

unsigned int *app_sp;
unsigned int *app_sp_top;int i;
app_sp = (unsigned int *)(context + 1);  /* context(异常栈大小) + 16*4 */ //异常栈大小+1为正常栈位置rt_kprintf("app stacks: \r\n");
app_sp_top = (unsigned int *)((unsigned int)rt_thread_self()->stack_addr + rt_thread_self()->stack_size);
i = 0;
while (app_sp_top >= app_sp)
{rt_kprintf("%08x ", *app_sp_top);app_sp_top--;i++;if (i % 16 == 0)rt_kprintf("\r\n");
}

打印出来的地址如下:
在这里插入图片描述

可见fputc函数的栈指针指向0x0800128f,要想知道调用fputc的函数地址,只需在fputc函数的地址减一即可找到:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

所以我们找到调用fputc的函数是printf函数,而printf函数的栈指针指向0x05501dbb,要想知道调用printf的函数地址,只需在printf函数的地址减一即可找到:
在这里插入图片描述
在这里插入图片描述

说明是在main函数中调用printf导致的奔溃,解决办法是将printf改成rtt中封装的打印函数rtt_kprintf。

 while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */rt_thread_mdelay(500);HAL_GPIO_TogglePin(LED_B_GPIO_Port,LED_B_Pin);//printf("hello\r\n");rt_kprintf("hello\r\n");}

10.2 栈大小的确认

在这里插入图片描述
①:调用test_stack函数时,一进去LR就会把返回地址保存进栈中
②:接着我们定义了一个大小为100的int型数组,其大小为100*4=400,于是SP栈指针指向SP-404的位置,分成一个栈给数组(多分配出的4个字节可能是编译器问题)
③:接下来在r0为存在sp+4的位置,由图可见,此时除去r0,r0往上的栈才是真正数组的栈(这里的汇编的上一行r1表示的是strcpy函数里面的参数字符串,保存在Flash中)
④:调用strcpy函数进行数组赋值
⑤:SP栈指针回到LR寄存器的位置
⑥:调用POP指令后SP栈指针指向栈的最顶端

这里说明了在调用函数test_stack时,会分配给其对应的栈,当函数执行完毕,该栈会被回收。

在这里插入图片描述

在

在上述函数中,会在栈的起始放入‘#’,以此来区别别的栈,当放入的不为‘#’时,说明此处为栈的截至位置,则可以知道栈的大小,如果要想知道一个线程用了多少栈,则与下面函数有关:

在这里插入图片描述

红框内说明当栈内为‘’#时,指针会一直从低处到高处增加,并计算栈大小。

相关文章:

RT_Thread——快速入门

文章目录 一、RT-Thread 目录结构二、核心文件三、移植时涉及的文件3.1 CPU 部分3.2 BSP 部分 四、内存管理五、启动流程及main函数5.1 启动流程5.2 关键函数速览5.3 main 函数示例 六、数据类型和编程规范6.1 数据类型6.2 函数名6.3 结构体定义6.4 注释规范 七、使用模拟器运行…...

Java 参数值传递机制

一个很经典的问题: java的方法入参 是值传递还是地址传递&#xff1f; 答案是&#xff1a;值传递。 今天排查一个生产问题&#xff0c;数据库链接资源没有关闭。 大致代码逻辑如下&#xff1a; try{Preparestatement ps null;String sql "select * from tableA wher…...

Redis 的 key 的过期策略是怎么实现的

在 Redis 中&#xff0c;有一个 expire 命令&#xff0c;用来设置某个 key 的过期时间&#xff0c;当超过这个时间后&#xff0c;这个 key 就被删除了&#xff0c;我们也就获取不到了&#xff0c;但是 Redis 是如何做到对于每一个设置了过期时间的 key 都能按时删除的呢&#x…...

ROG NUC 2025 :狂暴而冷静的小猛兽

在今年1 月的 CES 展会上&#xff0c;华硕首次披露了ROG NUC 2025&#xff0c;就以突破性紧凑设计桌面级超强性能配置&#xff0c;引发全球科技媒体和游戏爱好者的热议。蛰伏数月&#xff0c;蓄力进化&#xff01; 华硕自承接英特尔NUC产品线以来&#xff0c;就一直致力于重塑迷…...

origin绘图之【如何将多条重叠、高度重叠的点线图、折线图分开】

在使用 Origin 进行数据可视化时&#xff0c;尤其是在绘制多组数据的折线图或点线图时&#xff0c;我们经常会遇到这样的问题&#xff1a;多条曲线重叠严重&#xff0c;难以区分&#xff0c;导致图形信息密集、可读性差&#xff0c;影响图表的传达效果。 那么&#xff0c;我们该…...

2025第一届轩辕杯--Crypto--WriteUp

2025第一届轩辕杯–Crypto–WriteUp Crypto easyrsa task e 65537 n 1000000000000000000000000000156000000000000000000000000005643 c 418535905348643941073541505434424306523376401168593325605206exp from Crypto.Util.number import inverse, long_to_bytese …...

人工智能范式:技术革命下的认知重构

当生成式AI能够自主创作内容、设计解决方案甚至编写程序时&#xff0c;我们正在见证的不仅是工具革新&#xff0c;更是一场认知范式的根本转变。人工智能范式正在重塑人类理解世界、解决问题和创造价值的基本方式——这种转变将重新定义未来十年的职业逻辑与知识体系。 一、范…...

python训练营打卡第30天

模块和库的导入 知识点回顾&#xff1a; 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑&#xff1a;找到根目录&#xff08;python解释器的目录和终端的目录不一致&#xff09; 一、导入官方库 1.标准导入&#xff1a;导入整个库 import mathprint(&quo…...

第29天-python实现mysql数据增删改查

想用Python和Tkinter实现一个MySQL数据库的增删改查应用。首先,我需要确定用户的需求是什么。他们可能想要一个图形界面,方便操作数据库,而不需要直接写SQL语句。用户可能对Python和Tkinter有一定了解,但对如何整合数据库操作可能不太熟悉。 首先,我应该考虑如何设计界面。…...

2025.05.21华为暑期实习机考真题解析第三题

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 03. GPU资源租赁优化 问题描述 A先生是一家云计算服务商的资源调度负责人,负责管理公司的GPU资源租赁业务。公司拥有多个高性能GPU核心,并按时间段出租给不同客户使用。每个客户有…...

Datawhale 5月llm-universe 第4次笔记

第四章 构建RAG应用 envs 在 Conda 中&#xff0c;envs 目录是用来存放虚拟环境的地方。 也就是说&#xff0c;你在运行&#xff1a; onda create -n llm-universe python3.10 时&#xff0c;Conda 就会在这个路径下创建一个新的文件夹&#xff1a; makefile D:\Users\…...

滑窗问题实验LC2653(一次遍历维持窗口元素保持排序)

在只有一次遍历&#xff08;即滑窗每向右移动一步只处理新增元素和删除旧元素&#xff09;的前提下&#xff0c;要维持当前窗口内元素的全局“可排序”结构 问题背景&#xff1a;LeetCode 2653 - 滑动子数组的美丽值 题目要求在大小为 k 的滑动窗口中&#xff0c;找到第 x 小…...

PHP学习笔记(八)

返回值 值通过可选参数的返回语句返回 return的使用 函数不能返回多个值&#xff0c;但可以通过返回一个数组来得到类似的效果 函数返回一个引用&#xff0c;必须在函数声明和指派返回值给一个变量时都使用引用运算符&&#xff1a; 可变函数 PHP支持可变函数的概念。意味…...

【react18】在styled-components中引入图片报错

在styled-components项目中&#xff0c;遇到背景图片显示不出来的问题。图片的确是引入正确&#xff0c;但是webpack解析路径是有问题的 效果展示 以下这两种写法都不行&#xff0c;无法生效 export const HeaderNavLeft styled.h1width: 176px;height: 69px;background: ur…...

693SJBH基于.NET的题库管理系统

计算机与信息学院 本科毕业论文&#xff08;设计&#xff09;开题报告 论文中文题目 基于asp.net的题库管理系统设计与实现 论文英文题目 Asp.net based database management system design and Implementation 学生姓名 专业班级 XXXXXX专业08 班 ⒈选题的背景和意…...

centos系统redis-dump安装

1. ​Ruby 环境​ Redis-dump 是一个 Ruby 工具&#xff0c;需先安装 Ruby 和 RubyGems。 安装依赖​&#xff1a; sudo yum install -y curl gpg2 gcc-c patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf aut…...

如何利用 Conda 安装 Pytorch 教程 ?

如何利用 Conda 安装 Pytorch 教程 &#xff1f; 总共分为六步走&#xff1a; &#xff08;1&#xff09;第一步&#xff1a;验证conda 环境是否安装好&#xff1f; 1) conda -V2) conda --version&#xff08;2&#xff09;第二步&#xff1a;查看现有环境 conda env list…...

FPGA降低功耗研究

FPGA降低功耗研究 首先要明白一点&#xff1a;我们的核心目标是在维持性能的前提下&#xff0c;通过工艺、架构、设计方法学和系统级策略的协同优化&#xff0c;降低动态功耗、静态功耗和短路功耗。 本篇文章则是聚焦于 FPGA 设计阶段 的功耗优化&#xff0c;主要从 RTL 代码设…...

软考 系统架构设计师系列知识点之杂项集萃(67)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;66&#xff09; 第108题 RISC&#xff08;精简指令系统计算机&#xff09;的特点不包括&#xff08;&#xff09;。 A. 指令长度固定&#xff0c;指令种类尽量少 B. 寻址方式尽量丰富&#xff…...

第十节第三部分:常见API:传统时间:Date日期类、SimpleDateFormat

Date日期类常用方法 时间格式常用符号 Date日期类总结 为什么用SimpleDateFormat SimpleDateFormat常见方法 SimpleDateFormat解析字符串时间成为日期对象 SimpleDateFormat总结 代码&#xff1a; 代码一&#xff1a;Date日期类 package com.itheima.Time;import java.util.D…...

Python学习Day1:安装

Python的安装 1.安装python 打开python的官网&#xff0c;我们下载3.6.8版本Python Release Python 3.6.8 | Python.org 根据自己的电脑来下载对应的python版本 如图所示&#xff1a; 我已经下载完成&#xff0c;就是这样&#xff0c; 安装页面的第一排是自动安装&#xf…...

Java安全-Servlet内存马

内存马简介 内存马是指将恶意代码注入到内存中&#xff0c;达到无文件落地的效果&#xff0c;使得被攻击方难以察觉。由于是无文件的形式&#xff0c;可以绕过部分基于文件检测的杀软。而 Servlet 内存马是基于 Java Servlet 技术&#xff0c;动态将恶意代码注入到 Tomcat 内存…...

Mariadb cpu 93% 问题

最近项目遇到cpu平均使用率93% 一、登录数据库服务查看具体情况 可以看到服务器负载很高&#xff0c;&#xff0c;mariadb CPU使用已达到接近380.4% &#xff08;因为是8核&#xff0c;所以会有超过100%的情况&#xff09;。如下图&#xff1a; 二、排查是否有耗时较长sql 在…...

LeetCode222_完全二叉树的结点个数

LeetCode222_完全二叉树的结点个数 标签&#xff1a;#位运算 #树 #二分查找 #二叉树Ⅰ. 题目Ⅱ. 示例 0. 个人方法 标签&#xff1a;#位运算 #树 #二分查找 #二叉树 Ⅰ. 题目 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&…...

linux 查看java的安装路径

一、验证Java安装状态 java -version正常安装会显示版本信息&#xff1a; openjdk version "1.8.0_65" OpenJDK Runtime Environment (build 1.8.0_65-b17) OpenJDK 64-Bit Server VM (build 25.65-b01, mixed mode)二、检查环境变量配置 若已配置JAVA_HOME&#…...

day32 python解释性库PDPbox

目录 一、初识PDPbox官方文档 二、准备鸢尾花数据集和训练模型 三、使用PDPbox进行解释性分析 1. 导入类并实例化对象 2. 调用plot方法绘制图形 3. 探索返回值的意义 四、总结与感悟 作为一名正在学习机器学习的学生&#xff0c;今天要学习一个非常有趣的库——PDPbox&am…...

LVLM-AFAH论文精读

Basic Information 标题&#xff1a;Your Large Vision-Language Model Only Needs A Few Attention Heads For Visual Grounding作者&#xff1a;Seil Kang&#xff0c; Jinyeong Kim&#xff0c; Junhyeok Kim&#xff0c; Seong Jae Hwang机构&#xff1a;Yonsei Universit…...

蓝桥杯3503 更小的数

问题描述 小蓝有一个长度均为 n 且仅由数字字符 0∼9 组成的字符串&#xff0c;下标从 0 到 n−1&#xff0c;你可以将其视作是一个具有 n 位的十进制数字 num&#xff0c;小蓝可以从 num 中选出一段连续的子串并将子串进行反转&#xff0c;最多反转一次。 小蓝想要将选出的子…...

5.21本日总结

一、英语 复习list4list26 二、数学 学完14讲&#xff0c;1000题13讲写完 三、408 学习计网5.3剩余内容 四、总结 高数本月结束知识点学习&#xff0c;15讲知识点与14讲的题目同步进行。408剩余两本书要加快学习进度。 五、明日计划 英语&#xff1a;复习lsit5list25 …...

【25软考网工】第七章(3) UOS Linux防火墙配置和Web应用服务配置

博客主页&#xff1a;christine-rr-CSDN博客 ​​​专栏主页&#xff1a;软考中级网络工程师笔记 ​​​​ 大家好&#xff0c;我是christine-rr !目前《软考中级网络工程师》专栏已经更新三十多篇文章了&#xff0c;每篇笔记都包含详细的知识点&#xff0c;希望能帮助到你&am…...

Python数据分析基础

Python数据分析入门 介绍 在这个教程中&#xff0c;我们将学习如何使用Python来进行基本的数据分析。 安装必要的库 为了开始&#xff0c;你需要安装以下Python库&#xff1a; NumPyPandasMatplotlib 示例代码 import numpy as np import pandas as pd import matplotli…...

spring cloud config更新配置

在开发微服务时&#xff0c;往往需要有开发环境、测试环境和生产环境&#xff0c;手动修改配置环境是一件很麻烦的事情&#xff0c;因此&#xff0c;这里使用spring cloud config管理配置环境。要使用spring cloud config&#xff0c;需要先在GitHub搭建一个仓库。 一、仓库搭…...

小米汽车二期工厂下月将竣工,产能提升助力市场拓展

在新能源汽车市场竞争日益激烈的当下&#xff0c;小米汽车传来重要进展消息。据多方信息显示&#xff0c;小米汽车二期工厂下月即将竣工&#xff0c;这一关键节点的到来&#xff0c;有望为小米汽车的产能提升与市场布局带来重大突破。​ 小米汽车二期工厂位于北京亦庄&#xff…...

【单片机】如何产生负电压?

以下是对知乎文章《单片机中常用的负电压是这样产生的&#xff01;》的解析与总结&#xff0c;结合电路原理、应用场景及讨论要点展开&#xff1a; 一、负电压产生的核心原理 负电压本质是相对于参考地&#xff08;GND&#xff09;的电势差为负值&#xff0c;需通过电源或储能…...

Mcu_Bsdiff_Upgrade

系统架构 概述 MCU BSDiff 升级系统通过使用二进制差分技术&#xff0c;提供了一种在资源受限的微控制器上进行高效固件更新的机制。系统不传输和存储完整的固件映像&#xff0c;而是只处理固件版本之间的差异&#xff0c;从而显著缩小更新包并降低带宽要求。 该架构遵循一个…...

阿里云ecs 8核 16G 内存 装有redis6 分配了3G内存,和2个tomcat 每个tomcat 4G 服务器反应迟钝,如何确认不是redis的问题

我们经常用redis 但遇到tomcat timeout的时候&#xff0c;如何确认不是redis的问题。 不能因为这个再去搞个redis 压力测试。有没有更省劲的方法来确认不是redis的问题 以下是针对 阿里云 ECS&#xff08;8核16G&#xff0c;Redis 6分配3G内存&#xff0c;2个Tomcat各分配4G&a…...

机器学习-KNN算法

1.机器学习概述&#xff08;全部流程&#xff09; 获取数据&#xff1a;from sklearn.datasets import load_wine 数据处理(数据集划分、标准化):from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler 特征工程:from s…...

【数据结构 · 初阶】- 快速排序

目录 一. Hoare 版本 1. 单趟 2. 整体 3. 时间复杂度 4. 优化&#xff08;抢救一下&#xff09; 4.1 随机选 key 4.2 三数取中 二. 挖坑法 格式优化 三. 前后指针&#xff08;最好&#xff09; 四. 小区间优化 五. 改非递归 快速排序是 Hoare 提出的一种基于二叉树…...

HTTPS和HTTP区别

客户端向服务器发送HTTPS请求。服务器响应并发送其数字证书。客户端通过证书的公钥验证数字签名的有效性&#xff0c;如果有效&#xff0c;客户端生成一个随机的对称密钥。客户端使用公钥对这个对称密钥进行加密&#xff0c;然后将加密后的密钥发送给服务器。服务器使用自己的私…...

自动驾驶中的预测控制算法:用 Python 让无人车更智能

自动驾驶中的预测控制算法:用 Python 让无人车更智能 自动驾驶技术近年来取得了令人惊叹的进步,AI 与边缘计算的结合让车辆能够实时感知环境、规划路径并执行驾驶决策。其中,预测控制(Model Predictive Control,MPC) 作为一种先进的控制算法,凭借其对未来驾驶行为的优化…...

分享一些实用的网址

第一个&#xff1a;视频转化为动图 网址&#xff1a;https://www.freeconvert.com/zh/convert/mp4-to-gif 当然还有很多其他的功能&#xff0c;可以按需选择使用。 第二个&#xff1a;ASCII字符串到16进制在线转换工具 网址 &#xff1a;https://coding.tools/cn/ascii-to-…...

打开小程序提示请求失败(小程序页面空白)

1、小程序代码是商城后台下载的还是自己编译的 &#xff08;1&#xff09;要是商城后台下载的&#xff0c;检查设置里面的域名是不是https的 &#xff08;2&#xff09;要是自己编译的&#xff0c;检查app.js里面的接口域名是不是https的&#xff0c;填了以后有没有保存 注&a…...

Taro 安全区域

目录 一、问题描述 二、问题解决 1、顶部刘海区 2、底部小黑条 一、问题描述 安全区域主要是为了避免刘海屏或底部栏遮挡&#xff0c;而造成的不良显示效果。 本次将针对以下两点进行考量&#xff1a; 1、顶部刘海屏区 2、苹果X底部小黑条 二、问题解决 通过Taro.getS…...

DL00988-稀疏增强数据transformer船舶AIS轨迹预测含完整数据集

提升科研效率&#xff0c;精准预测船舶AIS轨迹&#xff01;文末有完整获取方式 作为研究生和科研人员&#xff0c;是否在进行船舶轨迹预测时遇到数据稀疏、轨迹复杂等问题&#xff1f;现在&#xff0c;我们为你提供一款基于稀疏增强数据Transformer的船舶AIS轨迹预测工具&#…...

重写B站(网页、后端、小程序)

1. 网页端 1.1 框架 Vue ElementUI axios 1.2 框架搭建步骤 搭建Vue 1.3 配置文件 main.js import {createApp} from vue import ElementUi from element-plus import element-plus/dist/index.css; import axios from "axios"; import router from…...

SOPHGO算能科技BM1688内存使用与编解码开发指南

1. BM1688内存分配接口详解 1.1 设备内存分配接口区别 BM1688提供了三个主要的设备内存分配接口,它们的主要区别如下: // 基本设备内存分配接口 void* bm_malloc_device_byte(bm_handle_t handle, unsigned int size);// 指定heap区域的设备内存分配 void*</...

如何使用Antv X6使用拖拽布局?

拖拽效果图 拖拽后 布局预览 官方&#xff1a; X6 图编辑引擎 | AntV 安装依赖 # npm npm install antv/x6 --save npm install antv/x6-plugin-dnd --save npm install antv/x6-plugin-export --save需要引入的代码 import { Graph, Shape } from antv/x6; import { Dnd } …...

STM32项目分享:智能家居(机智云)升级版

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; STM32智能家居(机智云)升级版 &#xff08;资料…...

Flask-SQLAlchemy核心概念:模型类与数据库表、类属性与表字段、外键与关系映射

前置阅读&#xff0c;关于Flask-SQLAlchemy支持哪些数据库及基本配置&#xff0c;链接&#xff1a;Flask-SQLAlchemy_数据库配置 摘要 本文以一段典型的 SQLAlchemy 代码示例为引入&#xff0c;阐述以下核心概念&#xff1a; 模型类&#xff08;Model Class&#xff09; ↔ 数…...

算法优选系列(9.BFS 解决拓扑排序)

目录 拓扑排序简介&#xff1a; ​编辑 课程表&#xff08;medium&#xff09;&#xff1a; 课程表II&#xff08;medium&#xff09;: 火星词典&#xff08;hard&#xff09;&#xff1a; 拓扑排序简介&#xff1a; 有向无环图&#xff08;DAG图&#xff09; 如上图每条边…...