AX58100+STM32使用FSMC接口,运行EtherCAT Slave协议栈

目录

  • 简介
  • 环境
  • 硬件接线
  • MCU一侧的初始化
      • 时钟
      • FSMC
      • 外部中断
      • timer
  • 协议栈生成
      • EtherCAT Slave
          • Slave infomation
          • generic
          • hardware
          • EtherCAT State Machine
          • Synchronisation
          • Applicaiton
          • ProcessData
          • Mailbox
      • OD TOOL
  • 协议栈移植
      • 协议栈集成和错误初步解决
      • 启动协议栈
  • 应用开发
  • 集成到TWINCAT
      • 集成
      • 烧录ESC 配置
      • 测试运行

简介

EtherCAT是一种快速准时的工业以太网协议,多用于运动控制和远程IO

EtherCAT协议分为Master和Slave,Slave的协议栈物理层芯片成为ESC

AX58100就是一个ESC,内部包含9KB的双端内存。

EtherCAT Master 对ESC更新数据的时候,是硬件自动完成对9KB DPRAM的操作,无需MCU参与。MCU自己决定什么时候处理数据。

环境

SSC:5.12, 5.1.3的软件版本在生成工程的时候有patch fail的错误

KEIL:5.3.6

CUBEMX:6.11.1

硬件接线

接口作用
FSMC访问AX58100的RAM
PDI INT中断信号,向MCU指示有Process Data更新
SYNC0 INT中断信号,向MCU指示SYNC0时间到达,未使用
SYNC1 INT中断信号,向MCU指示SYNC1时间到达,未使用

详细硬件接线如下

PIN功能PIN功能PIN功能
PF0FSMC_A0PD14FSMC_D0PG12FSMC_NE4
PF1FSMC_A1PD15FSMC_D1PD4FSMC_NOE
PF2FSMC_A2PD0FSMC_D2PD5FSMC_NWE
PF3FSMC_A3PD1FSMC_D3
PF4FSMC_A4PE7FSMC_D4
PF5FSMC_A5PE8FSMC_D5
PF12FSMC_A6PE9FSMC_D6PC3SYNC0_INT
PF13FSMC_A7PE10FSMC_D7PC1SYNC1_INT
PF14FSMC_A8PE11FSMC_D8PC0PDI_INT
PF15FSMC_A9PE12FSMC_D9
PG0FSMC_A10PE13FSMC_D10
PG1FSMC_A11PE14FSMC_D11
PG2FSMC_A12PE15FSMC_D12
PD8FSMC_D13
PD9FSMC_D14
PD10FSMC_D15

MCU一侧的初始化

时钟

时钟初始化,拉到最高

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

FSMC

FSMC挂载在AHB3片内总线上,拿到的频率应该就是图上的AHP总线频率168Mhz,一个tick是6ns左右。

data setup time :地址建立时间为0,设置为1个tick

Address setup time :数据建立时间参考下图,最差情况下为566ns,大约为95个tick

Bus turn arround time :读写切换时间为5ns,设置为2个tick

以上参数参考AX58100的数据手册,我自己的理解可能有误,请自行斟酌。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里插入图片描述

CubeMX中FSMC初始化参数如下

在这里插入图片描述

小测试

​ FSMC配置完毕之后,AX58100的双端RAM就挂载到0x6C000000上了,我们可以尝试对这一段数据做读取操作,将前8KB数据打印出来。

static uint8_t AX58100_RAM[8192] = {0};
SEGGER_RTT_printf(0, "*** START ***\n");
memcpy(AX58100_RAM,(uint8_t*)(0x6C000000 + 0), 8192);
for(uint8_t i = 0; i < 128; i++)
{for(uint8_t j = 0; j < 64; j++){SEGGER_RTT_printf(0, "%02x ", AX58100_RAM[i*128 + j]);}SEGGER_RTT_printf(0, "\r\n");
}
HAL_Delay(500);

注意:如果没有对AX58100做配置的话,此处不一定能读取出来如下图中的数据。AX58100的配置与EtherCAT描述文件相关,我在后面的章节描述的。这个测试可以在烧录描述文件之后再做。

但是,上面的代码至少不应该触发硬件中断,如果触发了硬件中断,有可能是FSMC片选线等配置问题。

在这里插入图片描述

外部中断

引脚正常为高电平,有信号的时候为低电平

在这里插入图片描述

重写HAL_GPIO_EXTI_Callback,直接短接中断引脚到地,测试能否进入中断函数中去

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin==PDI_INT_Pin){//}else if(GPIO_Pin==SYNC0_INT_Pin){//}else if(GPIO_Pin==SYNC1_INT_Pin){//}
}

timer

EtherCAT需要一个1ms timer定时喂狗,MCU一侧需要准备一个1mstimer和相应的回调函数

在这里插入图片描述

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim == &htim3){//}
}

做完上述之后,在main.h中添加外设和部分C库驱动,我们后面会直接把main.h引入到EtherCAT协议栈中

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "tim.h"					/* timer */
#include "SEGGER_RTT.h"				/* print */
#include "string.h"					/* memcpy */
#include "stdlib.h"					/* malloc */
/* USER CODE END Includes */

协议栈生成

上面我们准备好了协议栈底层对接的硬件,现在我们开始准备协议栈本体。

协议栈使用SSC工具生成

打开软件,FILE -> new,选择default默认模板。

在这里插入图片描述

选择模板之后,整体界面如下

在这里插入图片描述

EtherCAT Slave

协议栈文件集合,保持不变

Slave infomation

从站设备名称,图片,版本号等信息,保持不变

generic

SYSTEM_HEADER_FILE:设置为#include “main.h”,注意把所有MCU外设相关的头文件引入到main.h中

hardware

EL_9800HW:使用倍福官方的EL9800开发板,设置为0不使用

MCI_HW:使用并口,设置为1使用

CONTROLLER_32bit:STM32是32位处理器,设置为1

CONTROLLER_16bit:STM32是16位处理器,设置为0

_PIC18,_PIC24:STM32不是这两个处理器,设置为0

UC_SET_ECAT_LED:由单片机设置EtherCAT状态灯,这里先不处理,设置为0

其余配置项保持默认

EtherCAT State Machine

保持不变

Synchronisation

ECAT_TIMER_INT:用于看门狗的喂狗定时器,这里设置为1开启

Applicaiton

全部设置为0

ProcessData

​ 保持不变

Mailbox

保持不变,后面按需求开启

关于Mailbox和ProcessData地址的描述

在这里插入图片描述

AX58100 RAM分配如下:
0x0000~0x0FFF	(ESC Memory Map,EtherCAT协议栈配置相关,4KB)
0x1000~0x2FFF	(Process Data RAM,过程数据,4KB)SSC中的配置如下:
MBX_Write	(MIN-MAX), 0x1000_0x2FFF, 实际使用0x1000~0x1080,128字节
MBX_Write	(MIN-MAX), 0x1000_0x2FFF, 实际使用0x1080~0x1100,128字节
PD_Write	(MIN-MAX), 0x1000_0x2FFF, 实际使用0x1100~0x1144,68字节
PD_Read		(MIN-MAX), 0x1000_0x2FFF, 实际使用0x1400~0x1444,68字节

可以看出,SSC中的配置在58100的范围之内,能满足我们的要求

注意::

开启MCI_HW后出现如下警告,不用管,这个指示提醒你要完成mcihw.h中有关timer的宏定义,后面我们回去做。

在这里插入图片描述

编辑完毕之后记得保存SSC工程。所有配置如下

在这里插入图片描述

OD TOOL

OD TOOL实际上是一个Excel表格,用于编辑过程数据影像,COE Record,枚举等。SSC TOOL将会利用该表格生成ESI描述文件。

在这里插入图片描述

之后会弹出一个excel界面

这里我们只做输入输出数据的修改,配置数据、Module Slot、Diagnosis、ENUM都是能在此处编辑的,请参考《Application Note ET9300》文档。后面我们也会对其余配置做博客。

编辑输入输出数据如下
在这里插入图片描述

编辑完毕,保存并关闭EXCEL文件,点击创建新的从站文件

在这里插入图片描述

这里可以选择生成原码SRC和ESI文件的位置。

在这里插入图片描述

点击START开始

在这里插入图片描述

OK,到此为止协议栈文件生成成功了。后面就是移植的事情

对于SSC 5.1.3,这里会有一个patch fail,无伤大雅。

协议栈移植

协议栈集成和错误初步解决

keil中创建一个新的文件组,把协议栈文件全部加入keil环境中

在这里插入图片描述
直接编译,有一堆警告和问题。
我们主要要对接好mcihw.c 和mcihw.h两个文件,对接好之后这些警告和错误就消失了

打开mcihw.h

38行注释掉#include <malloc.h>,使用main.h中的stdlib.h申请释放内存

//#include <malloc.h>

48~68行,可以看到一些timer的宏定义,主要用于看门狗喂狗。对接timer函数如下:

#ifndef HW_GetTimer
/*** \todo Define a macro or implement a function to get the hardware timer value.<br>See SSC Application Note for further details, http://www.beckhoff.com/english.asp?download/ethercat_development_products.htm?id=71003127100387*/
#define HW_GetTimer()								__HAL_TIM_GET_COUNTER(&htim3)
#endif#ifndef HW_ClearTimer
/*** \todo Define a macro or implement a function to clear the hardware timer value.<br>See SSC Application Note for further details, http://www.beckhoff.com/english.asp?download/ethercat_development_products.htm?id=71003127100387*/
#define HW_ClearTimer()							__HAL_TIM_SET_COUNTER(&htim3, 0)
#endif/*** \todo Define the hardware timer ticks per millisecond.*/
#define ECAT_TIMER_INC_P_MS					1000

80行注释掉警告

//#warning "define access to timer register(counter)"

文件末尾增加中断和定时器的控制宏

#define 	INIT_ESC_INT
#define     DISABLE_ECAT_TIMER_INT    	NVIC_DisableIRQ(TIM3_IRQn)
#define     ENABLE_ECAT_TIMER_INT     	NVIC_EnableIRQ(TIM3_IRQn)
#define     DISABLE_SYNC0_INT         	NVIC_DisableIRQ(EXTI3_IRQn)
#define     ENABLE_SYNC0_INT          	NVIC_EnableIRQ(EXTI3_IRQn)
#define     DISABLE_SYNC1_INT         	NVIC_DisableIRQ(EXTI1_IRQn) 
#define     ENABLE_SYNC1_INT          	NVIC_EnableIRQ(EXTI1_IRQn) 
#define 	DISABLE_ESC_INT()       	NVIC_DisableIRQ(EXTI0_IRQn)
#define 	ENABLE_ESC_INT()        	NVIC_EnableIRQ(EXTI0_IRQn)

打开mcihw.c

118行,直接对pEsc赋值为0x6C000000,这是STM32 使用FSMC NE4的逻辑地址空间,此后pEsc就指向外挂双端内存的起始位置,长度为9KB。

pEsc = (ESC_MEM_ADDR ESCMEM *)(0x6C000000);

121-125行,注释掉警告

//#if _WIN32
//#pragma message ("The expected PDI Control value depends on the configured PDI (see ESC datasheet, register 0x140)")
//#else
//     #warning "The expected PDI Control value depends on the configured PDI (see ESC datasheet, register 0x140)"
//#endif

127~135行,这个地方在循环读取u16PdiCtrl等待ESC准备好,ESC准备好之后才能退出循环。对于SSC 5.1.3工具生成的代码会在这个地方卡死,需要手动修改。我们使用的5.1.2不会

    {UINT16 u16PdiCtrl = 0;do{HW_EscReadWord(u16PdiCtrl,ESC_PDI_CONTROL_OFFSET);u16PdiCtrl = SWAPWORD(u16PdiCtrl);} while (((u16PdiCtrl & 0xFF) < 0x8) || ((u16PdiCtrl & 0xFF) > 0xD) );	//5.1.2此处可以通过, 5.1.3建议调试到此处按值修改}

149行,HW_Init末尾追加timer3启动函数

    /* enable the ESC-interrupt microcontroller specific,the macro ENABLE_ESC_INT should be defined in ecat_def.h */ENABLE_ESC_INT();HAL_TIM_Base_Start_IT(&htim3);return 0;
}

160-180行,对接PDI和看门狗定时器的终端服务函数,全部注释之后后面追加我们自己的定时中断函数

///
///**
// \brief    Interrupt service routine for the interrupts from the EtherCAT Slave Controller
//*//#ifndef _WIN32
//interrupt
//#endif
//void HW_EcatIsr(void)
//{
//    PDI_Isr();
//}///
///**
// \brief    Timer interrupt service routine which will shall be called every ms
//*///* header of the ISR shall be defined in mcihw.h */
//TIMER_INT_HEADER
//void APPL_1MsTimerIsr(void)
//{
//    ECAT_CheckTimer();
//}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin==PDI_INT_Pin){PDI_Isr();}else if(GPIO_Pin==SYNC0_INT_Pin){Sync0_Isr();}else if(GPIO_Pin==SYNC1_INT_Pin){Sync1_Isr();}
}void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim == &htim3){ECAT_CheckTimer();}
}

启动协议栈

到此我们的移植对接工作接近末尾了,接下来我们准备启动EtherCAT协议栈

参考SSC-Device.c中未启用的main函数,EtherCAT的启动主要有如下步骤

#include "ecat_def.h"
#include "applInterface.h"
#include "SSC-Device.h"HW_Init();
MainInit();
bRunApplication = TRUE;
do
{MainLoop();} while (bRunApplication == TRUE);HW_Release();

我们把这些代码放到cubemx生成的main中也好,或者在RTOS中创建一个线程运行也好,都可以。这里我放main中

头文件

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ecat_def.h"
#include "applInterface.h"
#include "SSC-Device.h"
/* USER CODE END Includes */

初始化和循环

  /* USER CODE BEGIN 2 */HW_Init();MainInit();bRunApplication = TRUE;do{MainLoop();} while (bRunApplication == TRUE);HW_Release();/* USER CODE END 2 */

到此为止,我们的移植就做完了

编译之后的警告只剩余一些提示性的,屏蔽掉即可

//不用关注
../../Src/coeappl.c(883): warning: comparison of array 'ApplicationObjDic' not equal to a null pointer is always true [-Wtautological-pointer-compare]if(ApplicationObjDic != NULL)^~~~~~~~~~~~~~~~~    ~~~~//不用关注
../../Src/objdef.c(540): warning: result of comparison of constant 65535 with expression of type 'const unsigned char' is always true [-Wtautological-constant-out-of-range-compare]&&( pSubDesc[0] != 0xFF && pSubDesc[0] != 0xFE && pSubDesc[0] != 0xFFFF))~~~~~~~~~~~ ^  ~~~~~~//以下三个警告提示用户需要做相应的应用开发,我们完成这些应用函数的时候将其屏蔽即可
../../Src/SSC-Device.c(275): warning: "Implement input (Slave -> Master) mapping" [-W#warnings]#warning "Implement input (Slave -> Master) mapping"^
../../Src/SSC-Device.c(291): warning: "Implement output (Master -> Slave) mapping" [-W#warnings]#warning "Implement output (Master -> Slave) mapping"^
../../Src/SSC-Device.c(305): warning: "Implement the slave application" [-W#warnings]#warning "Implement the slave application"^
3 warnings generated.

应用开发

SSC-Device.c中

void APPL_InputMapping(UINT16* pData)		//从MCU本地copy数据到ESC中
void APPL_OutputMapping(UINT16* pData)  	//从ESC中copy数据到MCU本地
void APPL_Application(void)					//更新MCU本地的输入输出数据

我们使用按键和LED做示例
这里只是测试把KEY赋了固定值,然后按照LED的输出数据修改相关引脚电平

void APPL_InputMapping(UINT16* pData)
{uint8_t *pTmpData = (uint8_t *)pData;for (uint8_t j = 0; j < sTxPDOassign.u16SubIndex0; j++){switch (sTxPDOassign.aEntries[j]){/* TxPDO 1 */case 0x1A00://copy after subindex(2byte)memcpy(pTmpData, (uint8_t *)(&INPUT_GROUP0x6000) + 2, sizeof(INPUT_GROUP0x6000)-2);break;}}
}void APPL_OutputMapping(UINT16* pData)
{uint8_t *pTmpData = (uint8_t *)pData;for (uint8_t j = 0; j < sRxPDOassign.u16SubIndex0; j++){switch (sRxPDOassign.aEntries[j]){/* TxPDO 1 */case 0x1600://copy after subindex(2byte)memcpy((uint8_t *)(&OUTPUT_GROUP0x7000) + 2, pTmpData, sizeof(OUTPUT_GROUP0x7000)-2);break;}}
}void APPL_Application(void)
{INPUT_GROUP0x6000.KEY1 = 1;INPUT_GROUP0x6000.KEY2 = 0;INPUT_GROUP0x6000.KEY3 = 1;INPUT_GROUP0x6000.KEY4 = 0;INPUT_GROUP0x6000.KEY5 = 1;if(OUTPUT_GROUP0x7000.LED1 == 0)HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);elseHAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}

集成到TWINCAT

集成

关闭TwinCAT

将生成的描述文件导入到TWINCAT路径下,C:\TwinCAT\3.1\Config\Io\EtherCAT

启动TwinCAT

没装驱动的话在这里安装驱动

在这里插入图片描述

点击扫描设备

在这里插入图片描述

第一次可能出现如下窗口,点击YES

在这里插入图片描述

出现如下现象,这是因为我们还没有将XML中的配置烧录到ESC中。

在这里插入图片描述

烧录ESC 配置

ESC使用EEPROM保存配置数据,配置项比如是否启用并口,是否启用SPI等等。

这个配置数据我们要写入到ESI文件中,通过Twincat烧录进入AX58100

配置的描述在AX58100 DataSheet 3.2章节中描述

在这里插入图片描述

AX58100 ESI Design Note中也提供了一些配置模板,如下

我们使用其中的AX58100 Local Bus Demo Board,值:080000000a000000000000000000

在这里插入图片描述

找文本工具打开描述文件SSC-Device.xml

修改如下内容

在这里插入图片描述

保存,替换掉Twincat中的描述文件

重载TwinCAT描述

在这里插入图片描述
删除EtherCAT Master(重要),重新Scan,按照下图指示更新EEPROM固件
在这里插入图片描述

在这里插入图片描述

设备重新上电,重新扫描设备,状态机进入OP模式

在这里插入图片描述

测试运行

KEY显示是符合代码的,开发人员要按照项目需求修改此处的应用程序。

在这里插入图片描述

LED写入也OK

在这里插入图片描述

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

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

相关文章

IC数字后端实现之大厂IC笔试真题(经典时序计算和时序分析题)

今天小编给大家分享下每年IC秋招春招必考题目——静态时序分析时序分析题。 数字IC后端笔试面试题库 | 经典时序Timing计算题 时序分析题1&#xff1a; 给定如下图所示的timing report&#xff0c;请回答一下几个问题。 1&#xff09;这是一条setup还是hold的timing report?…

嵌入式系统与OpenCV

目录 一、OpenCV 简介 二、嵌入式 OpenCV 的安装方法 1. Ubuntu 系统下的安装 2. 嵌入式 ARM 系统中的安装 3. Windows10 和树莓派系统下的安装 三、嵌入式 OpenCV 的性能优化 1. 介绍嵌入式平台上对 OpenCV 进行优化的必要性。 2. 利用嵌入式开发工具&#xff0c;如优…

英伟达发布 Edify 3D 生成模型,可以在两分钟内生成详细的、可用于生产的 3D 资源、生成有组织的 UV 贴图、4K 纹理和 PBR 材质。

英伟达发布 Edify 3D 生成模型&#xff0c;可以利用 Agents 自动判断提示词场景中需要的模型&#xff0c;生成后将他们组合为一个场景。 Edify 3D 可以在两分钟内生成详细的、可用于生产的 3D 资源、生成有组织的 UV 贴图、4K 纹理和 PBR 材质。 相关链接 论文&#xff1a;htt…

抖音短视频矩阵源代码部署搭建流程

抖音短视频矩阵源代码部署搭建流程 1. 硬件准备 需确保具备一台性能足够的服务器或云主机。这些硬件设施应当拥有充足的计算和存储能力&#xff0c;以便支持抖音短视频矩阵系统的稳定运行。 2. 操作系统安装 在选定的服务器或云主机上安装适合的操作系统是关键步骤之一。推…

【Android+多线程】异步 多线程 知识总结:基础概念 / 多种方式 / 实现方法 / 源码分析

1 基本概念 1.1 线程 定义&#xff1a;一个基本的CPU执行单元 & 程序执行流的最小单元 比进程更小的可独立运行的基本单位&#xff0c;可理解为&#xff1a;轻量级进程组成&#xff1a;线程ID 程序计数器 寄存器集合 堆栈注&#xff1a;线程自己不拥有系统资源&#…

NLP论文速读(剑桥大学出品)|分解和利用专家模型中的偏好进行改进视觉模型的可信度

论文速读|Decompose and Leverage Preferences from Expert Models for Improving Trustworthiness of MLLMs 论文信息&#xff1a; 简介&#xff1a; 本文探讨的背景是多模态大型语言模型&#xff08;MLLMs&#xff09;&#xff0c;这类模型通过结合视觉特征和文本空间来增强语…

CentOS8.5.2111(7)完整的Apache综合实验

一、实验目标 1.掌握Linux系统中Apache服务器的安装与配置&#xff1b; 2.掌握个人主页、虚拟目录、基于用户和主机的访问控制及虚拟主机的实现方法。 二、实验要求 练习使用linux系统下WEB服务器的配置方法。 三、实验背景 重庆工程学院为筹备“重庆工程大学”特申请了c…

零基础3分钟快速掌握 ——Linux【终端操作】及【常用指令】Ubuntu

1.为啥使用Linux做嵌入式开发 能广泛支持硬件 内核比较高效稳定 原码开放、软件丰富 能够完善网络通信与文件管理机制 优秀的开发工具 2.什么是Ubuntu 是一个以桌面应用为主的Linux的操作系统&#xff0c; 内核是Linux操作系统&#xff0c; 具有Ubuntu特色的可视…

JVM类加载和垃圾回收算法详解

文章目录 JVM一、JVM运行流程1. JVM执行流程 二、JVM运行时数据区1. 程序计数器&#xff08;线程私有&#xff09;2. 虚拟机栈 &#xff08;线程私有&#xff09;3. 本地方法栈&#xff08;线程私有&#xff09;4. 堆&#xff08;线程共享&#xff09;5. 元空间&#xff08;线程…

iOS 17.4 Not Installed

0x00 系统警告 没有安装 17.4 的模拟器&#xff0c;任何操作都无法进行&#xff01; 点击 OK 去下载&#xff0c;完成之后&#xff0c;依旧是原样&#xff01; 0x01 解决办法 1、先去官网下载对应的模拟器&#xff1a; https://developer.apple.com/download/all/?q17.4 …

day04 企业级Linux安装及远程连接知识实践

1. 使用传统的网卡命名方式 在启动虚拟机时&#xff0c;按tab键进入编辑模式 添加命令&#xff1a; net.ifnames0 biosdevname0 这样linux系统会使用传统的网卡命名&#xff0c;例如eth0、eth1…… 2. 快照 做系统关键操作时&#xff0c;一定要使用快照(先将系统关机) 3.…

人体特定吸收率 (SAR) 分布建模

ANSYS HFSS 提供了一种建模 SAR 分布的方法&#xff01; 2020 年对我们所有人来说都是充满挑战的一年&#xff0c;由于 COVID 19 限制和居家隔离&#xff0c;许多工程师不得不推迟开发时间表。ANSYS HFSS 为所有工程师提供了一种在家安全工作的好方法。隔离期间&#xff0c;您…

.NET9 - Swagger平替Scalar详解(四)

书接上回&#xff0c;上一章介绍了Swagger代替品Scalar&#xff0c;在使用中遇到不少问题&#xff0c;今天单独分享一下之前Swagger中常用的功能如何在Scalar中使用。 下面我们将围绕文档版本说明、接口分类、接口描述、参数描述、枚举类型、文件上传、JWT认证等方面详细讲解。…

计算(a+b)/c的值

计算&#xff08;ab&#xff09;/c的值 C语言代码C语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给定3个整数a、b、c&#xff0c;计算表达式(ab)/c的值&#xff0c;/是整除运算。 输入 输入仅一行&…

PICO 获取设备号 SN码

Unity版本 2020.3.42f1c1PICO SDK版本PICO Unity Integration SDK-3.0.5-20241105Pico设备pico 4ultra 注意 此api暂时只测试企业版本 pico 4ultra 代码 using Unity.XR.PICO.TOBSupport;private void Awake() {bool result PXR_Enterprise.InitEnterpriseService();Debug.L…

【大数据技术基础】 课程 第8章 数据仓库Hive的安装和使用 大数据基础编程、实验和案例教程(第2版)

第8章 数据仓库Hive的安装和使用 8.1 Hive的安装 8.1.1 下载安装文件 访问Hive官网&#xff08;http://www.apache.org/dyn/closer.cgi/hive/&#xff09;下载安装文件apache-hive-3.1.2-bin.tar.gz 下载完安装文件以后&#xff0c;需要对文件进行解压。按照Linux系统使用的…

[STM32]从零开始的STM32 FreeRTOS移植教程

一、前言 如果能看到这个教程的话&#xff0c;说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗&#xff1f;是的&#xff0c;我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS&#xff0c;再到最…

DAY133权限提升-Windows权限提升篇溢出漏洞土豆家族通杀全系补丁对比EXP筛选

知识点 1、Web到Win-系统提权-土豆家族 2、Web到Win-系统提权-人工操作 章节点&#xff1a; 1、Web权限提升及转移 2、系统权限提升及转移 3、宿主权限提升及转移 4、域控权限提升及转移 Windows提权&#xff1a; 1、内核溢出漏洞提权 2、数据库类型提权 3、第三方软件…

web day03 Maven基础 Junit

目录 Maven坐标&#xff1a; 依赖排除&#xff1a; 依赖范围&#xff1a; Maven生命周期&#xff1a; 单元测试&#xff1a; Junit入门&#xff1a; 断言&#xff1a; Junit中的常见注解&#xff1a; 概念&#xff1a;Maven 是一款用于管理和构建 Java项目的工具&#…

day18 结构体

有参宏和函数的区别 1.展开时机&#xff1a;有参宏而言&#xff0c;在预处理阶段展开&#xff0c;而函数在调用时才展开 2.内存使用&#xff1a;有参宏而言&#xff0c;占用的是所在函数的空间&#xff0c;而函数在调用时会单独开辟空间 3.效率上&#xff1a;有参宏的效率比…