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

Clion开发STM32——移植FreeModbus

STM32型号 :STM32H743VIT6
FreeModbus版本 :1.6
使用工具:stm32cubeMX,Clion
使用STM32作从机,模式:RTU

网上用keil的比较多,用Clion的比较少,如果你也用Clion,那么希望本文可以给你提供些许参考。

1 下载官网源码

官网地址:https://www.embedded-experts.at/en/freemodbus/about/
demo是移植例程,但是里面没有stm32的。
modbus是源码.
在这里插入图片描述
看一下modbus文件,我这里使用的模式是RTU模式,所以ascii和tcp文件夹就不需要了,如果你也只用RTU模式,那么只需要标红的文件夹。
在这里插入图片描述
在freemodbus-v1.6\demo\BARE\port这个文件夹中的文件全部需要,这些是接口文件。
在这里插入图片描述

把上面的文件放在一个文件夹里。

在自己的工程目录下新建FreeModbus(自己起名就好),并添加上面的文件,如下:在这里插入图片描述

在这里插入图片描述

2 修改CMakeLists_template

可以参考这篇文章Clion开发STM32——添加自己文件

增加头文件路径
在这里插入图片描述
增加编译文件
在这里插入图片描述
只关注蓝色框框起来的即可,其他文件可以忽略,那是我这个工程的其他文件。

3 cubeMX配置串口和定时器

3.1串口

在这里插入图片描述

3.2 定时器

在这里插入图片描述

3.3 NVIC

中断回调函数比较繁琐,所以我这里取消掉了,自己写中断内的内容。
在这里插入图片描述

4 修改接口 port

4.1 port.h

首先是port.h文件

#ifndef _PORT_H
#define _PORT_H#include <assert.h>
#include <inttypes.h>/* ----------------------- Platform includes --------------------------------*/
#include "stm32h7xx_hal.h"
#include "main.h"/* ----------------------- Defines ---------*/#define	INLINE                      inline
#define PR_BEGIN_EXTERN_C           extern "C" {
#define	PR_END_EXTERN_C             }#define ENTER_CRITICAL_SECTION( )   __set_PRIMASK(1)//禁止中断
#define EXIT_CRITICAL_SECTION( )    __set_PRIMASK(0)//允许中断typedef uint8_t BOOL;typedef unsigned char UCHAR;
typedef char CHAR;typedef uint16_t USHORT;
typedef int16_t SHORT;typedef uint32_t ULONG;
typedef int32_t LONG;#ifndef TRUE
#define TRUE            1
#endif#ifndef FALSE
#define FALSE           0
#endif#endif

包含平台,定义进出临界区
在这里插入图片描述

4.2 portserial.c

这个文件是留给用户写串口函数接口的。
使能串口中断(串口接收中断,串口发送中断)
这里串口发送中断,可以选择两种
1 发送寄存器空中断 UART_IT_TXE
2 发送完成中断 UART_IT_TC

两种都可以 ,只是UART_IT_TC不会主动触发中断,必须得发送完成,发送完成是只数据被写入到发送寄存器,然后串口会把数据送到移位寄存器,等到移位寄存器发送完成,才会置发送完成中断。所以后面发送函数里,得收到加一个发送函数来触发,才能进中断。

而UART_IT_TXE使能后就可以进入中断,因为发送寄存器本就空的。往发送寄存器里写数据之后,数据也会被送到移位寄存器。

我这里使用的事发生寄存器空中断UART_IT_TXE。

#include "port.h"/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"/* ----------------------- static functions ---------------------------------*/void prvvUARTTxReadyISR( void );//被UART发送空中断调用的函数,注意是空中断,通知modbus数据可以发送void prvvUARTRxISR( void );//被UART接收中断调用的函数,通知modbus有数据到来/* ----------------------- Start implementation -----------------------------*/
/*使能串口中断*/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{/* If xRXEnable enable serial receive interrupts. If xTxENable enable* transmitter empty interrupts.*/if (xRxEnable) {/*设置485为接收模式*/__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);//使能接收中断} else {__HAL_UART_DISABLE_IT(&huart2, UART_IT_RXNE);}if (xTxEnable) {/*设置485为发送模式*/__HAL_UART_ENABLE_IT(&huart2, UART_IT_TXE);//使能发送寄存器为空中断} else {__HAL_UART_DISABLE_IT(&huart2, UART_IT_TXE);}
}
/*初始化串口*/
BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{/*MX_USART2_UART_Init*/return TRUE;
}
/*发送一个字节*/
BOOL
xMBPortSerialPutByte( CHAR ucByte )
{/* Put a byte in the UARTs transmit buffer. This function is called* by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been* called. */huart2.Instance->TDR = ucByte;//HAL_UART_Transmit(&huart2, (uint8_t*)&ucByte, 1, 0);return TRUE;
}
/*接收一个字节*/
BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{/* Return the byte in the UARTs receive buffer. This function is called* by the protocol stack after pxMBFrameCBByteReceived( ) has been called.*/*pucByte = (uint8_t)(huart2.Instance->RDR & (uint8_t)0x00FF);return TRUE;
}/* Create an interrupt handler for the transmit buffer empty interrupt* (or an equivalent) for your target processor. This function should then* call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that* a new character can be sent. The protocol stack will then call * xMBPortSerialPutByte( ) to send the character.*/void prvvUARTTxReadyISR( void )
{pxMBFrameCBTransmitterEmpty(  );
}/* Create an interrupt handler for the receive interrupt for your target* processor. This function should then call pxMBFrameCBByteReceived( ). The* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the* character.*/void prvvUARTRxISR( void )
{pxMBFrameCBByteReceived(  );
}

这两个函数需要取消static定义,这两个函数要在中断里被调用,而static就限制了它只能在本文件中使用,所以取消掉。(当然你把中断函数写在这个文件也可以,我个人习惯把中断都放在stm32h7xx_it.c文件中)
在这里插入图片描述

4.3 portimer.c

/* ----------------------- Platform includes --------------------------------*/
#include "port.h"/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"/* ----------------------- static functions ---------------------------------*/void prvvTIMERExpiredISR( void );//被定时器溢出中断调用的函数,通知modbus3.5个字符等待时间到/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{TIM_MasterConfigTypeDef sMasterConfig = {0};htim7.Instance = TIM7;htim7.Init.Prescaler = 11999;htim7.Init.CounterMode = TIM_COUNTERMODE_UP;htim7.Init.Period = usTim1Timerout50us - 1;htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim7) != HAL_OK){return FALSE;}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim7, &sMasterConfig) != HAL_OK){return FALSE;}return TRUE;
}/*使能定时器*/
inline void
vMBPortTimersEnable(  )
{__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);__HAL_TIM_SET_COUNTER(&htim7,0);HAL_TIM_Base_Start_IT(&htim7);/* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
}/*禁止定时器*/
inline void
vMBPortTimersDisable(  )
{HAL_TIM_Base_Stop_IT(&htim7);__HAL_TIM_SET_COUNTER(&htim7,0);__HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);/* Disable any pending timers. */
}/* Create an ISR which is called whenever the timer has expired. This function* must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that* the timer has expired.*/void prvvTIMERExpiredISR( void )
{( void )pxMBPortCBTimerExpired(  );
}

这个函数同样取消static,它被定时器溢出中断调用
在这里插入图片描述
关于定时器参数为什么要这么设置,可以看一下FreeModbus学习——eMBInit初始化

4.4 添加port.c文件

这个文件中存放的都是功能码处理函数调用的回调函数,当然你也可以放在别的文件,比如main.c里都可以。

这个文件中的函数怎么调用的,可以看一下FreeModbus学习——读输入寄存器eMBFuncReadInputRegister

/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"/* ----------------------- Defines ------------------------------------------*/
//输入寄存器
#define REG_INPUT_START  3000
#define REG_INPUT_NREGS  4//保持寄存器
#define REG_HOLD_START   4000
#define REG_HOLD_NREGS   10//线圈
#define REG_COILS_START  0
#define REG_COILS_NREGS  4//开关寄存器
#define REG_DISCRETE_START 1000
#define REG_DISCRETE_NREGS 4
/* ----------------------- Static variables ---------------------------------*/
static USHORT   usRegInputStart = REG_INPUT_START;
static USHORT   usRegInputBuf[REG_INPUT_NREGS] = {0x01, 0x02, 0x03, 0x04};static USHORT   usRegHoldStart = REG_HOLD_START;
static USHORT   usRegHoldBuf[REG_HOLD_NREGS];static USHORT   usRegCoilsStart = REG_COILS_START;
static uint8_t  usRegCoilsBuf[REG_COILS_NREGS];static USHORT   usRegDiscreteStart = REG_DISCRETE_START;
static uint8_t  usRegDiscreteBuf[REG_DISCRETE_NREGS];
/****************************************************************************
* 名	  称:eMBRegInputCB
* 功    能:读取输入寄存器,对应功能码是 04 eMBFuncReadInputRegister
* 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
*						usAddress: 寄存器地址
*						usNRegs: 要读取的寄存器个数
* 出口参数:
* 注	  意:上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
*								+StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
*								+LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
*								+CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
*							3 区
****************************************************************************/
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{eMBErrorCode    eStatus = MB_ENOERR;int             iRegIndex;//寄存器数组索引usAddress = usAddress - 1;//传进来的地址+1了,这里要减1//判断地址是否在输入寄存器范围内if( ( usAddress >= REG_INPUT_START ) && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ){iRegIndex = ( int )( usAddress - usRegInputStart );//地址 - 开始地址  =  索引while( usNRegs > 0 ){*pucRegBuffer++ = ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );//寄存器值高位*pucRegBuffer++ = ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );//寄存器值低位iRegIndex++;usNRegs--;}}else{eStatus = MB_ENOREG;}return eStatus;
}
/****************************************************************************
* 名	  称:eMBRegHoldingCB
* 功    能:对应功能码有:06 写保持寄存器 eMBFuncWriteHoldingRegister
*													16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister
*													03 读保持寄存器 eMBFuncReadHoldingRegister
*													23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
* 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
*						usAddress: 寄存器地址
*						usNRegs: 要读写的寄存器个数
*						eMode: 功能码
* 出口参数:
* 注	  意:4 区
****************************************************************************/
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{eMBErrorCode    eStatus = MB_ENOERR;int             iRegIndex;usAddress = usAddress - 1;if((usAddress >= REG_HOLD_START) && ((usAddress+usNRegs) <= (REG_HOLD_START + REG_HOLD_NREGS))){iRegIndex = (int)(usAddress - usRegHoldStart);switch(eMode){case MB_REG_READ://读寄存器while(usNRegs > 0){*pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] >> 8);*pucRegBuffer++ = (uint8_t)(usRegHoldBuf[iRegIndex] & 0xFF);iRegIndex++;usNRegs--;}break;case MB_REG_WRITE://写寄存器while(usNRegs > 0){usRegHoldBuf[iRegIndex] = *pucRegBuffer++ << 8;usRegHoldBuf[iRegIndex] |= *pucRegBuffer++;iRegIndex++;usNRegs--;}}}else//错误{eStatus = MB_ENOREG;}return eStatus;
}/****************************************************************************
* 名	  称:eMBRegCoilsCB
* 功    能:对应功能码有:01 读线圈 eMBFuncReadCoils
*													05 写线圈 eMBFuncWriteCoil
*													15 写多个线圈 eMBFuncWriteMultipleCoils
* 入口参数:pucRegBuffer: 数据缓存区,用于响应主机
*						usAddress: 线圈地址
*						usNCoils: 要读写的线圈个数
*						eMode: 功能码
* 出口参数:
* 注	  意:如继电器
*						0 区
****************************************************************************/
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{eMBErrorCode    eStatus = MB_ENOERR;USHORT          iRegIndex;USHORT usCoilGroups = ((usNCoils - 1) / 8 + 1);UCHAR  ucStatus     = 0;UCHAR  ucBits       = 0;UCHAR  ucDisp       = 0;usAddress = usAddress - 1;if((usAddress >= REG_COILS_START) &&	((usAddress + usNCoils) <= (REG_COILS_START + REG_COILS_NREGS))){iRegIndex = (int)(usAddress - usRegCoilsStart);switch(eMode){case MB_REG_READ://读线圈while(usCoilGroups--){ucDisp = 0;ucBits = 8;while((usNCoils--) != 0 && (ucBits--) != 0){ucStatus |= (usRegCoilsBuf[iRegIndex++] << (ucDisp++));}*pucRegBuffer++ = ucStatus;}break;case MB_REG_WRITE://写线圈while(usCoilGroups--){ucStatus = *pucRegBuffer++;ucBits   = 8;while((usNCoils--) != 0 && (ucBits--) != 0){usRegCoilsBuf[iRegIndex++] = ucStatus & 0X01;ucStatus >>= 1;}}}}else//错误{eStatus = MB_ENOREG;}return eStatus;
}
/****************************************************************************
* 名	  称:eMBRegDiscreteCB 
* 功    能:读取离散寄存器,对应功能码有:02 读离散寄存器 eMBFuncReadDiscreteInputs
* 入口参数:pucRegBuffer: 数据缓存区,用于响应主机   
*						usAddress: 寄存器地址
*						usNDiscrete: 要读取的寄存器个数
* 出口参数:
* 注	  意:1 区
****************************************************************************/
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{eMBErrorCode    eStatus = MB_ENOERR;USHORT          iRegIndex;USHORT usDiscreteGroups = ((usNDiscrete - 1) / 8 + 1);UCHAR  ucStatus     = 0;UCHAR  ucBits       = 0;UCHAR  ucDisp       = 0;usAddress = usAddress - 1;if((usAddress >= REG_DISCRETE_START) &&	((usAddress + usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_NREGS))){iRegIndex = (int)(usAddress - usRegDiscreteStart);while(usDiscreteGroups--){ucDisp = 0;ucBits = 8;while((usNDiscrete--) != 0 && (ucBits--) != 0){if(usRegDiscreteBuf[iRegIndex]){ucStatus |= (1 << ucDisp);}ucDisp++;}*pucRegBuffer++ = ucStatus;}}else//错误{eStatus = MB_ENOREG;}return eStatus;
}

4.5 写中断服务函数

void USART2_IRQHandler(void)
{/* USER CODE BEGIN USART2_IRQn 0 */if((__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESET)&& (__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_RXNE)!= RESET)) {__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_RXNE);prvvUARTRxISR();return;}if ((__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_TXE)!= RESET)&& (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE)!= RESET)){__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_TXE);prvvUARTTxReadyISR();return;}}void TIM7_IRQHandler(void)
{/* USER CODE BEGIN TIM7_IRQn 0 */if(__HAL_TIM_GET_FLAG(&htim7, TIM_FLAG_UPDATE) != RESET&& __HAL_TIM_GET_IT_SOURCE(&htim7, TIM_IT_UPDATE) !=RESET) {__HAL_TIM_CLEAR_FLAG(&htim7, TIM_FLAG_UPDATE);prvvTIMERExpiredISR();}}

5 调用协议栈

依次调用
eMBInit( MB_RTU, 1, 3, 9600, MB_PAR_NONE );
eMBEnable();

然后把eMBPoll();放在循环里
在这里插入图片描述

6 测试

以读输入寄存器为例
功能码04

使用软件Modbus Poll
在这里插入图片描述
软件配置:
在这里插入图片描述
效果:
在这里插入图片描述
OK !
移植结束。
想深入了解FreeModbus源码,可以看我写的其笔记FreeModbus,写的不好,对源码理解上以及写的时候,难免有瑕疵纰漏,如有错误还请大佬指出。您原谅着瞧,原谅着看。

相关文章:

Clion开发STM32——移植FreeModbus

STM32型号 &#xff1a;STM32H743VIT6 FreeModbus版本 &#xff1a;1.6 使用工具&#xff1a;stm32cubeMX&#xff0c;Clion 使用STM32作从机&#xff0c;模式&#xff1a;RTU 网上用keil的比较多&#xff0c;用Clion的比较少&#xff0c;如果你也用Clion&#xff0c;那么希望…...

c++栈笔记

一种常见的数据结构&#xff0c;遵循后进先出&#xff0c;先进后出的原则。地址不连续&#xff0c;栈顶&#xff08;top&#xff09; 1.常见函数 stack<int> s;定义一个参数类型为int 的栈 名为ss.push()向栈中插入元素s.emplace()压栈&#xff0c;无返回值s.pop()删除…...

Oracle配置TCPS加密协议测试

文章目录 一、环境信息二、配置过程1.创建证书2.监听配置2.1.配置sqlnet.ora2.2.配置listener.ora文件2.3.配置tnsnames.ora文件2.4.重载监听 3.数据库本地测试3.1. tcps登录测试3.2.日志监控 一、环境信息 操作系统&#xff1a;Linux 版本信息&#xff1a;Oracle 19c 参考文档…...

Jetpack Compose 通过 OkHttp 发送 HTTP 请求的示例

下面是一个使用 Kotlin 和 Jetpack Compose 来演示通过 OkHttp 发送 HTTP 请求的示例。这个示例包括在 Jetpack Compose 中发送一个 GET 请求和一个 POST 请求&#xff0c;并显示结果。 添加okhttp依赖 首先&#xff0c;在你的 build.gradle.kts 文件中添加必要的依赖&#xf…...

Pytorch使用教学3-特殊张量的创建与类型转化

1 特殊张量的创建 与numpy类似&#xff0c;PyTorch中的张量也有很多特殊创建的形式。 zeros:全0张量 # 形状为2行3列 torch.zeros([2, 3]) # tensor([[0., 0., 0.], # [0., 0., 0.]])ones:全1张量 # 形状为2行3列 torch.ones([2, 3]) # tensor([[1., 1., 1.], # …...

【日记】办个护照不至于有这种刑事罪犯一样的待遇吧……(737 字)

正文 暴晒&#xff0c;中午出去骑共享单车&#xff0c;座垫都不敢坐。 至于为什么&#xff0c;中午觉都不睡跑出去&#xff0c;是因为今天他们办承兑汇票的业务&#xff0c;搞了一天&#xff0c;中午不休息&#xff0c;说可能还会用到我的指纹&#xff0c;让我 on call。我心想…...

【矩阵微分】在不涉及张量的前提下计算矩阵对向量的导数并写出二阶泰勒展开

本篇内容摘自CMU 16-745最优控制的第10讲 “Nonlinear Trajectory Optimization”。 如何在不涉及张量运算的前提下&#xff0c;计算矩阵对向量的导数并写出二阶泰勒展开 在多维微积分中&#xff0c;计算矩阵对向量的导数和二阶泰勒展开是一项重要的任务。本文将介绍如何在不涉…...

数据结构之判断平衡二叉树详解与示例(C,C++)

文章目录 AVL树定义节点定义计算高度获取平衡因子判断是否为平衡二叉树完整示例代码结论 在计算机科学中&#xff0c;二叉树是一种非常重要的数据结构。它们被广泛用于多种算法中&#xff0c;如排序、查找等。然而&#xff0c;普通的二叉树在极端情况下可能退化成链表&#xff…...

深入解析仓颉编程语言:函数式编程的核心特性

摘要 仓颉编程语言以其独特的语法和功能&#xff0c;为开发者提供了强大的编程工具。本文将深入探讨仓颉语言中的嵌套函数、Lambda 表达式和闭包等函数式编程的核心特性&#xff0c;帮助开发者更好地理解和利用这些工具。 引言 在现代编程语言中&#xff0c;函数式编程范式越…...

springboot惠农服务平台-计算机毕业设计源码50601

目录 1 绪论 1.1 研究背景 1.2研究意义 1.3论文结构与章节安排 2 惠农服务平台app 系统分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 惠农服务平台app 总体设计 3.1 系统功能模块设计 3.2 数据库设计 表access_token (…...

Lua脚本简单理解

目录 1.安装 2.语法 2.1Lua数据类型 2.2变量 2.3lua循环 2.4流程控制 2.5函数 2.6运算符 2.7关系运算符 3.lua脚本在redis中的使用 3.1lua脚本再redis简单编写 3.2普通锁Lua脚本 3.3可重入锁lua脚本 1.安装 centos安装 安装指令&#xff1a; yum -y update yum i…...

AutoSAR自适应平台架构总览--AP的初认识

AutoSAR自适应平台架构总览:AP 基础设施层&#xff08;Foundation Layer&#xff09;核心操作系统&#xff08;Core OS&#xff09;通信管理&#xff08;Communication Management&#xff09; 服务层&#xff08;Services Layer&#xff09;诊断服务&#xff08;Diagnostics S…...

GPT-4o Mini:探索最具成本效益的小模型在软件开发中的应用

随着人工智能技术的迅猛发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域也取得了显著的进步。OpenAI 最新发布的 GPT-4o Mini 模型&#xff0c;以其卓越的性能和极具竞争力的价格&#xff0c;成为了广大开发者关注的焦点。作为一名长期关注人工智能及其在软件开发…...

{Spring Boot 原理篇} Spring Boot自动装配原理

SpringBootApplication 1&#xff0c;Spring Boot 应用启动&#xff0c;SpringBootApplication标注的类就是启动类&#xff0c;它去实现配置类中的Bean的自动装配 SpringBootApplication public class SpringbootRedis01Application {public static void main(String[] args)…...

QEMU源码全解析 —— CPU虚拟化(10)

接前一篇文章: 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 《深度探索Linux系统虚拟化原理与实现》—— 王柏生 谢广军, 机械工业出版社 特此致谢! 二、x86架构CPU虚拟化 3. VMX 上一回讲解了支…...

46、PHP实现矩阵中的路径

题目&#xff1a; PHP实现矩阵中的路径 描述&#xff1a; 请设计一个函数&#xff0c;用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。 路径可以从矩阵中的任意一个格子开始&#xff0c;每一步可以在矩阵中向左&#xff0c;向右&#xff0c;向上&#xff0c;向…...

c++笔记2

目录 2.2 栈底&#xff08;bottom&#xff09; } 大数乘大数 节点&#xff1a;包含一个数据元素及若干指向子树分支的信息 。 节点的度&#xff1a;一个节点拥有子树的数目称为节点的度 。 叶子节点&#xff1a;也称为终端节点&#xff0c;没有子树的节点或者度为零的节点…...

通过Lua脚本手写redis分布式锁

1、手写 Redis 分布式锁&#xff0c;包括上锁、解锁、自动续期。 此功能实现采用 Lua脚本实现&#xff0c;Lua脚本可以保证原子性。 setnx可以实现分布式锁&#xff0c;但是无法实现可重入锁&#xff0c;所以用hset来代替setnx实现可重入的分布式锁。 -- lock if redis.call…...

解析银行个人征信系统

银行个人征信系统&#xff0c;也被称为个人信用信息基础数据库或金融信用信息基础数据库&#xff0c;是我国社会信用体系的重要基础设施。该系统由中国人民银行组织国内相关金融机构建立&#xff0c;旨在依法采集、整理、保存、加工自然人&#xff08;法人&#xff09;及其他组…...

AttributeError: ‘list‘ object has no attribute ‘text‘

AttributeError: ‘list‘ object has no attribute ‘text‘ 目录 AttributeError: ‘list‘ object has no attribute ‘text‘ 【常见模块错误】 【解决方案】 示例代码 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英…...

Codeforces Round 874 (Div. 3)(A~D题)

A. Musical Puzzle 思路: 用最少的长度为2的字符串按一定规则拼出s。规则是&#xff1a;前一个字符串的尾与后一个字符串的首相同。统计s中长度为2的不同字符串数量。 代码: #include<bits/stdc.h> #include <unordered_map> using namespace std; #define N 20…...

[Python][基础语法]详细讲解

目录 1.顺序语句2.条件语句3.缩进和代码块4.空语句 pass5.循环语句1.while2.for3.continue4.break ∞.积累 1.顺序语句 默认情况下&#xff0c;Python的代码执行顺序是按照从上到下的顺序&#xff0c;依次执行# 输出结果&#xff1a;"123" print("1") pri…...

Layui---输入事件

输入实时监听 //监听表单单选框复选框选择 form.on(radio, function (data) {console.log(data.value); //得到被选中的值 });//监听表单下拉菜单选择form.on(select, function (data) //监听表单下拉菜单选择form.on(select, function (data) ​ //监听表单复选框选择form.…...

甄选范文“论软件测试中缺陷管理及其应用”软考高级论文,系统架构设计师论文

论文真题 软件缺陷指的是计算机软件或程序中存在的某种破坏正常运行能力的问题、错误,或者隐藏的功能缺陷。缺陷的存在会导致软件产品在某种程度上不能满足用户的需要。在目前的软件开发过程中,缺陷是不可避免的。软件测试是发现缺陷的主要手段,其核心目标就是尽可能多地找…...

spring框架实现滑动验证码功能

spring框架实现滑动验证码功能 1. 整体描述2. 具体实现2.1 滑动验证码实体类2.2 滑动验证码登录VO2.3 滑动验证码接口返回类2.4 滑动验证码工具类2.5 滑动验证码Service2.6 滑动验证码Controller 3 工程源码4 总结 1. 整体描述 之前项目需要在验证码模块&#xff0c;增加滑动验…...

Pytorch使用教学8-张量的科学运算

在介绍完PyTorch中的广播运算后&#xff0c;继续为大家介绍PyTorch的内置数学运算&#xff1a; 首先对内置函数有一个功能印象&#xff0c;知道它的存在&#xff0c;使用时再查具体怎么用其次&#xff0c;我还会介绍PyTorch科学运算的注意事项与一些实用小技巧 1 基本数学运算…...

[Spring Boot]登录密码三种加密方式

简述 介绍其三种密码加密方法 1.SM2加密与验签 2.随机密码盐加密 3.MD5加密 推荐使用方法1&#xff0c;其次使用方法2&#xff0c;最不推荐的是方法3。方法3极其容易被密码字典破解&#xff0c;如果项目进行安全测试&#xff0c;通常是不允许的加密方式。 SM2加密与验签 引入…...

前端面试项目细节重难点分享(十三)

面试题提问&#xff1a;分享你最近做的这个项目&#xff0c;并讲讲该项目的重难点&#xff1f; 答&#xff1a;最近这个项目是一个二次迭代开发项目&#xff0c;迭代周期一年&#xff0c;在做这些任务需求时&#xff0c;确实有很多值得分享的印象深刻的点&#xff0c;我讲讲下面…...

每天五分钟深度学习:向量化方式完成逻辑回归m个样本的前向传播

本文重点 我们已经知道了向量化可以明显的加速程序的运行速度,本节课程将使用向量化来完成逻辑回归的前向传播,不使用一个for循环。 逻辑回归的前向传播 我们先来回忆一下逻辑回归的前向传播,如果我们有m个训练样本,首先对第一个样本进行预测,我们需要计算z,然后计算预…...

以线程完成并发的UDP服务端

网络(九)并发的UDP服务端 以线程完成功能 客户端 // todo UDP发送端 #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <stdlib.h> #include <string.h…...

linux c 特殊字符分割

/* * brief: 根据split_symbol分割字符串 * param: str为要分割的字符串&#xff0c;split_symbol是分隔符 * return&#xff1a;返回garray的指针数组&#xff0c;如果返回非空需要自己处理释放 */ GPtrArray_autoptr char_sz_spilt(pchar* str, pchar split_symbol) {if (NUL…...

搭建本地私有知识问答系统:MaxKB + Ollama + Llama3 (wsl网络代理配置、MaxKB-API访问配置)

目录 搭建本地私有知识问答系统:MaxKB、Ollama 和 Llama3 实现指南引言MaxKB+Ollama+Llama 3 Start buildingMaxKB 简介:1.1、docker部署 MaxKB(方法一)1.1.1、启用wls或是开启Hyper使用 WSL 2 的优势1.1.2、安装docker1.1.3、docker部署 MaxKB (Max Knowledge Base)MaxKB …...

谷粒商城实战笔记-65-商品服务-API-品牌管理-表单校验自定义校验器

文章目录 1&#xff0c;el-form品牌logo图片自定义显示2&#xff0c;重新导入和注册element-ui组件3&#xff0c;修改brand-add-or-update.vue控件的表单校验规则firstLetter 校验规则sort 校验规则 1&#xff0c;el-form品牌logo图片自定义显示 为了在品牌列表中自定义显示品…...

学好C++之——命名空间

c开始学习之时&#xff0c;你不可避免会遇到一个新朋友&#xff0c;那就是——namespace&#xff08;命名空间&#xff09;。 那么这篇文章就来为你解决这个小麻烦喽~ 目录 1.namespace存在的意义 2.namespace的定义 3.namespace的使用 1.namespace存在的意义 在C中&#…...

pytorch lightning报错all tensors to be on the same device

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! 修改指定为gpu trainer pl.Trainer(max_epochstrain_params.iterations, loggertb_logger,acceleratorgpu, devices1)...

Redis中的哨兵(Sentinel)

上篇文章我们讲述了Redis中的主从复制&#xff08;Redis分布式系统中的主从复制-CSDN博客&#xff09;&#xff0c;本篇文章针对主从复制中的问题引出Redis中的哨兵&#xff0c;希望本篇文章会对你有所帮助。 文章目录 一、引入哨兵机制 二、基本概念 三、主从复制的问题 四、哨…...

产业创新研究杂志产业创新研究杂志社产业创新研究编辑部2024年第12期目录

高质量发展 如何在新一轮产业链变革中平稳应对挑战 王宏利; 1-3《产业创新研究》投稿&#xff1a;cnqikantg126.com 基于ERGM的城市间绿色低碳技术专利转让网络结构及演化研究 吕彦朋;姜军;张宁; 4-6 数字基础设施建设对城市FDI的影响——基于“宽带中国”试点政策…...

网闸(Network Gatekeeper或Security Gateway)

本心、输入输出、结果 文章目录 网闸(Network Gatekeeper或Security Gateway)前言网闸主要功能网闸工作原理网闸使用场景网闸网闸(Network Gatekeeper或Security Gateway) 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 如果觉得本文对你有帮助…...

C#中的字符串

String 在实例方法中string虽然传入的是引用类型 但是修改string 并不是修改原来堆里面的值 而是又重新创建一个堆值 用来然后用方法内的变量指向新的堆值 C# 中的字符串&#xff08;string 类型&#xff09;提供了许多有用的方法来处理字符串数据。以下是一些常用的字符…...

docker安装部署elasticsearch7.15.2

docker安装部署elasticsearch7.15.2 1.拉取es镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.2如果不想下载或者镜像拉去太慢可以直接下载文章上面的镜像压缩包 使用镜像解压命令 docker load -i elasticsearch-7-15-2.tar如下图所示就表示镜像解压成…...

Symfony 入门指南:快速安装与基础配置

Symfony 入门指南&#xff1a;快速安装与基础配置 Symfony 是一个强大而灵活的 PHP 框架&#xff0c;广泛应用于构建现代 Web 应用程序。本指南将带您一步一步地了解如何快速安装 Symfony&#xff0c;并完成基本配置&#xff0c;以便您能够开始使用这个强大的框架。 目录 引…...

3.3V升压至5V的AH6922芯片:高效能的SOP8封装解决方案

# 3.3V升压至5V的AH6922芯片&#xff1a;高效能的SOP8封装解决方案 在当今快速发展的电子设备领域&#xff0c;对于电源管理的需求日益增长。特别是对于便携式产品和手持设备&#xff0c;一个高效、稳定且体积小巧的升压解决方案变得至关重要。本文将介绍一款专为这些需求设计…...

赋能未来教育,3DCAT助力深圳鹏程技师学院打造5G+XR实训室

随着国家对教育行业的重视&#xff0c;实训室建设已成为推动教育现代化的关键。《教育信息化2.0行动计划》、《职业教育示范性虚拟仿真实训基地建设指南》等政策文件&#xff0c;明确指出了加强虚拟仿真实训教学环境建设的重要性。 在这一大背景下&#xff0c;教育行业对于实训…...

力扣141环形链表问题|快慢指针算法详细推理,判断链表是否有环|龟兔赛跑算法

做题链接 目录 前言&#xff1a; 一、算法推导&#xff1a; 1.假设有环并且一定会相遇&#xff0c;那么一定是在环内相遇&#xff0c;且是快指针追上慢指针。 2.有环就一定会相遇吗&#xff1f;快指针是每次跳两步&#xff0c;有没有可能把慢指针跳过去&#xff1f; 3.那一定…...

React 常见的报错及解决方法

1、Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons&#xff08;无效的钩子调用。钩子只能在函数组件的内部调用。这可能是由于以下原因之一&#xff09; 原因&#x…...

更新服务器nginx 1.26.1版本

今天在官网下载了nginx1的1.26.1版本&#xff0c;使用gpt的脚本想直接覆盖安装&#xff0c;脚本如下 #!/bin/bash# 设置变量 NGINX_VERSION"1.26.1" TAR_FILE"nginx-$NGINX_VERSION.tar.gz" SRC_DIR"nginx-$NGINX_VERSION"# 检查是否存在tar包 …...

JAVA代码审计JAVA0基础学习(需要WEB基础知识)DAY2

JAVA 在 SQL执行当中 分为3种写法&#xff1a; JDBC注入分析 Mybatis注入分析 Hibernate注入分析 JDBC 模式不安全JAVA代码示例部分特征 定义了一个 sql 参数 直接让用户填入id的内容 一个最简单的SQL语句就被执行了 使用安全语句却并没有被执行 Mybatis&#xff1a; #…...

SpringBoot整合elasticsearch-java

一、依赖 系统使用的是ElasticSearch8.2.0 <dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.1.0</version> </dependency> 二、配置 1、yml文件配置 elastics…...

网络服务与应用

一、 文件传输 FTP 1、FTP采用典型的C/S架构&#xff08;即服务器端和客户端模型&#xff09;&#xff0c;客户端与服务器端建立TCP连接之后即可实现文件的上传、下载。 2、FTP传输过程 1&#xff09;、主动模式&#xff08;POST&#xff09;&#xff1a;入站连接 2&#x…...

Git项目如何配置,如何上传至GitHub

Git项目配置并上传至GitHub的详细步骤如下&#xff1a; 一、准备工作 创建GitHub账号&#xff1a; 访问GitHub官网&#xff0c;点击“Sign up”注册新账号。填写相关信息&#xff0c;包括用户名、邮箱和密码&#xff0c;完成账号创建。安装Git客户端&#xff1a; 访问Git官网…...