STM32網絡通訊之CubeMX實現LWIP項目設計(十五)

STM32F407 系列文章 - ETH-LWIP-CubeMX(十五)


目錄

前言

一、軟件設計

二、CubeMX實現

1.配置前準備

2.CubeMX配置

1.ETH模塊配置

2.時鐘模塊配置

3.中斷模塊配置

4.RCC及SYS配置

5.LWIP模塊配置

3.生成代碼

1.main文件

2.用戶層源文件

3.用戶層頭文件

4.效果演示

總結


前言

一般對于許多嵌入式系統或單片機,在其資源受限的環境下,要想實現網絡通訊,并保證資源的高效利用和穩定的網絡通信,我們一般采用一種輕量級的網絡協議lwIP。TI公司的STM32芯片一般都會自帶一路以太網口,用于網絡通訊,但因其內存資源受限,所以都用采用一種小型化、輕量級的lwIP網絡協議,只需十幾KB的RAM和大約40K的ROM即可運行,既可以在無操作系統環境下工作,也可以與各種操作系統配合使用,使其成為資源受限的嵌入式系統的理想選擇。一般市場上所賣的板子都帶這一功能的,需準備STM32F407開發板一塊和網線一根。


一、軟件設計

前面上一篇博文STM32之LWIP網絡通訊設計介紹(十四)-CSDN博客講述了對STM32實現LWIP網絡通訊的前提性要求介紹,包含使用到的網絡協議、MAC內核、PHY驅動芯片、通訊連接示意圖、以及硬件電路原理設計圖,為網絡通訊軟件開發提供了設計指導。今天將完成STM32網絡通訊的軟件設計,采用通過可視化工具STM32CubeMX完成對lwIP通訊的配置,一鍵化生成工程代碼,這是博主比較推薦的一種方法,簡便快捷。

二、CubeMX實現

?STM32CubeMX是一個圖形化配置工具,主要用于配置STM32微控制器和微處理器。它通過直觀的圖形用戶界面,幫助用戶選擇STM32 MCU型號、配置引腳、設置系統時鐘和外設參數,并生成相應的初始化C代碼。這里對CubeMX可視化工具不做詳細的介紹,改天會專門寫篇文章介紹它。

1.配置前準備

在進行可視化工具CubeMX設置前,需要先了解處理器網絡通訊的電路圖實現,主要是了解到處理器使用到的IO引腳以及網絡驅動芯片,根據上一篇文章介紹網絡通訊設計-上(十四)(有提供stm32f407手冊數據和YT8512C驅動芯片數據),線連接到處理器的IO引腳PC4、PC5、PG13、PG14、PG11、PC1、PA2、PA7、PD3,如下圖所示。

2.CubeMX配置

打開CubeMX工具,如下所示。

1.ETH模塊配置

上圖,在右邊Pinout View上面,根據電氣原理圖設置stm32相關IO引腳,如上圖所示,設置完相關引腳后在上圖左邊ETH項,打開可以看到配置的相關引腳PC4、PC5、PG13、PG14、PG11、PC1、PA2、PA7、PD3如下所示。

在上圖上,我們選擇網絡模式為RMII,根據YT8512C驅動芯片數據手冊,MAC地址、PHY地址、PHY狀態寄存器地址、PHY速度、PHY雙工狀態、以及PHY相關參數設置如下。

需要注意的是,在PHY使用型號上,我們也可以使用常見LAN8472芯片,選擇它后,cube自動會幫你配置參數,不像自定義user PHY需要自己配置。

并使能Eth中斷配置,如下。

根據電氣設計圖,設置處理器IO引腳PD3為ETH復位引腳,如下所示。

2.時鐘模塊配置

根據圖紙參數,外部時鐘為8MHz,處理器最高位168MHz,完成相關設置如下。

3.中斷模塊配置

4.RCC及SYS配置

5.LWIP模塊配置

最后,別忘記使能LWIP模塊,完成對其配置,打開第三方插件Middleware,勾選LWIP,里面可以看到LWIP使用的版本號,并完成LWIP的地址、掩碼、TCP、BUF等參數的設置,如下所示。

下圖中key Options參數在生成的lwipopts.h文件上可以看到。

提一句,CubeMX這里面用的LWIP跟外部官網上是一樣,因為其開源免費的特性,CubeMX直接將其內嵌在軟件里面使用。

在第三方插件Middleware界面上,還可以看到FATFS通用文件系統設置、以及freeRTOS線程設置等等,說明使用CubeMX可視化工具,很方便、功能也挺多。

3.生成代碼

上面完成配置引腳、設置系統時鐘、以及外設參數設置后,點擊GENERATE CODE直接生成代碼和工程文件,在保存的路徑上面查看。

??

打開工程,查看代碼如下。

1.main文件

這里將完成相關GPIO引腳、LWIP、定時器初始化配置,首先重置所有外圍設備,初始化Flash接口和Systick,配置系統時鐘,初始化所有已配置的外圍設備;然后初始化用戶UDP網絡設置、和用戶參數,并啟動1毫秒定時器;最后進入主循環,處理網絡上的數據,主要為MX_LWIP_Process()函數和UDP_Data_Process()函數完成,其中MX_LWIP_Process函數為CubeMX工具生成的函數,主要作用為處理網絡上接收到的數據,傳遞給注冊的接收回調函數UDP_Receive_Callback解析處理。代碼示例如下。

/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2025 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under Ultimate Liberty license* SLA0044, the "License"; You may not use this file except in compliance with* the License. You may obtain a copy of the License at:*                             www.st.com/SLA0044********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "lwip.h"
#include "tim.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
#include "eth_user.h"
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/*** @brief  The application entry point.* @retval int*/
int main(void)
{/* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the system clock */SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM6_Init();MX_LWIP_Init();MX_TIM7_Init();User_UDP_Init();HAL_TIM_Base_Start_IT(&htim6); // 啟動1ms定時器/* Infinite loop */while (1){Delay_us(100);MX_LWIP_Process();UDP_Data_Process();}
}
/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 8;RCC_OscInitStruct.PLL.PLLN = 320;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){Error_Handler();}HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_4);
}

2.用戶層源文件

這里將完成網絡用戶層設置,主要為網絡IP初始化設置、以及網絡收發數控制,代碼示例如下。

#include "eth_user.h"
#include "stm32f4xx_hal.h"
#include "lwip.h"
#include "lwip/igmp.h"#define UDP_PORT     8888 		  // 網絡端口
static struct udp_pcb *upcb;    // UDP通訊的控制塊對象
static DeviceStatus SendUDPSt;	// UDP通道的通訊狀態
UDP_Message RecvUDPMes;
UDP_Message AckUDPMes;
UDP_Message SendUDPMes;
/******************************************************************************* 描述  : 初始化UDP所用的相關數據對象* 參數  : 無* 返回  : 無
******************************************************************************/
void UDP_Data_Init(void)
{memset(&RecvUDPMes, 0, sizeof(UDP_Message));memset(&AckUDPMes, 0, sizeof(UDP_Message));memset(&SendUDPMes, 0, sizeof(UDP_Message));memset(&SendUDPSt, 0, sizeof(DeviceStatus));SendUDPSt.ID = 0x10;
}
/******************************************************************************* 描述  : 接收回調函數編寫* 參數  : upcb UDP協議控制塊*         p 收到的數據包緩沖區*         addr 接收數據包的遠程IP地址 *         port 接收數據包的遠程端口* 返回  : 無
******************************************************************************/
static void UDP_Receive_Callback(void *arg, struct udp_pcb *upcb,struct pbuf *p, const ip_addr_t *addr, u16_t port)
{uint8_t udprecvbuf[MAX_UDP_FRAME_LEN] = {0};struct pbuf *ptmp = p;uint32_t data_len = 0;if(upcb != NULL && p != NULL){ip_addr_t remote_source_ip;IP4_ADDR(&remote_source_ip, 192,168,1,113);		if((port == UDP_PORT) && ((addr->addr) == remote_source_ip.addr)) //判斷地址和端口從哪里來的{for (ptmp = p; ptmp != NULL; ptmp = ptmp->next)	 //遍歷完整個buf鏈表{				//判斷要拷貝到buf中的數據是否大于UDP_DEMO_RX_BUFSIZE的剩余空間,//如果大于的話就只拷貝剩余長度的數據,否則的話就拷貝所有的數據if (ptmp->len <= (MAX_UDP_FRAME_LEN - data_len)){					memcpy(udprecvbuf + data_len, ptmp->payload, ptmp->len);data_len += ptmp->len;}else{					memcpy(udprecvbuf + data_len, ptmp->payload, (MAX_UDP_FRAME_LEN - data_len)); //拷貝數據data_len = MAX_UDP_FRAME_LEN;}//超出UDP最大數據包,則跳出循環if (data_len > MAX_UDP_FRAME_LEN){				break; }}// 初步處理memcpy(&AckUDPMes, udprecvbuf, data_len);SendUDPSt.LastRecvTime = g_1msTick;SendUDPSt.ComSt = COM_ST_PENDING;if(*((uint32_t*)udprecvbuf) != UDP_FRAME_HEAD) { // 同步頭校驗AckUDPMes.AnsResult = ACK_HEAD_ERROR;}else if(AckUDPMes.Len != (data_len-4)) { // 幀長度校驗AckUDPMes.AnsResult = ACK_LEN_ERROR;}else if(RecvUDPMes.CRC16 != CRC16_Calculate((uint8_t*)&RecvUDPMes.SN, RecvUDPMes.Len-4)) { // CRC校驗AckUDPMes.AnsResult = ACK_CRC_ERROR;}else SendUDPSt.ComSt = COM_ST_INIT;}}pbuf_free(p); // 釋放內存
}/******************************************************************************* 描述  : 創建udp客戶端* 參數  : 無* 返回  : 無
******************************************************************************/
void User_UDP_Init(void)
{ip_addr_t local_ip;ip_addr_t remote_ip;err_t err;/* 初始化UDP數據消息 */UDP_Data_Init();// 組播配置//IP4_ADDR(&local_ip, 224,1,1,201);   //配置本地接收組播的地址//IP4_ADDR(&remote_ip, 224,1,1,113);//獨播IP4_ADDR(&local_ip, 192,168,1,201);IP4_ADDR(&remote_ip, 192,168,1,113);upcb = udp_new();  // 創建udp控制塊if (upcb!=NULL){	upcb->local_port = UDP_PORT;           // 配置本地端口upcb->local_ip.addr = local_ip.addr;   // 配置本地地址upcb->remote_port = UDP_PORT;          // 綁定遠程端口upcb->remote_ip.addr = remote_ip.addr; // 綁定遠程地址//加入組播//err= igmp_joingroup(IP_ADDR_ANY,&local_ip); //只需要將接收地址放入igmp組,發送的不需要//連接遠程服務器IP和端口err= udp_connect(upcb, &remote_ip, UDP_PORT);if(err == ERR_OK){err = udp_bind(upcb,&local_ip,UDP_PORT); //只能收到綁定的本地接收ip地址和端口的數據//err = udp_bind(upcb,IP_ADDR_ANY,UDP_LOCAL_PORT); //可以收到固定端口上任意ip地址的數// 注冊接收回調函數,只要接收到數據,這個回調函數會被lwip內核調用udp_recv(upcb, UDP_Receive_Callback, NULL);  // 函數初始化時注冊-接收回調函數	}else{//離開組播地址//igmp_leavegroup(IP_ADDR_ANY,&local_ip);// 斷開UDP連接udp_remove(upcb);}}
}/******************************************************************************* 描述  : 發送數據* 參數  : (in)pData 發送數據的指針* 返回  : 無
******************************************************************************/
int8_t UDP_Send_Data(struct udp_pcb *upcb, uint8_t *pData, uint16_t len)
{struct pbuf *p;int8_t ret = ERR_BUF;if (upcb != NULL && pData != NULL && len > 0){/* 分配緩沖區空間 */p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL);if(p != NULL){/* 填充緩沖區數據 */ret = pbuf_take(p, pData, len);if(ret == ERR_OK){/* 發送udp數據 */ret = udp_send(upcb, p);}			/* 釋放緩沖區空間 */pbuf_free(p);}}return ret;
}// 處理單項控制命令
CMD_Ack UDP_Single_Ctrl(UDP_Message msg)
{CMD_Ack ret = ACK_OK;if((uint8_t*)&msg != NULL){switch(msg.Param2){case 0:break;case 1:break;case 2:break;default:break;}}else{ret = ACK_ERROR;}return ret;	
}/******************************************************************************* 描述  : 將接收到的UDP數據包解析處理* 參數  : 無* 返回  : 無
******************************************************************************/
void UDP_Msgs_Process(void)
{if(SendUDPSt.ComSt == COM_ST_INIT) {AckUDPMes.AnsResult = UDP_Single_Ctrl(RecvUDPMes);SendUDPSt.ComSt = COM_ST_TRANS;}
}/******************************************************************************
* 描述  : 向以太網上發送UDP數據包* 參數  : 無* 返回  : 無
******************************************************************************/
void UDP_Send_Msgs(void)
{static uint32_t lastime = 0;/* deal ack data */if(SendUDPSt.ComSt != COM_ST_STOP) {AckUDPMes.Head = UDP_FRAME_HEAD;AckUDPMes.Len = UDP_MSG_LEN;AckUDPMes.CRC16 = CRC16_Calculate((uint8_t*)&AckUDPMes.SN, AckUDPMes.Len-4);UDP_Send_Data(upcb, (uint8_t*)&AckUDPMes, UDP_FULL_FRAM_LEN(AckUDPMes.Len));SendUDPSt.ComSt = COM_ST_STOP;memset(&AckUDPMes, 0, sizeof(UDP_Message));}/*d eal heartbeat data */if(g_1msTick - lastime > 1000) {lastime = g_1msTick;SendUDPMes.Head = UDP_FRAME_HEAD;SendUDPMes.Len = UDP_MSG_LEN + 2;SendUDPMes.SN += 1;SendUDPMes.Param1 = SUB_CMD_KEEPALIVE;SendUDPMes.Param2 = RUN_IDLE;SendUDPMes.AnsResult = ACK_PENDING;SendUDPMes.Data[0] = 0xff;SendUDPMes.Data[1] = 0xff;SendUDPMes.CRC16 = CRC16_Calculate((uint8_t*)&SendUDPMes.SN, SendUDPMes.Len-4);UDP_Send_Data(upcb, (uint8_t*)&SendUDPMes, UDP_FULL_FRAM_LEN(SendUDPMes.Len));}
}/******************************************************************************* 描述  : UDP處理流程(處理現有消息,調度發送隊列)* 參數  : 無* 返回  : 無
******************************************************************************/
void UDP_Data_Process(void)
{UDP_Msgs_Process();UDP_Send_Msgs();
}

3.用戶層頭文件

#ifndef __UDP_USER_H
#define __UDP_USER_H#ifdef __cplusplusextern "C" {
#endif#include "stdint.h"
#include "string.h"
#include "crc.h"
#include "udp.h"
#include "timer.h"
#define MAX_UDP_BUF_SIZE 1000
typedef struct 
{uint32_t Head;      // 同步頭uint16_t Len;       // 整幀長度(UDP_MSG_LEN+Data長度)uint16_t CRC16;     // CRC校驗結果(UDP_MSG_LEN-4+Data長度的數據)uint16_t SN;        // 幀序號uint32_t Param1;    // 參數1uint32_t Param2;    // 參數2uint32_t AnsResult; // 應答結果uint8_t Data[MAX_UDP_BUF_SIZE]; // 數據內容(不能超過1024字節)
}__attribute__((packed)) UDP_Message;#define UDP_FRAME_HEAD 0xC3A53C5A				// 幀頭
#define UDP_MSG_LEN 22				          // 幀頭長度
#define UDP_FULL_FRAM_LEN(msgLen) ((msgLen)+4)	// 幀頭+整幀長度
#define MAX_UDP_FRAME_LEN (4+UDP_MSG_LEN+MAX_UDP_BUF_SIZE)//sizeof(UDP_Message) UDP最大幀長度typedef enum
{ACK_PENDING = 0,        // 等待反饋ACK_OK = 0x10,          // 命令執行結束,且結果正常ACK_ERROR = 0x11,       // 命令執行過程發生異常ACK_WARNING = 0x12,     // 命令執行結束,但結果異常ACK_HEAD_ERROR = 0x20,   // Head校驗錯誤ACK_CRC_ERROR  = 0x21,   // CRC校驗錯誤ACK_LEN_ERROR  = 0x22,   // 長度校驗錯誤ACK_CMD_INVALID = 0x23,  // 命令參數錯誤,無法執行ACK_RUNNING = 0x22,     // 有其他命令正在執行
}CMD_Ack; // 回應類型}Sub_CMD_Type;typedef enum
{RUN_IDLE 		  = 0x01,			// 空閑RUN_TEST_CTRL	= 0x02,			// 測試RUN_BURN_IN	  = 0x03,		  // 老煉RUN_UPGRADE		= 0x04			// 在線升級
}RunningStType;   // 軟件運行狀態類型typedef enum
{COM_ST_UNKNOWN 	= 0x00,		// 未知COM_ST_PENDING 	= 0x01,		// 等待回應COM_ST_INIT 	  = 0x02,		// 初步OKCOM_ST_TRANS 	  = 0x03,		// 可傳輸COM_ST_STOP	 	  = 0x04		// 已停止
}DeviceComStatus; // 設備通訊狀態標識void User_UDP_Init(void);
int8_t UDP_Send_Data(struct udp_pcb *upcb, uint8_t *pData, uint16_t len);
void UDP_Msgs_Process(void);
void UDP_Send_Msgs(void);
void UDP_Data_Process(void);
#ifdef __cplusplus
}
#endif#endif

4.效果演示

編寫完用戶代碼后,進行編譯運行,連接仿真器在線調式、或者直接燒寫到板子中,打開網絡監控助手,效果如下。


總結

下面提供的代碼,基于STM32F407ZGT芯片編寫,可直接在原子開發板上運行,也可運行在各工程項目上,但需要注意各接口以及相應的引腳應和原子開發板上保持一致。

相應的代碼鏈接:單片機STM32F407-Case程序代碼例程-CSDN文庫

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66230.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66230.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66230.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單組合邏輯

多路選擇器 在多路數據傳輸過程中&#xff0c;能夠將任意一路選出來的電路叫做數據選擇器&#xff0c;也稱多路選擇器。對于一個具有2^n個輸入和一個輸出的多路選擇器&#xff0c;有n個選擇變量&#xff0c;多路選擇器也是FPGA內部的一個基本資源&#xff0c;主要用于內部信號的…

【Unity-Game4Automation PRO 插件】

Game4Automation PRO 插件 是一個用于 Unity 引擎 的工業自動化仿真工具&#xff0c;它提供了對工業自動化領域的仿真和虛擬調試支持&#xff0c;特別是在與工業機器人、生產線、PLC 系統的集成方面。該插件旨在將工業自動化的實時仿真與游戲開發的高質量 3D 可視化能力結合起來…

【安卓開發】【Android】總結:安卓技能樹

【持續更新】 對筆者在安卓開發的實踐中認為必要的知識點和遇到的問題進行總結。 一、基礎知識部分 1、Android Studio軟件使用 軟件界面 最新的版本是瓢蟲&#xff08;Ladybug&#xff09;&#xff0c;bug的確挺多。筆者更習慣使用電鰻&#xff08;Electric Eel&#xff0…

鴻蒙打包發布

HarmonyOS應用/元服務發布&#xff08;打包發布&#xff09; https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/ide-publish-app-V13?catalogVersionV13 密鑰&#xff1a;包含非對稱加密中使用的公鑰和私鑰&#xff0c;存儲在密鑰庫文件中&#xff0c;格式…

Spring Boot 下的Swagger 3.0 與 Swagger 2.0 的詳細對比

先說結論&#xff1a; Swgger 3.0 與Swagger 2.0 區別很大&#xff0c;Swagger3.0用了最新的注釋實現更強大的功能&#xff0c;同時使得代碼更優雅。 就個人而言&#xff0c;如果新項目推薦使用Swgger 3.0&#xff0c;對于工具而言新的一定比舊的好&#xff1b;對接于舊項目原…

神經網絡基礎-價格分類案例

文章目錄 1. 需求分析2. 導入所需工具包3. 構建數據集4. 構建分類網絡模型5. 訓練模型6. 模型訓練7. 評估模型8. 模型優化 學習目標&#xff1a; 掌握構建分類模型流程動手實踐整個過程 1. 需求分析 小明創辦了一家手機公司&#xff0c;他不知道如何估算手機產品的價格。為了…

SAP 固定資產常用的數據表有哪些,他們是怎么記錄數據的?

在SAP系統中&#xff0c;固定資產管理&#xff08;FI-AA&#xff09;涉及多個核心數據表&#xff0c;用于記錄資產主數據、折舊、交易等。以下是常用的數據表及其記錄數據的邏輯&#xff1a; 1. ANKT - 資產主數據表 功能&#xff1a;存儲資產主數據的文本描述。 字段&#x…

光伏儲能電解水制氫仿真模型Matlab/Simulink

今天更新的內容為光伏儲能制氫技術&#xff0c;這個方向我之前在21年就系統研究并發表過相關文章&#xff0c;經過這幾年的發展&#xff0c;綠色制氫技術也受到更多高校的注意&#xff0c;本篇博客也是在原先文章的基礎上進行更新。 首先讓大家熟悉一下綠氫制取技術這個概念&a…

Redis 3.2.1在Win10系統上的安裝教程

諸神緘默不語-個人CSDN博文目錄 這個文件可以跟我要&#xff0c;也可以從官網下載&#xff1a;https://github.com/MicrosoftArchive/redis/releases 這個是微軟以前維護的Windows版Redis安裝包&#xff0c;如果想要比較新的版本可以從別人維護的項目里下&#xff08;https://…

基于springboot+vue.js+uniapp技術開發的一套大型企業MES生產管理系統源碼,支持多端管理

企業級智能制造MES系統源碼&#xff0c;技術架構&#xff1a;springboot vue-element-plus-admin 企業級云MES全套源碼&#xff0c;支持app、小程序、H5、臺后管理端 MES指的是制造企業生產過程執行系統&#xff0c;是一套面向制造企業車間執行層的生產信息化管理系統。MES系…

【Redis】Redis事務和Lua腳本的區別

Redis事務 概念 事務&#xff1a;Redis事務是一組命令的集合&#xff0c;這些命令會被序列化地執行&#xff0c;中間不會被其他命令插入。 MULTI/EXEC&#xff1a;Redis事務通過MULTI命令開始&#xff0c;通過EXEC命令執行所有已入隊的命令。 特點 原子性&#xff1a; 事務…

frameworks 之 AMS與ActivityThread交互

frameworks 之 AMS與ActivityThread交互 1. 類關系2. 流程2.1 AMS流程2.1 ActivityThread流程 3. 堆棧 講解AMS 如何和 ActivityThread 生命周期調用流程 涉及到的類如下 frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.javaframeworks/base/cor…

Jmeter 簡單使用、生成測試報告(一)

一、下載Jmter 去官網下載&#xff0c;我下載的是apache-jmeter-5.6.3.zip&#xff0c;解壓后就能用。 二、安裝java環境 JMeter是基于Java開發的&#xff0c;運行JMeter需要Java環境。 1.下載JDK、安裝Jdk 2.配置java環境變量 3.驗證安裝是否成功&#xff08;java -versio…

如何使用淘寶URL采集商品詳情數據及銷量

一、通過淘寶開放平臺&#xff08;如果有資質&#xff09; 注冊成為淘寶開發者 訪問淘寶開放平臺官方網站&#xff0c;按照要求填寫開發者信息&#xff0c;包括企業或個人身份驗證等步驟。這一步是為了獲取合法的 API 使用權限。 了解商品詳情 API 淘寶開放平臺提供了一系列…

Unity3D中的Lua、ILRuntime與HybridCLR/huatuo熱更對比分析詳解

前言 在游戲開發中&#xff0c;熱更新技術是一項重要的功能&#xff0c;它允許開發者在不重新發布游戲客戶端的情況下&#xff0c;更新游戲內容。Unity3D作為廣泛使用的游戲引擎&#xff0c;支持多種熱更新方案&#xff0c;包括Lua、ILRuntime和HybridCLR/huatuo。本文將詳細介…

QT加載Ui文件信息方法(python)

在 PyQt 或 PySide 中&#xff0c;加載 Qt Designer 生成的 .ui 文件有兩種常見方法&#xff1a; 使用 pyuic 將 .ui 文件轉換為 Python 代碼。動態加載 .ui 文件。 以下是兩種方法的詳細說明和示例代碼。 方法 1&#xff1a;使用 pyuic 將 .ui 文件轉換為 Python 代碼 步驟…

javascript基礎從小白到高手系列一十二:JSON

本章內容 ? 理解JSON 語法 ? 解析JSON ? JSON 序列化 正如上一章所說&#xff0c;XML 曾經一度成為互聯網上傳輸數據的事實標準。第一代Web 服務很大程度上 是以XML 為基礎的&#xff0c;以服務器間通信為主要特征。可是&#xff0c;XML 也并非沒有批評者。有的人認為XML 過…

網絡編程 - - TCP套接字通信及編程實現

概述 TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;是一種面向連接的、可靠的傳輸層協議。在網絡編程中&#xff0c;TCP常用于實現客戶端和服務器之間的可靠數據傳輸。本文將基于C語言實現TCP服務端和客戶端建立通信的過程。 三次握手 在…

2023-2024 學年 廣東省職業院校技能大賽(高職組)“信息安全管理與評估”賽題一

2023-2024 學年 廣東省職業院校技能大賽(高職組“信息安全管理與評估”賽題一&#xff09; 模塊一:網絡平臺搭建與設備安全防護第一階段任務書任務 1&#xff1a;網絡平臺搭建任務 2&#xff1a;網絡安全設備配置與防護DCRS:DCFW:DCWS:DCBC:WAF: 模塊二&#xff1a;網絡安全事件…

thinkphp6 + redis實現大數據導出excel超時或內存溢出問題解決方案

redis下載安裝&#xff08;window版本&#xff09; 參考地址&#xff1a;https://blog.csdn.net/Ci1693840306/article/details/144214215 php安裝redis擴展 參考鏈接&#xff1a;https://blog.csdn.net/jianchenn/article/details/106144313 解決思路&#xff1a;&#xff0…