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

Zynq-Linux移植学习笔记之67- 国产ZYNQ上通过GPIO模拟MDC/MDIO协议

1、背景介绍

模块上有9个PHY,其中两个PHY通过ZYNQ PS端的MDIO总线连接,其余7个PHY单独通过GPIO进行控制,需要实现GPIO模拟MDC/MDIO协议。

2、vivado工程设计

vivado工程内为每个PHY建立两个GPIO IP核,分别用来代表MDC和MDIO(虽然有点浪费)

MDC配置为默认输出

MDIO配置为双向

MDIO管脚默认上拉

3、MDIO时序介绍

MDIO接口包括两条线,MDIO和MDC,其中MDIO是双向数据线,而MDC是由STA驱动的时钟线。MDC时钟的最高速率一般为2.5MHz,MDC也可以是非固定频率,甚至可以是非周期的。MDIO接口只是会在MDC时钟的上升沿进行采样,而并不在意MDC时钟的频率(类似于I2C接口)。MDIO是一个PHY的管理接口,用来读/写PHY的寄存器,以控制PHY的行为或获取PHY的状态,MDC为MDIO提供时钟。

Preamble+Start:32bits的前导码以及2bit的开始位。

OP Code:2bits的操作码,10表示读,01表示写。

PHYAD:5bits的PHY地址,一般PHY地址,从0开始顺序编号,例如6口switch中PHY地址为0-5。

REGAD:5bits的寄存器地址,即要读或写的寄存器。

Turn Around:2bits的TA,在读命令中,MDIO在此时由MAC驱动改为PHY驱动,并等待一个时钟周期准备发送数据。在写命令中,不需要MDIO方向发生变化,则只是等待两个时钟周期准备写入数据。

Data:16bits数据,在读命令中,PHY芯片将读到的对应PHYAD的REGAD寄存器的数据写到Data中,在写命令中,MAC将要写入对应PHYAD的REGAD寄存器的值写入Data中。

Idle:空闲状态,此时MDIO无源驱动,处高阻状态,但一般用上拉电阻使其处在高电平,上拉电阻一般为1.5K。(空闲电平是低电平)

逻辑分析上抓到的示意图如下:

4、应用程序设计

参考上面的时序,采用GPIO翻转实现,注意AXI GPIO IP核0x4写0为输出,写1为输入,主要是用来操作MDIO方向

代码如下:

/** Copyright (c) 2012 Xilinx, Inc.  All rights reserved.** Xilinx, Inc.* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A* COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS* ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY* AND FITNESS FOR A PARTICULAR PURPOSE.**/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/mii.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include "xil_io.h"#define  PHY2_YT8521_ADDR                             0x01
#define  PHY3_YT8521_ADDR                             0x02
#define  PHY5_YT8521_ADDR                             0x04
#define  PHY6_YT8521_ADDR                             0x05
#define  PHY7_YT8521_ADDR                             0x06
#define  PHY8_YT8521_ADDR                             0x07
#define  PHY9_YT8521_ADDR                             0x00#define  PHY_YT8521_ID_REG_ADDR                      0x03
#define  PHY_YT8521_REG_DEBUG_ADDR_OFFSET            0x1E
#define  PHY_YT8521_REG_DEBUG_DATA                   0x1F
#define  PHY_YT8521_EXT_REG_ADDR                     0xa00d#define MDC2_GPIO_ADDR 0x412B0000
#define MDC3_GPIO_ADDR 0x412D0000
#define MDC5_GPIO_ADDR 0x412F0000
#define MDC6_GPIO_ADDR 0x41310000
#define MDC7_GPIO_ADDR 0x41330000
#define MDC8_GPIO_ADDR 0x41350000
#define MDC9_GPIO_ADDR 0x41370000#define MDIO2_GPIO_ADDR 0x412C0000
#define MDIO3_GPIO_ADDR 0x412E0000
#define MDIO5_GPIO_ADDR 0x41300000
#define MDIO6_GPIO_ADDR 0x41320000
#define MDIO7_GPIO_ADDR 0x41340000
#define MDIO8_GPIO_ADDR 0x41360000
#define MDIO9_GPIO_ADDR 0x41380000#define PHY2_SOFT_SMI_MDIO_READ Xil_In32(MDIO2_GPIO_ADDR)
#define PHY3_SOFT_SMI_MDIO_READ Xil_In32(MDIO3_GPIO_ADDR)
#define PHY5_SOFT_SMI_MDIO_READ Xil_In32(MDIO5_GPIO_ADDR)
#define PHY6_SOFT_SMI_MDIO_READ Xil_In32(MDIO6_GPIO_ADDR)
#define PHY7_SOFT_SMI_MDIO_READ Xil_In32(MDIO7_GPIO_ADDR)
#define PHY8_SOFT_SMI_MDIO_READ Xil_In32(MDIO8_GPIO_ADDR)
#define PHY9_SOFT_SMI_MDIO_READ Xil_In32(MDIO9_GPIO_ADDR)typedef unsigned char u8;
typedef unsigned short u16;void mdio_out(int index)
{switch(index){case 2:Xil_Out32(MDIO2_GPIO_ADDR+0x4,0x0);break;case 3:Xil_Out32(MDIO3_GPIO_ADDR+0x4,0x0);break;case 5:Xil_Out32(MDIO5_GPIO_ADDR+0x4,0x0);break;case 6:Xil_Out32(MDIO6_GPIO_ADDR+0x4,0x0);break;case 7:Xil_Out32(MDIO7_GPIO_ADDR+0x4,0x0);break;case 8:Xil_Out32(MDIO8_GPIO_ADDR+0x4,0x0);break;case 9:Xil_Out32(MDIO9_GPIO_ADDR+0x4,0x0);break;default:break;}}void mdio_in(int index)
{switch(index){case 2:Xil_Out32(MDIO2_GPIO_ADDR+0x4,0x1);break;case 3:Xil_Out32(MDIO3_GPIO_ADDR+0x4,0x1);break;case 5:Xil_Out32(MDIO5_GPIO_ADDR+0x4,0x1);break;case 6:Xil_Out32(MDIO6_GPIO_ADDR+0x4,0x1);break;case 7:Xil_Out32(MDIO7_GPIO_ADDR+0x4,0x1);break;case 8:Xil_Out32(MDIO8_GPIO_ADDR+0x4,0x1);break;case 9:Xil_Out32(MDIO9_GPIO_ADDR+0x4,0x1);break;default:break;}}void mdc_low(int index)
{switch(index){case 2:Xil_Out32(MDC2_GPIO_ADDR,0x0);break;case 3:Xil_Out32(MDC3_GPIO_ADDR,0x0);break;case 5:Xil_Out32(MDC5_GPIO_ADDR,0x0);break;case 6:Xil_Out32(MDC6_GPIO_ADDR,0x0);break;case 7:Xil_Out32(MDC7_GPIO_ADDR,0x0);break;case 8:Xil_Out32(MDC8_GPIO_ADDR,0x0);break;case 9:Xil_Out32(MDC9_GPIO_ADDR,0x0);break;default:break;}}void mdc_high(int index)
{switch(index){case 2:Xil_Out32(MDC2_GPIO_ADDR,0xffffffff);break;case 3:Xil_Out32(MDC3_GPIO_ADDR,0xffffffff);break;case 5:Xil_Out32(MDC5_GPIO_ADDR,0xffffffff);break;case 6:Xil_Out32(MDC6_GPIO_ADDR,0xffffffff);break;case 7:Xil_Out32(MDC7_GPIO_ADDR,0xffffffff);break;case 8:Xil_Out32(MDC8_GPIO_ADDR,0xffffffff);break;case 9:Xil_Out32(MDC9_GPIO_ADDR,0xffffffff);break;default:break;}}void mdio_low(int index)
{switch(index){case 2:Xil_Out32(MDIO2_GPIO_ADDR,0x0);break;case 3:Xil_Out32(MDIO3_GPIO_ADDR,0x0);break;case 5:Xil_Out32(MDIO5_GPIO_ADDR,0x0);break;case 6:Xil_Out32(MDIO6_GPIO_ADDR,0x0);break;case 7:Xil_Out32(MDIO7_GPIO_ADDR,0x0);break;case 8:Xil_Out32(MDIO8_GPIO_ADDR,0x0);break;case 9:Xil_Out32(MDIO9_GPIO_ADDR,0x0);break;default:break;}}void mdio_high(int index)
{switch(index){case 2:Xil_Out32(MDIO2_GPIO_ADDR,0xffffffff);break;case 3:Xil_Out32(MDIO3_GPIO_ADDR,0xffffffff);break;case 5:Xil_Out32(MDIO5_GPIO_ADDR,0xffffffff);break;case 6:Xil_Out32(MDIO6_GPIO_ADDR,0xffffffff);break;case 7:Xil_Out32(MDIO7_GPIO_ADDR,0xffffffff);break;case 8:Xil_Out32(MDIO8_GPIO_ADDR,0xffffffff);break;case 9:Xil_Out32(MDIO9_GPIO_ADDR,0xffffffff);break;default:break;}}void Mcu_Yt8521_Soft_Smi_Bit_Set(int index,u8 bit)
{// set mdio dir out// set mdiomdio_out(index);if(bit) mdio_high(index);else mdio_low(index);// set clk.mdc_low(index);mdc_high(index);
}void Mcu_Yt8521_Soft_Smi_Bit_Get(int index,u8 *bit)
{// set mdio dir in// get mdiomdio_in(index);      //MDIO线设置为输入switch(index){case 2:*bit = !!PHY2_SOFT_SMI_MDIO_READ;break;case 3:*bit = !!PHY3_SOFT_SMI_MDIO_READ;break;case 5:*bit = !!PHY5_SOFT_SMI_MDIO_READ;break;case 6:*bit = !!PHY6_SOFT_SMI_MDIO_READ;break;case 7:*bit = !!PHY7_SOFT_SMI_MDIO_READ;break;case 8:*bit = !!PHY8_SOFT_SMI_MDIO_READ;break;case 9:*bit = !!PHY9_SOFT_SMI_MDIO_READ;break;default:break;}// set clk.mdc_low(index);mdc_high(index);}u16 Srv_Yt8521_Soft_I2c_Device_Write(int index,u8 phy_addr, u8 reg_addr, u16 data)
{u16 i = 0;//idelfor(i = 0; i < 32; i++){Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);}//startMcu_Yt8521_Soft_Smi_Bit_Set(index,0);Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);//op codeMcu_Yt8521_Soft_Smi_Bit_Set(index,0);Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);//phy addressfor(i = 0; i < 5; i++){if( phy_addr & (0x10 >> i) ){Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);}else{Mcu_Yt8521_Soft_Smi_Bit_Set(index,0);}}//register addressfor(i = 0; i < 5; i++){if( reg_addr & (0x10 >> i) ){Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);}else{Mcu_Yt8521_Soft_Smi_Bit_Set(index,0);}}//TA翻转状态(ack)Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);Mcu_Yt8521_Soft_Smi_Bit_Set(index,0);//register datafor(i = 0; i < 16; i++){if( data & (0x8000 >> i) ){Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);}else{Mcu_Yt8521_Soft_Smi_Bit_Set(index,0);}}return 0;
}u16 Srv_Yt8521_Soft_I2c_Device_Read(int index,u8 phy_addr, u8 reg_addr)
{u16 i = 0;u16 data = 0;     //待获取的数据u8  bit  = 0;//idelfor(i = 0; i < 32; i++){Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);}//startMcu_Yt8521_Soft_Smi_Bit_Set(index,0);Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);//op codeMcu_Yt8521_Soft_Smi_Bit_Set(index,1);Mcu_Yt8521_Soft_Smi_Bit_Set(index,0);//phy addressfor(i = 0; i < 5; i++){if( phy_addr & (0x10 >> i) ){Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);}else{Mcu_Yt8521_Soft_Smi_Bit_Set(index,0);}}//register addressfor(i = 0; i < 5; i++){if( reg_addr & (0x10 >> i) ){Mcu_Yt8521_Soft_Smi_Bit_Set(index,1);}else{Mcu_Yt8521_Soft_Smi_Bit_Set(index,0);}}//TA翻转状态(ack)Mcu_Yt8521_Soft_Smi_Bit_Get(index,&bit);Mcu_Yt8521_Soft_Smi_Bit_Get(index,&bit);//register datafor(i = 0; i < 16; i++){data<<=1;Mcu_Yt8521_Soft_Smi_Bit_Get(index,&bit);if(bit){data |= 0x1;}}return data;
}int main(int argc, char *argv[])
{int phy_index=0;int reg_addr=0;int value=0;u16 Reg_Value;if(argc<4){printf("Usage mdio_test w/r phy_index[2,3,5,6,7,8,9] reg_addr [value]\n ");return 0;}if(argc==4){phy_index=(uint16_t) strtoul(argv[2], NULL, 0);reg_addr=(uint16_t) strtoul(argv[3], NULL, 0);switch(phy_index){case 2:Reg_Value=Srv_Yt8521_Soft_I2c_Device_Read(2,PHY2_YT8521_ADDR, reg_addr);printf("[READ]phy_index %d reg_addr 0x%x value is 0x%x\n",phy_index,reg_addr,Reg_Value);break;case 3:Reg_Value=Srv_Yt8521_Soft_I2c_Device_Read(3,PHY3_YT8521_ADDR, reg_addr);printf("[READ]phy_index %d reg_addr 0x%x value is 0x%x\n",phy_index,reg_addr,Reg_Value);break;case 5:Reg_Value=Srv_Yt8521_Soft_I2c_Device_Read(5,PHY5_YT8521_ADDR, reg_addr);printf("[READ]phy_index %d reg_addr 0x%x value is 0x%x\n",phy_index,reg_addr,Reg_Value);break;case 6:Reg_Value=Srv_Yt8521_Soft_I2c_Device_Read(6,PHY6_YT8521_ADDR, reg_addr);printf("[READ]phy_index %d reg_addr 0x%x value is 0x%x\n",phy_index,reg_addr,Reg_Value);break;case 7:Reg_Value=Srv_Yt8521_Soft_I2c_Device_Read(7,PHY7_YT8521_ADDR, reg_addr);printf("[READ]phy_index %d reg_addr 0x%x value is 0x%x\n",phy_index,reg_addr,Reg_Value);break;case 8:Reg_Value=Srv_Yt8521_Soft_I2c_Device_Read(8,PHY8_YT8521_ADDR, reg_addr);printf("[READ]phy_index %d reg_addr 0x%x value is 0x%x\n",phy_index,reg_addr,Reg_Value);break;case 9:Reg_Value=Srv_Yt8521_Soft_I2c_Device_Read(9,PHY9_YT8521_ADDR, reg_addr);printf("[READ]phy_index %d reg_addr 0x%x value is 0x%x\n",phy_index,reg_addr,Reg_Value);break;default:break;}}else if(argc==5){phy_index=(uint16_t) strtoul(argv[2], NULL, 0);reg_addr=(uint16_t) strtoul(argv[3], NULL, 0);value=(uint16_t) strtoul(argv[4], NULL, 0);printf("[WRITE] phy_index is %d reg_addr is 0x%x value is 0x%x\n",phy_index,reg_addr,value);switch(phy_index){case 2:Srv_Yt8521_Soft_I2c_Device_Write(2,PHY2_YT8521_ADDR, reg_addr,value);break;case 3:Srv_Yt8521_Soft_I2c_Device_Write(3,PHY3_YT8521_ADDR, reg_addr,value);break;case 5:Srv_Yt8521_Soft_I2c_Device_Write(5,PHY5_YT8521_ADDR, reg_addr,value);break;case 6:Srv_Yt8521_Soft_I2c_Device_Write(6,PHY6_YT8521_ADDR, reg_addr,value);break;case 7:Srv_Yt8521_Soft_I2c_Device_Write(7,PHY7_YT8521_ADDR, reg_addr,value);break;case 8:Srv_Yt8521_Soft_I2c_Device_Write(8,PHY8_YT8521_ADDR, reg_addr,value);break;case 9:Srv_Yt8521_Soft_I2c_Device_Write(9,PHY9_YT8521_ADDR, reg_addr,value);break;default:break;}}#if 0u16 id = 0;printf("//***************** Read SMI Reg of YT8521 ******************//\r\n");printf("------ PHY Identification Registers ------\r\n");id = Srv_Yt8521_Soft_I2c_Device_Read(2,PHY2_YT8521_ADDR, PHY_YT8521_ID_REG_ADDR);   //reg_addr:0x03  读取的值应为0x11aprintf("PHY2_YT8521 id = 0x%x\n", id);id = Srv_Yt8521_Soft_I2c_Device_Read(3,PHY3_YT8521_ADDR, PHY_YT8521_ID_REG_ADDR);   //reg_addr:0x03  读取的值应为0x11aprintf("PHY3_YT8521 id = 0x%x\n", id);id = Srv_Yt8521_Soft_I2c_Device_Read(5,PHY5_YT8521_ADDR, PHY_YT8521_ID_REG_ADDR);   //reg_addr:0x03  读取的值应为0x11aprintf("PHY5_YT8521 id = 0x%x\n", id);id = Srv_Yt8521_Soft_I2c_Device_Read(6,PHY6_YT8521_ADDR, PHY_YT8521_ID_REG_ADDR);   //reg_addr:0x03  读取的值应为0x11aprintf("PHY6_YT8521 id = 0x%x\n", id);id = Srv_Yt8521_Soft_I2c_Device_Read(7,PHY7_YT8521_ADDR, PHY_YT8521_ID_REG_ADDR);   //reg_addr:0x03  读取的值应为0x11aprintf("PHY7_YT8521 id = 0x%x\n", id);id = Srv_Yt8521_Soft_I2c_Device_Read(8,PHY8_YT8521_ADDR, PHY_YT8521_ID_REG_ADDR);   //reg_addr:0x03  读取的值应为0x11aprintf("PHY8_YT8521 id = 0x%x\n", id);id = Srv_Yt8521_Soft_I2c_Device_Read(9,PHY9_YT8521_ADDR, PHY_YT8521_ID_REG_ADDR);   //reg_addr:0x03  读取的值应为0x11aprintf("PHY9_YT8521 id = 0x%x\n", id);printf("Setting PHY2\n");Srv_Yt8521_Soft_I2c_Device_Write(2,PHY2_YT8521_ADDR, PHY_YT8521_REG_DEBUG_ADDR_OFFSET, PHY_YT8521_EXT_REG_ADDR);Srv_Yt8521_Soft_I2c_Device_Write(2,PHY2_YT8521_ADDR, PHY_YT8521_REG_DEBUG_DATA,0x604);printf("Setting PHY3\n");Srv_Yt8521_Soft_I2c_Device_Write(3,PHY3_YT8521_ADDR, PHY_YT8521_REG_DEBUG_ADDR_OFFSET, PHY_YT8521_EXT_REG_ADDR);Srv_Yt8521_Soft_I2c_Device_Write(3,PHY3_YT8521_ADDR, PHY_YT8521_REG_DEBUG_DATA,0x604);printf("Setting PHY5\n");Srv_Yt8521_Soft_I2c_Device_Write(5,PHY5_YT8521_ADDR, PHY_YT8521_REG_DEBUG_ADDR_OFFSET, PHY_YT8521_EXT_REG_ADDR);Srv_Yt8521_Soft_I2c_Device_Write(5,PHY5_YT8521_ADDR, PHY_YT8521_REG_DEBUG_DATA,0x604);printf("Setting PHY6\n");Srv_Yt8521_Soft_I2c_Device_Write(6,PHY6_YT8521_ADDR, PHY_YT8521_REG_DEBUG_ADDR_OFFSET, PHY_YT8521_EXT_REG_ADDR);Srv_Yt8521_Soft_I2c_Device_Write(6,PHY6_YT8521_ADDR, PHY_YT8521_REG_DEBUG_DATA,0x604);printf("Setting PHY7\n");Srv_Yt8521_Soft_I2c_Device_Write(7,PHY7_YT8521_ADDR, PHY_YT8521_REG_DEBUG_ADDR_OFFSET, PHY_YT8521_EXT_REG_ADDR);Srv_Yt8521_Soft_I2c_Device_Write(7,PHY7_YT8521_ADDR, PHY_YT8521_REG_DEBUG_DATA,0x604);printf("Setting PHY8\n");Srv_Yt8521_Soft_I2c_Device_Write(8,PHY8_YT8521_ADDR, PHY_YT8521_REG_DEBUG_ADDR_OFFSET, PHY_YT8521_EXT_REG_ADDR);Srv_Yt8521_Soft_I2c_Device_Write(8,PHY8_YT8521_ADDR, PHY_YT8521_REG_DEBUG_DATA,0x604);printf("Setting PHY9\n");Srv_Yt8521_Soft_I2c_Device_Write(9,PHY9_YT8521_ADDR, PHY_YT8521_REG_DEBUG_ADDR_OFFSET, PHY_YT8521_EXT_REG_ADDR);Srv_Yt8521_Soft_I2c_Device_Write(9,PHY9_YT8521_ADDR, PHY_YT8521_REG_DEBUG_DATA,0x604);
#endifreturn 0;
}

5、测试验证

读取裕太8521的PHY ID

相关文章:

Zynq-Linux移植学习笔记之67- 国产ZYNQ上通过GPIO模拟MDC/MDIO协议

1、背景介绍 模块上有9个PHY&#xff0c;其中两个PHY通过ZYNQ PS端的MDIO总线连接&#xff0c;其余7个PHY单独通过GPIO进行控制&#xff0c;需要实现GPIO模拟MDC/MDIO协议。 2、vivado工程设计 vivado工程内为每个PHY建立两个GPIO IP核&#xff0c;分别用来代表MDC和MDIO&…...

Zookeeper(一)在WSL单机搭建Zookeeper伪集群

目录 Zookeeper1 启动单个Zookeeper实例1.1 下载Zookeeper安装包并解压1.2 添加环境变量1.3 修改默认配置1.4 新建数据存储目录和日志目录1.5 启动Zookeeper1.6 停止Zookeeper 2 搭建Zookeeper集群2.1 新建集群目录2.2 配置环境变量2.3 创建节点目录2.4 修改配置2.5 创建节点ID…...

QT(18):QString

目录 QStringQTypedArrayDataQTypedArrayDataQLatin1StringQStringLiteral乱码 QStringRef QString QString 存储16位QChar的字符串&#xff0c;其中每个QChar对应一个 UTF-16代码单元。QString 使用&#xff08;写入时复制copy-on-write&#xff09;来减少内存使用并避免不必…...

宏工科技通过CMMI三级认证,软件研发能力获国际权威认可

近日&#xff0c;宏工科技子公司湖南宏工软件成功通过CMMI三级认证并正式获得资质证书&#xff0c;斩获全球软件领域最权威的认证之一&#xff0c;标志着宏工科技在软件技术开发、研发管理、项目管理等多方面获得国际权威认证。 CMMI全称是Capability Maturity Model Integrati…...

2次MD5加密——用于分布式对话

用户端 &#xff1a; 指发起请求并与服务器进行交互的终端设备或应用程序。它可以是电脑、智能手机等。 用户端负责发送请求给服务端&#xff0c;并接收和处理服务端返回的响应。 服务端 &#xff1a; 是指提供服务、接收和处理用户端请求的计算机系统或应用程序。 它监听来自用…...

用Java制作简易版的王者荣耀

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 创建类 GameFrame 运行类 package com.sxt;import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import j…...

android 保活的一种有效的方法

android 保活的一种有效的方法 为什么要保活 说起程序的保活&#xff0c;其实很多人都觉得&#xff0c;要在手机上进行保活&#xff0c;确实是想做一些小动作&#xff0c;其实有些正常的场景也是需要我们进行保活的&#xff0c;这样可以增强我们的用户体验。保活就是使得程序…...

kibana安装

kibana安装下载注意事项 地址&#xff1a;curl -O https://artifacts.elastic.co/downloads/kibana/kibana-7.16.3-linux-x86_64.tar.gz 下载后直接解压启动即可 1. 但需要使用非root用户启动 &#xff0c;root用户启动会报错 2. kibana需要和elasticsearch版本一致 不然…...

LV.12 D19 ADC实验 学习笔记

一、ADC简介 1.1 ADC ADC(Analog to Digital Converter)即模数转换器&#xff0c;指一个能将模拟信号转化为数字信号的电子元件 1.2 ADC主要参数 分辨率 ADC的分辨率一般以输出二进制数的位数来表示&#xff0c;当最大输入电压一定时&#xff0c;位数越高&#xff0c…...

ubuntu配置免密登录vscode

1、配置免密登录 &#xff08;1&#xff09;在windows系统cmd下运行命令 ssh-keygen 一路回车&#xff0c;将会在C:\Users\用户名\.ssh目录下生成两个文件&#xff1a;id_rsa和id_rsa.pub。如下图所示。 &#xff08;2&#xff09;进入.ssh目录。如果想使用root用户&#xff0…...

软件工程--面向对象分析用通俗语言20小时爆肝总结!(包含用例图、活动图、类图、时序图......)

面向对象方法分为面向对象分析&#xff08;OOA&#xff09;、面向对象设计&#xff08;OOD&#xff09;、面向对象编程&#xff08;OOP&#xff09;&#xff0c;本文详细介绍面向对象分析 本文参考教材&#xff1a;沈备军老师的《软件工程原理》大多图片来源其中 目录 面向对…...

HarmonyOS—ArkTS中@Observed和@ObjectLink装饰器的嵌套类对象属性变化【鸿蒙专栏-11】

文章目录 ARKTS中@Observed和@ObjectLink装饰器的嵌套类对象属性变化@Observed 类装饰器说明装饰器参数类装饰器的使用@ObjectLink 变量装饰器说明装饰器参数同步类型允许装饰的变量类型被装饰变量的初始值举例装饰器的限制条件观察变化和行为表现观察的变化框架行为使用场景1.…...

网络通信安全的坚固防线双向认证技术详解

目录 什么是双向认证 双向认证的工作原理 双向认证的实现方式 双向认证的重要性 双向认证的挑战 安全最佳实践 小结 什么是双向认证 双向认证&#xff0c;又称为双向身份验证或双向鉴别&#xff0c;是一种在通信双方之间建立信任关系的安全机制。在通信过程中&#xff0…...

Appium+python+unittest搭建UI自动化框架

阅读本小节&#xff0c;需要读者具备如下前提条件&#xff1a; 1. 掌握一种编程语言基础&#xff0c;如java、python等。 2. 掌握一种单元测试框架&#xff0c;如java语言的testng框架、python的unittest框架。 3. 掌握目前主流的UI测试框架&#xff0c;移动端APP测试框架…...

使用paddledetection的记录

首先在这里使用的是是paddle--detection2.7的版本。 成功进行训练 目录&#xff1a; 目录 数据集准备 配置文件的修改 使用的是BML的平台工具&#xff1a; !python -m pip install paddlepaddle-gpu2.5 -i https://mirror.baidu.com/pypi/simple --user %cd /home/aistudio…...

MySQL数据库的备份与恢复

在管理MySQL数据库时&#xff0c;备份和恢复是保证数据安全和完整性的关键环节。本文将指导您如何有效地备份MySQL数据库&#xff0c;并在需要时进行数据恢复。 请注意&#xff0c;如果没有 mysql> 的标志&#xff0c;说明我们是在外面终端进行的操作 创建备份文件路径 在…...

Pycharm配置jupyter使用notebook详细指南(可换行conda环节)

本教程为事后记录&#xff0c;部分图片非实操图片。 详细记录了pycharm配置jupyter的方法&#xff0c;jupyter添加其他conda环境的方法&#xff0c;远程密码调用jupyter的方法&#xff0c;修改jupyter工作目录的方法。 文章目录 一、入门级配置1. Pycharm配置Conda自带的jupyt…...

企业微信ipad版,http协议接口发开,获取客户群列表

版本介绍&#xff1a; HTTP协议接口可以通过该接口实现企业微信的各种功能&#xff0c;使用HTTP协议可以避免使用hook形式的需要开启PC客户端的方式&#xff0c;同时可以实现三端同时在线&#xff0c;不影响PC和手机端的登录状态&#xff0c;调用简单&#xff0c;可以支持几千…...

Double 4 VR智能互动教学系统在小语种课堂中的教学应用

小语种课堂一直是教育领域的一个难点。由于语言本身的复杂性和文化背景的差异&#xff0c;小语种教学一直是一个挑战。传统的课堂教学方法往往难以激发学生的学习兴趣和动力&#xff0c;教学效果不尽如人意。而Double 4 VR智能互动教学系统为小语种课堂带来了新的可能。 Double…...

OSEK OS任务调度的底层逻辑

先参考 FreeRTOS的任务触发底层逻辑 简述RTOS任务调度底层逻辑 AUTOSAR-OS的调度机制-调度表&#xff08;没理解透&#xff0c;继续更新&#xff09; OSEK与FreeRTOS在任务调度上最大的区别在于&#xff0c;FreeRTOS是基于全抢占任务调度和时间片轮转调度机制&#xff0c;具有…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...

node.js的初步学习

那什么是node.js呢&#xff1f; 和JavaScript又是什么关系呢&#xff1f; node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说&#xff0c; 需要在node.js的环境上进行当JavaScript作为前端开发语言来说&#xff0c;需要在浏览器的环境上进行 Node.js 可…...