FREERTOS内容解惑与综合应用(基于STM32F103)

news2024/11/20 3:34:40
本文基础内容参考的是正点原子的FREERTOS课程。

这是基于HAL库的

正点原子手把手教你学FreeRTOS实时系统

这是基于标准库的

正点原子FreeRTOS手把手教学-基于STM32

基础知识,直接参考正点原子《FreeRTOS开发指南V1.1》基于标准库的,此处不再赘述。

本文主要对不理解的地方进行查缺补漏,并且先用起来,涉及到原理的部分,可以观看上述教学视频或者开发指南。



官网

官网首页:

FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions

官网参考手册:

官网参考手册:FreeRTOS 内核快速入门指南

注意事项:

官网进入比较慢,API估计都进不去。

这时如果需要查看API,可以查看正点原子给的几个文档

在这几个文档里搜索一下应该就能找到,可以优先看中文文档,没有的话再看英文文档。

使用步骤

1、参考正点原子《FreeRTOS开发指南V1.1》“第二章 FreeRTOS 移植,进行移植。

其中,如果不用正点原子system目录中的三个文件,可以删除。

STM32裸机可以使用systick延时,但是操作系统就没必要使用systick来实现延时了。

如果删除这三个文件,那么这部分跟RTOS相关的内容就需要单独设置。

其中最相关的就是systick的使用,因为裸机中systick被用来做延时,但是到了操作系统中,systick就要用来做系统的时钟节拍了,不推荐用来延时(但是正点原子实现了鱼与熊掌都可兼得)。

这里插一句,正点原子的移植在这块耦合性太强了,就是说最好使用他的这三个文件,如果不用,移植过程就不太一样了。

这一块颇为麻烦。

所以,试图换个教程看看如何移植的

更换教程链接如下

2.3-FreeRTOS移植--FreeRTOS移植_哔哩哔哩_bilibili

该教程在工程建立之前的步骤和正点原子几乎是一致的。

所以,文件移植部分,可以参考这里,也可以参考正点原子。

绕过正点原子修改SYSTEM文件夹等后续环节,之后的移植部分参考上述视频链接,并在此记录。

引入FreeRTOSConfig.h配置文件后,编译,会提示以下内容:

这是因为freertos中也定义了SVC 中断服务函数SVC_Handler()和 PendSV 中断服务函数PendSV_Handler(),而我们STM32的中断文件stm32f10x_it.c中也定义了。

所以,需要将STM32定义的这两个空中断处理函数给屏蔽掉。

之后再编译就没有错误了。

接下来,还需要配置systick时钟。

看到这里,发现这个视频应该也是参考的正点原子。

但是看了这个视频,可以确认SYSTEM中只有delay.c这个文件和freertos关系比较大,因为就是在这里配置了systick,所以,我们干脆把正点原子的delay.c拿来使用,并将文件改名为systick.c,反正这个文件既能实现延时,也能实现任务调度。

注意,正点原子是将systick的中断服务函数放到了delay.c中,所以我们在stm32中断处理文件中,将SysTick_Handler(void)函数也屏蔽掉。

在systick.c文件中,跟freertos使用systick定时器配置的部分是这几个部分:

这里有个频率设置configTICK_RATE_HZ,是在FreeRTOSConfig.h文件中定义的,我们直接在配置文件中更改,就能更改相应的中断间隔,默认是1000Hz,即每1/1000s,也就是1ms产生一次中断,也就是说,任务调度的时间片就是1ms。

初始化之后,就会周期性地调用systick的中断服务函数。

其中,xPortSysTickHandler();函数是在port.c函数中定义的。

另外,提下该文件中的几个延时函数。

delay_ms中,在操作系统运行时,调用了vTaskDelay函数,所以会引起任务调度,需要注意,delay_xms是单纯调用delay_us实现的,所以不会引起任务调度。

2、参考正点原子《FreeRTOS开发指南V1.1》“第三章 FreeRTOS 系统配置 ,熟悉配置文件FreeRTOSConfig.h

/***************************************************************************************************************/
/*                                        FreeRTOS基础配置配置选项                                              */
/***************************************************************************************************************/
#define configUSE_PREEMPTION					1                       //1使用抢占式内核,0使用协程
#define configUSE_TIME_SLICING					1						//1使能时间片调度(默认式使能的)
#define configUSE_PORT_OPTIMISED_TASK_SELECTION	1                       //1启用特殊方法来选择下一个要运行的任务
                                                                        //一般是硬件计算前导零指令,如果所使用的
                                                                        //MCU没有这些硬件指令的话此宏应该设置为0!
#define configUSE_TICKLESS_IDLE					0                       //1启用低功耗tickless模式
#define configUSE_QUEUE_SETS					1                       //为1时启用队列
#define configCPU_CLOCK_HZ						(SystemCoreClock)       //CPU频率
#define configTICK_RATE_HZ						(1000)                  //时钟节拍频率,这里设置为1000,周期就是1ms
#define configMAX_PRIORITIES					(32)                    //可使用的最大优先级
#define configMINIMAL_STACK_SIZE				((unsigned short)130)   //空闲任务使用的堆栈大小
#define configMAX_TASK_NAME_LEN					(16)                    //任务名字字符串长度

#define configUSE_16_BIT_TICKS					0                       //系统节拍计数器变量数据类型,
                                                                        //1表示为16位无符号整形,0表示为32位无符号整形
#define configIDLE_SHOULD_YIELD					1                       //为1时空闲任务放弃CPU使用权给其他同优先级的用户任务
#define configUSE_TASK_NOTIFICATIONS            1                       //为1时开启任务通知功能,默认开启
#define configUSE_MUTEXES						1                       //为1时使用互斥信号量
#define configQUEUE_REGISTRY_SIZE				8                       //不为0时表示启用队列记录,具体的值是可以
                                                                        //记录的队列和信号量最大数目。
#define configCHECK_FOR_STACK_OVERFLOW			0                       //大于0时启用堆栈溢出检测功能,如果使用此功能
                                                                        //用户必须提供一个栈溢出钩子函数,如果使用的话
                                                                        //此值可以为1或者2,因为有两种栈溢出检测方法。
#define configUSE_RECURSIVE_MUTEXES				1                       //为1时使用递归互斥信号量
#define configUSE_MALLOC_FAILED_HOOK			0                       //1使用内存申请失败钩子函数
#define configUSE_APPLICATION_TASK_TAG			0                       
#define configUSE_COUNTING_SEMAPHORES			1                       //为1时使用计数信号量

/***************************************************************************************************************/
/*                                FreeRTOS与内存申请有关配置选项                                                */
/***************************************************************************************************************/
#define configSUPPORT_DYNAMIC_ALLOCATION        1                       //支持动态内存申请
#define configTOTAL_HEAP_SIZE					((size_t)(20*1024))     //系统所有总的堆大小

/***************************************************************************************************************/
/*                                FreeRTOS与钩子函数有关的配置选项                                              */
/***************************************************************************************************************/
#define configUSE_IDLE_HOOK						0                       //1,使用空闲钩子;0,不使用
#define configUSE_TICK_HOOK						0                       //1,使用时间片钩子;0,不使用

/***************************************************************************************************************/
/*                                FreeRTOS与运行时间和任务状态收集有关的配置选项                                 */
/***************************************************************************************************************/
#define configGENERATE_RUN_TIME_STATS	        0                       //为1时启用运行时间统计功能
#define configUSE_TRACE_FACILITY				1                       //为1启用可视化跟踪调试
#define configUSE_STATS_FORMATTING_FUNCTIONS	1                       //与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
                                                                        //prvWriteNameToBuffer(),vTaskList(),
                                                                        //vTaskGetRunTimeStats()
                                                                        
/***************************************************************************************************************/
/*                                FreeRTOS与协程有关的配置选项                                                  */
/***************************************************************************************************************/
#define configUSE_CO_ROUTINES 			        0                       //为1时启用协程,启用协程以后必须添加文件croutine.c
#define configMAX_CO_ROUTINE_PRIORITIES         ( 2 )                   //协程的有效优先级数目

/***************************************************************************************************************/
/*                                FreeRTOS与软件定时器有关的配置选项                                            */
/***************************************************************************************************************/
#define configUSE_TIMERS				        1                               //为1时启用软件定时器
#define configTIMER_TASK_PRIORITY		        (configMAX_PRIORITIES-1)        //软件定时器优先级
#define configTIMER_QUEUE_LENGTH		        5                               //软件定时器队列长度
#define configTIMER_TASK_STACK_DEPTH	        (configMINIMAL_STACK_SIZE*2)    //软件定时器任务堆栈大小

/***************************************************************************************************************/
/*                                FreeRTOS可选函数配置选项                                                      */
/***************************************************************************************************************/
#define INCLUDE_xTaskGetSchedulerState          1                       
#define INCLUDE_vTaskPrioritySet		        1
#define INCLUDE_uxTaskPriorityGet		        1
#define INCLUDE_vTaskDelete				        1
#define INCLUDE_vTaskCleanUpResources	        1
#define INCLUDE_vTaskSuspend			        1
#define INCLUDE_vTaskDelayUntil			        1
#define INCLUDE_vTaskDelay				        1
#define INCLUDE_eTaskGetState			        1
#define INCLUDE_xTimerPendFunctionCall	        1

/***************************************************************************************************************/
/*                                FreeRTOS与中断有关的配置选项                                                  */
/***************************************************************************************************************/
#ifdef __NVIC_PRIO_BITS
	#define configPRIO_BITS       		__NVIC_PRIO_BITS
#else
	#define configPRIO_BITS       		4                  
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			15                      //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5                       //系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/***************************************************************************************************************/
/*                                FreeRTOS与中断服务函数有关的配置选项                                          */
/***************************************************************************************************************/
#define xPortPendSVHandler 	PendSV_Handler
#define vPortSVCHandler 	SVC_Handler

直接查看对应的注释即可。

补充说明

每个任务都有自己的堆栈。设置堆栈大小时,单位是字,也就是四个字节。

任务优先级理论上是无限的,但因为和configUSE_PORT_OPTIMISED_TASK_SELECTION这个宏的功能相关,也就是和硬件相关,所以最大只能设置到32。不过一般也不会用到32个优先级。

关于宏configUSE_16_BIT_TICKS

宏configCHECK_FOR_STACK_OVERFLOW一般只在调试阶段打开。

暂且认为钩子函数就是回调函数吧。

heap4.c中实现了动态内存管理函数。

堆的内存池大小也在heap4.c中有使用。

这里总堆大小的单位是字节,定义的是20K,具体情况具体设置。

这些都是跟调试相关的

3、熟悉正点原子《FreeRTOS开发指南V1.1》“第四章 FreeRTOS 中断配置和临界段

在使用FREERTOS时,需要将STM32的优先级分组设置为分组4,即 NVIC_PriorityGroup_4
这样的话优先级就都全是抢占优先级了,没有亚优先级,那么就有 0~15 共 16 个优先级。
因为FREERTOS有抢占式调度,其中断配置没有处理亚优先级这种情况,为了更好地实现抢占式调度,所以只使用抢占优先级。
FreeRTOS 的开关中断就是操作 BASEPRI 寄存器来实现的!它可以关闭低于某个阈值的中断,高于这个阈值的中断就不会被关闭!
这里注意,STM32的中断机制中,数值越小,优先级越高,数值越大,优先级越低。
比如,设置关中断时设置阈值为5,那么数值高于5的中断都会被关闭,而数值低于5的中断就不会被关闭。
PendSV SysTick 优先级在函数 xPortStartScheduler()中设置,该函数在启动任务调度的函数vTaskStartScheduler中被调用,即PendSV SysTick 优先级在开启任务调度器时被设置,而且在 FreeRTOS中 PendSV 和 SysTick 的中断优先级都是最低的!都是15。
注意临界区代码一定要精简!因为进入临界区会关闭中断,这样会导致优先级低于 configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断得不到及时的响应!
函数 taskENTER_CRITICAL_FROM_ISR() taskEXIT_CRITICAL_FROM_ISR() 中断级别
临界段代码保护,是用在中断服务程序中的,而且这个中断的优先级一定要低于
configMAX_SYSCALL_INTERRUPT_PRIORITY !这样才能使用FREERTOS提供的API函数。

4、熟悉正点原子《FreeRTOS开发指南V1.1》“第五章 第六章”之FreeRTOS 任务管理

相对于操作系统来说,裸机主循环里的任务就相当于优先级都是一样的,都在同一个队列中,而且,也没有时间片轮转执行,所以需要排队等候,实时性差。

RTOS是个任务管理系统,终究是针对任务的,任务的优先级总是会低于中断的优先级,不管你任务的优先级有多高,只要中断来了,任务都得靠边站。

任务的数值越高,优先级越高;中断的数值越高,优先级越低。要注意区分。

了解下可重入的概念:可重入函数详解-CSDN博客

重入:同一个函数被不同执行流调用,当前一个执行流还没执行完,就被其他执行流再次进入,我们称之为重入,一个函数在重入的情况下,运行结果不会出现任何不同或任何问题,则该函数被称为可重入函数,否则为不可重入函数。

多线程的情况下,几乎一定会出现这种情况,所以需要仔细考虑下可重入的问题。

任务状态

任务创建后即进入就绪态;

挂起态恢复后进入就绪态;

阻塞态满足条件后进入就绪态;

也就是说,任务如果想要进入运行态,必须先进入就绪态。

就绪态无法直接进入阻塞态。

挂起态、就绪态、阻塞态各自有一个任务列表。

任务优先级数字越低表示任务的优先级越低,0 的优先级最低,configMAX_PRIORITIES-1 的优先级最高。空闲任务的优先级最低,为 0。

中断只有条件触发才会执行一次;有高优先级任务执行的情况下,低优先级任务得不到执行,所以,肯定会有条件不满足让高优先级任务进入阻塞态,这时,低优先级任务才能得到执行。或者手动让高优先级任务挂起。

动态任务创建

使用函数 xTaskCreate() 来动态创建任务。
一般,任务名称字符串和调用的任务名保持一致即可。
另外就是,任务函数的参数为NULL即可。
任务句柄其实就是任务的堆栈首地址,这个参数就是用来存放任务句柄的。其他API操作该任务时,其实就是操作的任务句柄。
要创建的任务,要放入死循环中。
注意:不能从任务函数中返回或者退出。如果一定要从任务函数中退出的话那一定要调用函数vTaskDelete(NULL)来删除此任务。
常规使用示例如下:
这里有个问题需要解决,那就是,任务调度是只会调度死循环里的部分,还是会调度整个函数???????????????????也就是说,死循环之外的部分会被反复执行吗???????????????????

每个任务都有自己的堆栈,用于保存和恢复上下文环境。

关于堆栈大小

删除任务时,如果传入的是NULL,那么就会默认删除当前正在运行的那个任务。

一般用于当前任务删除自身。

句柄,一般就是访问某个目标的标识符,在不同的场景中具体含义不一样,有的是一个整数,有的是一个对象,有的是一个指针……总之,其抽象含义是一致的,都可以看做是某个对象或者某种行为的指代,类似于名称。可参考如下说法:

句柄是什么?图像句柄,函数句柄,句柄的概念

了解正点原子《FreeRTOS开发指南V1.1》“第七章 FreeRTOS 列表和列表项”

列表是 FreeRTOS 中的一个数据结构,概念上和双向链表有点类似。

FREERTOS有几种列表,就绪列表、阻塞列表、挂起列表。

列表有其管理的结构体,还有结点(列表项)的结构体,结点(列表项)的结构体中就有成员指明该结点当前属于哪个列表。

就绪列表是个列表数组:从纵向看,是不同优先级任务之间的抢占式调度;从横向看,是同一优先级任务之间的时间片轮转调度。

5、熟悉正点原子《FreeRTOS开发指南V1.1》“第十一章 FreeRTOS 其他任务 API 函数”

这些函数一般用来调试使用,具体查看手册即可。

几个重点函数记录:

uxTaskPriorityGet() 查询某个任务的优先级。
uxTaskGetStackHighWaterMark() 获取任务的堆栈的历史剩余最小值,FreeRTOS 中叫做“高
水位线”,此函数可用于调整堆栈大小,防止过大或溢出风险。
uxTaskGetNumberOfTasks() 获取当前系统中存在的任务数量。
vTaskGetRunTimeStats() 获取每个任务的运行时间
如果IDLE任务占比很大,就说明CPU大部分时间都是处于空闲状态,比如
vTaskList() 以一种表格的形式输出当前系统中所有任务的详细信息。

6、熟悉正点原子《FreeRTOS开发指南V1.1》“第十二章 FreeRTOS 时间管理”之延时函数

在使用 FreeRTOS 的过程中我们通常会在一个任务函数中使用延时函数对这个任务延时, 当执行延时函数的时候就会进行任务切换并且此任务就会进入阻塞态,直到延时完成任务重新进入就绪态。
FreeRTOS 中延时函数有相对模式和绝对模式,不过在 FreeRTOS 中不同的模式用的函数不同,其中函数 vTaskDelay() 是相对模式 ( 相对延时函数 ) , 函数vTaskDelayUntil() 是绝对模式 ( 绝对延时函数 )
要使用此函数的话 INCLUDE_vTaskDelay 必须为 1
相对延时就是调用这个函数时直到结束,就是延时那么久;绝对延时就是延时函数加上之前的代码执行时间,总的时间是那么久。
我们常用的是相对延时函数 vTaskDelay(),传入要延时的时间数,单位毫秒(ms)
延时时间由参数 xTicksToDelay 来确定,为要延时的时间节拍数,延时时间肯定要大于0 。否则的话相当于直接调用函数 portYIELD() 进行任务切换。

7、熟悉正点原子《FreeRTOS开发指南V1.1》“第十三章 FreeRTOS 队列”

注意区分队列和上面说的列表。

队列说的就FIFO队列。

队列中只能存储数据类型相同的值。

由于队列用来传递消息的,所以也称为消息队列。
全局变量有什么问题呢?
因为全局变量底层实际是要进行读改写的操作的,在多任务的场景下,全局变量可能会在一个任务中还没完成操作,就被下一个任务打断,这样,就会导致某些程序获取到的数据是不对的。
而队列在实现时,加入了临界区保护

消息队列跟裸机中的缓冲数组类似,属于一种循环队列。

消息队列有哪些应用场景呢?

比如

初学者会创建队列、向队列发送数据、从队列接收数据即可。

8、熟悉正点原子《FreeRTOS开发指南V1.1》“第十四章 FreeRTOS 信号量”

二值信号量的使命就是任务同步,完成任务与任务或中断与任务之间的同步。大多数情况下都是中断与任务之间的同步。类似于裸机中的标志位。
二值信号量在释放信号量之后就是满状态,接收信号量之后就是空状态。

9、熟悉正点原子《FreeRTOS开发指南V1.1》“第十六章 FreeRTOS 事件标志组”

使用信号量来同步的话任务只能与单个的事件或任务进行同步。有时候某个任务可能会需要与多个事件或任务进行同步,此时信号量就无能为力了。FreeRTOS 为此提供了一个可选的解决方法,那就是事件标志组。其实就类似于裸机中的位标志操作。

 三个重要的中断

在 FreeRTOS 的移植过程中会这遇到三个重要的中断,分别是 FreeRTOS 系统时基定时器的中断(SysTick 中断)、SVC 中断、PendSV 中断。

SysTick 中断是用来提供系统时基的;

PendSV被用来进行上下文切换。

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

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

相关文章

【Java 进阶篇】HTML介绍与软件架构相关知识详解

HTML&#xff08;Hypertext Markup Language&#xff09;是一种用于创建网页的标记语言。它是互联网上信息传递和展示的基础&#xff0c;无论是在浏览器中查看网页还是在移动设备上浏览应用程序&#xff0c;HTML都扮演着关键角色。本文将向您介绍HTML的基础知识&#xff0c;并探…

踩大坑ssh免密登录详细讲解

目 录 问题背景 环境说明 免密登录流程说明 1.首先要在对应的用户主机名的情况下生成密钥对&#xff0c;在A服务器执行 2.将A服务器d公钥拷贝到B服务器对应的位置 3.在A服务器访问B服务器 免密登录流程 0.用户说明 1.目前现状演示 2.删除B服务器.ssh 文件夹下面的…

多普勒频率相关内容介绍

图1 多普勒效应 1、径向速度 径向速度是作用于雷达或远离雷达的速度的一部分。 图2 不同的速度 2、喷气发动机调制 JEM是涡轮机的压缩机叶片的旋转的多普勒频率。 3、多普勒困境 最大无模糊范围需要尽可能低的PRF&#xff1b; 最大无模糊速度需要尽可能高的PRF&#xff1b…

什么是TF-A项目的长期支持?

安全之安全(security)博客目录导读 问题&#xff1a;Trusted Firmware-A社区每六个月发布一次代码。然而&#xff0c;对于生产中的平台&#xff0c;该策略在维护、重要软件修复的向后兼容性、获得最新的安全缓解措施和整体产品生命周期管理方面不具备可扩展性。 开源软件项目&…

假期题目整合

1. 下载解压题目查看即可 典型的猪圈密码只需要照着输入字符解开即可得到答案 2. 冷门类型的密码题型&#xff0c;需要特意去找相应的解题思路&#xff0c;直接百度搜索天干地支解密即可 3. 一眼能出思路他已经给了篱笆墙的提示提示你是栅栏密码对应解密即可 4. 最简单的社会主…

【17】c++设计模式——>原型模式

原型模式的定义 c中的原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;其目的是通过复制&#xff08;克隆&#xff09;已有对象来创建新的对象&#xff0c;而不需要显示的使用构造函数创建对象&#xff0c;原型模式适用于创建复杂对象时&a…

Linux软硬链接和动静态库

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 软硬链接和动静态库 前言正文软硬链接原理使用 文件时间动静态库库介绍静态库静态库制作静态库的使用关于静态链接 动态库动态库制作动态库的使用关于动态链接 补充 最…

React18学习

17、React_JSX的注意事项 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>JSX的注意</title><script src="./script/react.development.js"></script><script src=&…

秋招还没Offer怎么办?

作者 | 磊哥 来源 | Java中文社群 作者微信 | GG_Stone 如果你是双非院线、没有实习经历、没有出众的技术&#xff08;算法没刷一千道&#xff0c;也没做过 Spring Cloud 项目&#xff09;、现在还没有面试&#xff08;或只有少量的面试&#xff09;、并且目前还没有 Offer&…

1392. 最长快乐前缀

链接&#xff1a; 1392. 最长快乐前缀 题解&#xff1a; class Solution { public:string longestPrefix(string s) {if (s.size() < 0) {return "";}int MOD 1e9 7;// 构建26的n次方&#xff0c;预处理std::vector<long> pow26(s.size());pow26[0] 1…

频次直方图、KDE和密度图

Seaborn的主要思想是用高级命令为统计数据探索和统计模型拟合创建各种图形&#xff0c;下面将介绍一些Seaborn中的数据集和图形类型。 虽然所有这些图形都可以用Matplotlib命令实现&#xff08;其实Matplotlib就是Seaborn的底层&#xff09;&#xff0c;但是用 Seaborn API会更…

网页版”高德地图“如何设置默认城市?

问题&#xff1a; 每次打开网页版高德地图时默认定位的都是“北京”&#xff0c;想设置起始点为目前本人所在城市&#xff0c;烦恼的是高德地图默认的初始位置是北京。 解决&#xff1a; 目前网页版高德地图暂不支持设置起始点&#xff0c;打开默认都是北京&#xff0c;只能将…

Redisson—分布式服务

一、 分布式远程服务&#xff08;Remote Service&#xff09; 基于Redis的Java分布式远程服务&#xff0c;可以用来通过共享接口执行存在于另一个Redisson实例里的对象方法。换句话说就是通过Redis实现了Java的远程过程调用&#xff08;RPC&#xff09;。分布式远程服务基于可…

【小沐学Python】Python实现Web图表功能(Dash)

文章目录 1、简介2、安装3、功能示例3.1 Hello World3.2 连接到数据3.3 可视化数据3.4 控件和回调3.5 设置应用的样式3.5.1 HTML and CSS3.5.2 Dash Design Kit (DDK)3.5.3 Dash Bootstrap Components3.5.4 Dash Mantine Components 4、更多示例4.1 Basic Dashboard4.2 Using C…

计算机毕业设计 基于SSM的支教志愿者招聘系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

哪个版本的FL Studio更适合我,到底应该入手哪一款FL Studio?

很多打算入手正版FL Studio的新手朋友都会纠结一个问题&#xff1a; 哪个版本的FL Studio更适合我&#xff0c;到底应该入手哪一款FL Studio&#xff1f; 本文会介绍每个版本之间的差异点&#xff0c;并带大家选择适合自己的FL Sudio版本。 FL Studio Win-安装包&#xff1a;…

【Pinia】小菠萝详细使用说明

文章目录 1. 介绍1.1 Pinia介绍1.2 pinia的属性说明 2. 安装3. 初步使用4. store具体使用4.1 值修改4.2.1 直接修改4.2.2 通过$patch整体修改4.2.3 通过$patch函数式4.2.4 通过$state整体修改4.2.5 通过actions修改 4.2 解构store 5 actions使用6. getters使用6.1 通过this获取…

【ARM】(1)架构简介

前言 ARM既可以认为是一个公司的名字&#xff0c;也可以认为是对一类微处理器的通称&#xff0c;还可以认为是一种技术的名字。 ARM公司是专门从事基于RISC技术芯片设计开发的公司&#xff0c;作为知识产权&#xff08;IP&#xff09;供应商&#xff0c;本身不直接从事芯片生产…

加锁常见的问题

锁其是用来控制在某些场景下让代码串行的工具。我们为了充分利用计算机的硬件性能&#xff0c;发明了多线程&#xff0c;多线程有好处&#xff0c;但同时也有它复杂的一面&#xff0c;必须控制好多个线程的执行&#xff0c;才能驯服这个有能力也有脾气的烈马。 一、加锁范围误区…

Java基于SSM+Vue的平时成绩管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…