【嵌入式】HC32F07X CAN通讯配置和使用配置不同缓冲器以连续发送
一 背景说明
使用小华(华大)的MCU HC32F07X实现 CAN 通讯配置和使用
二 原理分析
【1】CAN原理说明(参考文章《CAN通信详解》):
CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现分布式实时控制的串行通信网络。
(i)CAN通信形式:CAN 使用称为 CANH / CANL 的通信线路执行传输和接收。电位差较小的电信号称为隐性信号,其逻辑值为1。电位差较大的电信号称为显性信号,其逻辑值0。如果通信总线上发生显性和隐性冲突,则显性优先。总线空闲时保持隐性。
(ii)CAN数据格式:CAN的数据定义了有5种帧类型:
(ii)CAN数据帧:数据帧一般由 7 个段构成,即:
(1) 帧起始。表示数据帧开始的段。
(2) 仲裁段。表示该帧优先级的段。
(3) 控制段。表示数据的字节数及保留位的段。
(4) 数据段。数据的内容,一帧可发送 0~8 个字节的数据。
(5) CRC 段。检查帧的传输错误的段。
(6) ACK 段。表示确认正常接收的段。
(7) 帧结束。表示数据帧结束的段
图中 D 表示显性电平, R 表示隐形电平。
更多具体内容不再赘述,可以参考上面的文章链接或者自行搜索。
【2】HC32F07X的CAN外设:
芯片CAN外设的主要特性:
■ 完全支持 CAN2.0A/CAN2.0B 协议。
■ 向上兼容 CAN-FD 协议。
■ 支持最高通信波特率 1Mbit/s
■ 支持 1~1/256 的波特率预分频, 灵活配置波特率。
■ 10 个接收缓冲器
- FIFO 方式
- 错误或者不被接收的数据不会覆盖存储的消息
■ 1 个高优先主发送缓冲器 PTB
■ 4 个副发送缓冲器 STB
- FIFO 方式
- 优先级仲裁方式
■ 8 组独立的筛选器
- 支持 11 位标准 ID 和 29 位扩展 ID
- 可编程 ID CODE 位以及 MASK 位
■ PTB/STB 均支持支持单次发送模式
■ 支持静默模式
■ 支持回环模式
■ 支持捕捉传输的错误种类以及定位仲裁失败位置
■ 可编程的错误警告值
■ 支持 ISO11898-4 规定时间触发 CAN 以及接收时间戳
系统框图如下:
更多详细的内容可以参考HC32F07X芯片的DATASHEET。
三 CAN通讯硬件设计
以下推荐了两个CAN收发的硬件电路,可以将外部的 CANH/CANL 差分信号,转换为 CAN_TX/CAN_RX 信号用以内部MCU处理。一个是官方提供的,一个是开发板提供的,都可以正常使用。
注意CAN通信需要5V,用以给收发器供电。
【1】推荐电路1:
参考官方的硬件设计指南《AN_HC32L072_HC32L073_HC32F072系列硬件开发指南_Rev1.1》,里面对于CAN通信收发的硬件电路有如下推荐电路,其中使用了NXP的 TJA1042 作为收发器:
【2】推荐电路2:
使用的周立功开发板中也引出了CAN功能,其中使用了NXP的TJA1051T作为收发器:
四 CAN通讯软件配置
选用引脚 PD00(CAN_RX)、PD01(CAN_TX)、PC12(CAN_STB)实现CAN通信功能,使用时钟频率为48MHz(官方例程使用的是外部8M晶振),CAN通讯波特率为1M,标准帧ID号为1。
【1】系统时钟配置:
static void App_SysClkInit(void)
{stc_sysctrl_clk_cfg_t stcCfg;stc_sysctrl_pll_cfg_t stcPLLCfg;Sysctrl_SetPeripheralGate(SysctrlPeripheralFlash, TRUE); ///< 使能FLASH模块的外设时钟Flash_WaitCycle(FlashWaitCycle1);Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz); ///< PLL使用RCH作为时钟源,因此需要先设置RCHstcPLLCfg.enInFreq = SysctrlPllInFreq4_6MHz; ///< RCH 4MHzstcPLLCfg.enOutFreq = SysctrlPllOutFreq36_48MHz; ///< PLL 输出48MHzstcPLLCfg.enPllClkSrc = SysctrlPllRch; ///< 输入时钟源选择RCHstcPLLCfg.enPllMul = SysctrlPllMul12; ///< 4MHz x 12 = 48MHzSysctrl_SetPLLFreq(&stcPLLCfg);///< 选择PLL作为HCLK时钟源;stcCfg.enClkSrc = SysctrlClkPLL;///< HCLK SYSCLK/2stcCfg.enHClkDiv = SysctrlHclkDiv1;///< PCLK 为HCLK/8stcCfg.enPClkDiv = SysctrlPclkDiv1;///< 系统时钟初始化Sysctrl_ClkInit(&stcCfg);
}
【2】CAN初始化GPIO:
//CAN通信引脚定义
#define CAN_RX_PORT (GpioPortD)
#define CAN_RX_PIN (GpioPin0)
#define CAN_TX_PORT (GpioPortD)
#define CAN_TX_PIN (GpioPin1)
#define CAN_STB_PORT (GpioPortC)
#define CAN_STB_PIN (GpioPin12)#define APB1_CLK 48000000 //CAN 的输入时钟
#define CAN_BAUD 1000000 //CAN 的波特率/**************************************************************************
* 函数名称: COM_Init
* 功能描述: CAN通信初始化GPIO
**************************************************************************/
void COM_Init(void)
{stc_gpio_cfg_t stcGpioCfg;Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);stcGpioCfg.enDir = GpioDirIn; ///< 端口方向配置->输入stcGpioCfg.enDrv = GpioDrvL; ///< 端口驱动能力配置->高驱动能力stcGpioCfg.enPu = GpioPuDisable; ///< 端口上下拉配置->无stcGpioCfg.enPd = GpioPdDisable;stcGpioCfg.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭stcGpioCfg.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHBGpio_Init(CAN_RX_PORT, CAN_RX_PIN, &stcGpioCfg);stcGpioCfg.enDir = GpioDirOut;Gpio_Init(CAN_TX_PORT, CAN_TX_PIN, &stcGpioCfg);Gpio_Init(CAN_STB_PORT, CAN_STB_PIN, &stcGpioCfg);///<CAN RX\TX复用功能配置Gpio_SetAfMode(CAN_RX_PORT, CAN_RX_PIN, GpioAf1);Gpio_SetAfMode(CAN_TX_PORT, CAN_TX_PIN, GpioAf1);///<STB 低-PHY有效Gpio_ClrIO(CAN_STB_PORT, CAN_STB_PIN);
}
【3】CAN波特率自适应配置接口:
/**************************************************************************
* 函数名称: COM_BaudCfg
* 功能描述: CAN通信波特率自动配置
* 其他说明: 48MHz主频,1M波特率计算得到:SJW=2, PRESC=1-1, SEG_2=15, SEG_1=30若输入500K波特率,PRESC为2-1; 输入250K波特率,PRESC为4-1
**************************************************************************/
void COM_BaudCfg(stc_can_init_config_t *p_stcCanInitCfg, uint32_t src_clk, uint32_t baud)
{uint32_t i,value = baud,record = 1;uint32_t remain = 0,sum_prescaler = 0;while(( baud == 0 )||( src_clk == 0 ));sum_prescaler = src_clk / baud;for ( i = 73; i > 3; i-- ) {remain = sum_prescaler - ((sum_prescaler / i)*i);if( remain == 0 ) {record = i;break;} else {if (remain < value) {value = remain;record = i;}}}/* 设置重新同步跳跃宽度为2个时间单位 */p_stcCanInitCfg->stcCanBt.SJW = 2;p_stcCanInitCfg->stcCanBt.PRESC = (sum_prescaler/record) - 1;p_stcCanInitCfg->stcCanBt.SEG_2 = (record - 3) / 3;p_stcCanInitCfg->stcCanBt.SEG_1 = (record - 3) - p_stcCanInitCfg->stcCanBt.SEG_2;
}
【注】:CAN波特率的计算和配置,也可以使用CAN波特率计算器工具来计算得到(下载地址:CAN波特率计算器下载):
【4】CAN初始化配置(其中,波特率配置为1M,滤波器配置标准帧ID为1):
/**************************************************************************
* 函数名称: COM_Cfg
* 功能描述: CAN通信初始化配置
**************************************************************************/
void COM_Cfg(void)
{stc_can_init_config_t stcCanInitCfg;stc_can_filter_t stcFilter;Sysctrl_SetPeripheralGate(SysctrlPeripheralCan, TRUE);///<CAN 波特率配置COM_BaudCfg(&stcCanInitCfg, APB1_CLK, CAN_BAUD); //48MHz主频,1M波特率stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 16-1;stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 10;stcCanInitCfg.enCanRxBufAll = CanRxNormal;stcCanInitCfg.enCanRxBufMode = CanRxBufNotStored;stcCanInitCfg.enCanSTBMode = CanSTBFifoMode;CAN_Init(&stcCanInitCfg);///<CAN 滤波器配置stcFilter.enAcfFormat = CanAllFrames;stcFilter.enFilterSel = CanFilterSel1;stcFilter.u32CODE = 0x00000001;stcFilter.u32MASK = 0x1FFFFFFF;CAN_FilterConfig(&stcFilter, TRUE);CAN_IrqCmd(CanRxIrqEn, TRUE);EnableNvic(CAN_IRQn, IrqLevel0, TRUE);
}
【5】CAN中断服务子程序(用于CAN接收):
stc_can_rxframe_t stcRxFrame;
stc_can_txframe_t stcTxFrame;
uint8_t u8RxFlag = FALSE;/**************************************************************************
* 函数名称: Can_IRQHandler
* 功能描述: CAN中断服务函数
**************************************************************************/
void Can_IRQHandler(void)
{if(TRUE == CAN_IrqFlgGet(CanRxIrqFlg)){CAN_IrqFlgClr(CanRxIrqFlg);CAN_IrqCmd(CanRxIrqEn, FALSE);CAN_Receive(&stcRxFrame);u8RxFlag = TRUE;}
}
【6】CAN发送接口(用于CAN发送):
/**************************************************************************
* 函数名称: COM_Tx
* 功能描述: CAN通信发送测试
**************************************************************************/
void COM_Tx(void)
{//中断接收,循环发送uint8_t u8Idx = 0;if(TRUE == u8RxFlag){u8RxFlag = FALSE;if(1 == stcRxFrame.Cst.Control_f.RTR){return;}//<<Can TxstcTxFrame.StdID = stcRxFrame.StdID;stcTxFrame.Control_f.DLC = stcRxFrame.Cst.Control_f.DLC;stcTxFrame.Control_f.IDE = stcRxFrame.Cst.Control_f.IDE;stcTxFrame.Control_f.RTR = stcRxFrame.Cst.Control_f.RTR;for(u8Idx=0; u8Idx<stcRxFrame.Cst.Control_f.DLC; u8Idx++){stcTxFrame.Data[u8Idx] = stcRxFrame.Data[u8Idx];}CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd);CAN_IrqCmd(CanRxIrqEn, TRUE);}
}
【7】主函数调用:
int32_t main(void)
{//系统时钟App_SysClkInit();//通信模块COM_Init();COM_Cfg();while(1){//通信COM_Tx();delay1ms(10);}
}
五 CAN通讯测试1(中断接收,Echo发送单帧)
进行CAN测试的方法很多,如果没有USB-CAN通信转换工具/CAN协议分析工具,可以增加CAN外部回环或者内部回环的配置,配合Log串口输出或者仿真器Debug进行测试。我这边使用了USB-CAN通信转换工具(CAN-II)/CAN协议分析工具(CANTest)直接进行收发测试:
【1】选择 CANTest 中的对应设备 USBCAN2:
【2】匹配软件中的波特率为1M,确定并启动CAN:
【3】修改帧ID为1,点击发送,可以看到上位机发送数据到测试板,经由测试板返回相同长度及内容的数据:
以上配置及测试成功。
六 CAN通讯测试2(中断接收,发送多帧)
【1】发送多帧背景说明:
实际应用中,往往需要收到一组请求之后,发送多组数据。尝试直接在 COM_Tx 函数中紧跟着第一帧数据发送之后再发一帧,有了如下操作:
实测上述连续发送的方法是错误的,因为时间间隔太短,前一组通过主缓冲器(PTB)发送的数据还没有完成就又收到新的发送命令,导致后发送的命令失败。
【2】同一个缓冲器连续发送多帧,中间加延时的方法:
使用同一个主缓冲器(PTB)发送,中间增加1ms延时等待上一帧发送结束(在我的系统上实测这个延迟的时间要大于500us,其他环境不绝对):
/**************************************************************************
* 函数名称: COM_Tx
* 功能描述: CAN通信发送测试
* 其他说明:
**************************************************************************/
void COM_Tx(void)
{uint8_t u8Idx = 0;if(TRUE == u8RxFlag){u8RxFlag = FALSE;if(1 == stcRxFrame.Cst.Control_f.RTR){return;}//<<主缓冲器Can Tx第一帧stcTxFrame.StdID = 0;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.TBUF32_2[0] = 0;stcTxFrame.TBUF32_2[1] = 1;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd); //PTB发送命令delay1ms(1); //若使用单一缓冲器,连续发送失败,需要中间加延时等待上一帧发送结束(实测大于500us)stcTxFrame.StdID = 1;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.TBUF32_2[0] = 2;stcTxFrame.TBUF32_2[1] = 3;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd); //PTB发送命令CAN_IrqCmd(CanRxIrqEn, TRUE);}
}
测试结果如下:
【3】使用不同缓冲器发送多帧的方法:
除了上述同一个缓冲器加延时以实现连续发送多帧数据之外,还可以依赖MCU CAN外设提供的另外几组缓冲器实现连续发送多帧数据的目的(更可靠)。
由芯片说明书可以看到,主缓冲器(PTB)只能缓冲一帧数据。而另外的副缓冲器(STB)可以缓冲4帧数据。实现代码如下(收到信号之后,一次发送5帧数据,其中第一帧挂载主缓冲器PTB上,其他四帧挂载副缓冲器STB上):
/**************************************************************************
* 函数名称: COM_Tx
* 功能描述: CAN通信发送测试
* 其他说明:
**************************************************************************/
void COM_Tx(void)
{uint8_t u8Idx = 0;if(TRUE == u8RxFlag){u8RxFlag = FALSE;if(1 == stcRxFrame.Cst.Control_f.RTR){return;}//<<主缓冲器Can Tx第一帧stcTxFrame.StdID = 0;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.TBUF32_2[0] = 0;stcTxFrame.TBUF32_2[1] = 1;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd); //PTB发送命令// delay1ms(1); //若使用单一缓冲器,连续发送失败,需要中间加延时等待上一帧发送结束(实测大于500us)//<<副缓冲器Can Tx第二帧stcTxFrame.StdID = 1;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 2;stcTxFrame.TBUF32_2[1] = 3;CAN_SetFrame(&stcTxFrame);//<<副缓冲器Can Tx第三帧stcTxFrame.StdID = 2;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 4;stcTxFrame.TBUF32_2[1] = 5;CAN_SetFrame(&stcTxFrame);//<<副缓冲器Can Tx第四帧stcTxFrame.StdID = 3;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 6;stcTxFrame.TBUF32_2[1] = 7;CAN_SetFrame(&stcTxFrame);//<<副缓冲器Can Tx第五帧stcTxFrame.StdID = 4;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 8;stcTxFrame.TBUF32_2[1] = 9;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanSTBTxAllCmd); //STB所有帧发送命令CAN_IrqCmd(CanRxIrqEn, TRUE);}
}
测试结果如下:
综上,CAN通信收发测试完成。
相关文章:

【嵌入式】HC32F07X CAN通讯配置和使用配置不同缓冲器以连续发送
一 背景说明 使用小华(华大)的MCU HC32F07X实现 CAN 通讯配置和使用 二 原理分析 【1】CAN原理说明(参考文章《CAN通信详解》): CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现…...

Linux的常见指令(一)
目录 一、文件 二、常见指令 1、pwd 2、ls 1、ls -a 2、ls -l 3、ls -i 编辑 3、touch 4、mkdir 5、cd 6、rmdir 和 rm 7、man 8、cp 一、文件 目录和文件是在磁盘上建立的,空文件是在磁盘上占用空间的(文件包括文件内容和文件的各种属…...

Jenkins 参数动态获取目录里面的内容
Jenkins 参数动态获取目录里面的内容 假如我们想把一个目录下面的tar.gz文件作为jenkins参数,这个目录会实时更新,每次运行job的时候需要把目录里面的文件作为输入,这时候我们可以使用jenkins自带的Active Choices Parameter参数 在参数中写…...

centos 搭建内网ntp时间服务器
在 CentOS 搭建内网 NTP 时间服务器,你可以按照以下步骤操作: 安装 NTP 服务: 打开终端并以 root 用户身份登录。使用以下命令安装 NTP 服务: sudo yum install ntp配置 NTP 服务器: 打开 NTP 配置文件 /etc/ntp.conf&…...

FreeRTOS-消息队列的使用
1. 定义队列传输的内容和队列结构体对象 使用 xQueueHandle结构体创建对象 typedef struct {u8 TaskNum;u8 Cmd;u8 * buf;}QueueObject_t;xQueueHandle xQueue NULL; 2. 调用xQueueCreate API创建队列 xQueueCreate()函数:用于创建一个消息队列。 QueueHan…...

喜欢 Android 14 的 14 个理由
和去年 8 月中旬发布的 Android 13 正式版不同,今年的 Android 14 正式版延后到了 10 月 4 日——也就是 Pixel 8 系列发布的同一天。原因我们似乎也能从 Google 宣传新特性中略窥一二: 除了明确表示会率先向特定 Pixel 机型推送的 AI 壁纸生成…...

图解系列--路由器和它庞大的功能
03.01 何为路由器 路由器是指主要负责 OSI参考模型中网络层的处理工作,并根据路由表信息在不同的网络 之间转发IP 分组的网络硬件(图3-1)。这里的网络一般是指IP 子网,也可以称为广播域。此外,现在的路由器还会搭载其他各种各样的功能。 0…...

DBeaver 23.2.3发布,带来多项增强和修复
数据库管理工具DBeaver最新版本23.2.3已经发布。这个版本带来了一系列的增强和修复,提升了用户的使用体验和工作效率。 以下是DBeaver 23.2.3版本的一些亮点功能: 数据编辑器方面的改进: Excel (XLSX) 导出现在支持列自动拟合,…...

Proteus仿真--基于51单片机的按键选播电子音乐(仿真文件+程序)
本文主要介绍基于51单片机的按键选播电子音乐(完整仿真源文件及代码见文末链接) 本设计中包括一个按键和一个喇叭,点击按键可以切换选择播放不同的音乐 仿真图如下 其中点击按键K1进行音乐选播选择切换 仿真运行视频 Proteus仿真--基于5…...

node使用http模块
文章目录 前言一、创建http服务二、设置http的响应报文三、不同请求响应不同数据四、请求响应不同html文件1. 添加www文件夹2. js代码3. 效果 五、get和post请求的区别 前言 提示:这里可以添加本文要记录的大概内容: 一、创建http服务 // 1:…...

Golang Study 进阶
Golang 本文章中记录一些 Golang 中的语言特性,包括 init 函数,面向对象,defer 关键字,并发编程等。 init 函数与导包 init函数的执行流程是早于main函数的,如果想在main函数执行前做一些事情,可以在init函…...

Shopee买家通系统详细功能介绍
Shopee买家通系统是一款全自动化操作的软件,可以批量注册买家号、自动加购加心愿单、自动下单等。 批量注册买家号 准备好相应资料后,在运行注册时可以自动输入手机号、自动输入短信、自动输入设置的密码。 自动加购加心愿单 根据设置的关键词及产品编…...

git生成gitee和github两个不同的公钥
配置多个公钥 Windows 用户建议使用 Windows PowerShell 或者 Git Bash,在 命令提示符 下无 cat 和 ls 命令。 1、生成公钥文件: 通过命令 ssh-keygen 生成 SSH Key: ssh-keygen -t rsa -C "Gitee SSH Key" -f ~/.ssh/gitee_be…...

基于SSM的同学录网站
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…...

第十五节——观察者watch
一、概念 在Vue中,watch是一个用于监听数据变化的功能。它可以监听一个或多个数据,并在数据发生变化时执行相应的操作。当我们需要在数据变化时执行异步操作、计算属性或执行一些副作用时,watch就派上了用场啦。注意。watch默认只能进行浅层…...

tauri 访问静态资源,响应头为Content-Type:‘text/html‘
现象 报错: Error: THREE.FBXLoader: Unknown format. at FBXLoader.parse (index-f8291142.js:22050:15) at Object.onLoad (index-f8291142.js:22033:22) at index-f8291142.js:19769:20 使用threejs 加载fbx模型文件时,返回头中Content-…...

【佳学基因检测】Node.js中如何读取并调用内容
【佳学基因检测】Node.js中如何读取并调用内容 先给出功能实现代码: var http require(http); var fs require(fs); http.createServer(function (req, res) {fs.readFile(jiaxuejiyin.html, function(err, data) {res.writeHead(200, {Content-Type: text/html…...

java根据音频流或者音频的地址获取分贝的工具类
工具类 import lombok.extern.slf4j.Slf4j;import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; import java.io.BufferedInputStre…...

Pycharm出现的一些问题和解决办法
1.每次启动打开多个项目,速度很慢。改为每次启动询问打开哪个单一项目 Setting -> Appearance & Behavior -> System Settings -> Project -> 关闭Reopen projects on startop 2.一直显示《正在关闭项目closing project》,关不上 pycha…...

进程优先级(nice值,top指令),独立性,竞争性,进程切换(时间片),抢占与出让,并发并行概念
目录 优先级 引入 为什么会存在优先级 特点 优先级值 nice值 更改nice值 top指令 独立性 竞争性 进程切换 引入 时间片 上下文切换 调度器 抢占与出让 强占 出让 并发和并行 并发 并行 优先级 引入 与权限不同的是,权限是能不能做的问题,优先级是什…...

若依微服务集成Mybatis-plus详细教程
本章教程,主要介绍,若依开源框架微服务版本,如何集成Mybatis-plus。 目录 一、引入依赖 1、在根pom.xml中的properties里加入Mybatis-plus版本 2、在根pom.xml中引入Mybatis-plus依赖...

WebSocket:实现实时双向通信的利器
WebSocket:实现实时双向通信的利器 WebSocket是一种强大的协议,用于实现实时双向通信,允许客户端和服务器之间建立长久的连接,以便实时传递数据。这个协议在现代Web应用中发挥着至关重要的作用,因为它使得开发实时性要…...

【uniapp】html和css-20231031
我想用控件和样式来表达应该会更贴切,html和css的基础需要看看。 关于html:https://www.w3school.com.cn/html/html_layout.asp 关于css:https://www.w3school.com.cn/css/index.asp html让我们实现自己想要的布局(按钮࿰…...

Docker Tomcat 搭建文件服务器
本文基于openwrt上进行。 步骤 1: 安装 Docker 如果尚未安装Docker,首先需要安装Docker。根据你的操作系统,参考Docker官方文档来完成安装, 这里不做详细介绍。 步骤 2: 拉去docker Tomcat镜像 进入openwrt管理界面,docker选项中 拉取最新…...

无感刷新 token
文章目录 背景基本思路需解决的问题请求进入死循环标记刷新 token 请求避免请求拦截覆盖 refresh token并发刷新 token 完整代码注意:拦截器注册顺序另一种方案:事件驱动刷新 前景提要: ts 简易封装 axios,统一 API 实现在 confi…...

【MISRA C 2012】Rule 2.6 函数不应该包含未使用的标签声明
1. 规则1.1 原文1.2 分类 2. 关键描述3. 代码实例 1. 规则 1.1 原文 Rule 2.6 A function should not contain unused label declarations Category Advisory Analysis Decidable, Single Translation Unit Applies to C90, C99 1.2 分类 规则2.6:函数不应该包含…...

Ubuntu:使用apache2部署Vue开发的网站
作者:CSDN @ _乐多_ 本文记录了Vue项目打包到部署到ubuntu系统的全部步骤。 文章目录 一、代码打包二、安装 Apache2三、开启/关闭apache23.1 开启3.2 关闭四、部署Vue应用到Apache24.1 首次部署4.2 更新部署五、全部操作截图一、代码打包 首先,确保您已经在本地开发环境中…...

使用IO完成端口实现简单回显服务器
说明 使用IO完成端口实现简单回显服务器,因为是测试用的,所以代码很粗糙。 提醒 使用的是ReadFile、WriteFile来实现Overlapped IO,正式场合应该用WSARecv、WSASend,原因:来自《Windows网络编程技术》 8.2.5节 在这里…...

【ROS】Nav2源码之nav2_behavior_tree详解
1、简介 nav2_bt_navigator实现ROS2节点以行为树的方式来处理。 nav2_behavior_tree模块提供如下功能: 一个c模板类,可以轻松地将ROS2 动作(actions)和服务(services)集成到行为树(Behavior Trees)中。特定于导航的行为树节点。通用的BehaviorTreeEngine类&#…...

SpringBoot---myBatis数据库操作
一,分页查询 现在controller中设置参数,RequestParam(defaultValue "1") 设置默认值 GetMapping public Result page(RequestParam(defaultValue "1") Integer page,RequestParam(defaultValue "10") Integer pageSize…...