APM32芯得 EP.29 | 基于APM32F103的USB鍵盤與虛擬串口復合設備配置詳解

如遇開發技術問題,歡迎前往開發者社區,極海技術團隊將在線為您解答~
極海官方開發者社區?https://community.geehy.cn/

《APM32芯得》系列內容為用戶使用APM32系列產品的經驗總結,均轉載自21ic論壇極海半導體專區,全文未作任何修改,未經原文作者授權禁止轉載。

目錄

1、USB設備描述符

2、USB配置描述符

3、USB HID報告描述符

4、修改端點緩存地址


? ? 最近在編寫DMA_ADC例程的過程中出現了一個中斷配置的問題,在ADC采集過程中,結合手冊進行ADC連續轉換模式配置采集,手冊上給出需要進行中斷配置的信息,但是真實情況不需要進行中斷配置也可以進行ADC連續轉換采集,因此,我沒過濾掉ADC采集中開啟中斷配置的信息,開啟了ADC中斷采集,因此這次以APM32F411官方例程中的DMA_ADC例程,復刻了此次出現的問題。

APM32F103具有USB全速接口,可以做USB從機的多種功能。USB協議中為了提供對多樣設備的支持,定義了許多外部設備子類,常見的包括:

  • 人機交互類設備HID(Human Interface Device)

  • 通信類設備CDC(Communicate Device Class)

  • 大容量存儲設備MSC(Mass Storage Class)

  • 視頻類設備UVC(USB Video Class)

  • 音頻類設備UAC(USB Audio Class)

HID (Human Interface Device)?是一種用于連接人機交互設備的USB設備類別。它定義了一組通用的協議和規范,用于支持鍵盤、鼠標、游戲控制器等各種輸入設備的連接和交互。

CDC(Communication Device Class)是USB組織定義的一類專門給各種通信設備(電信通信設備和中速網絡通訊設備)使用的USB子類,常用于虛擬串口。

USB大容量存儲設備類(The USB mass storage device class)是一種計算機和移動設備之間的傳輸協議,它允許一個通用串行總線(USB)設備來訪問主機的計算設備,使兩者之間進行文件傳輸,常用于存儲器讀寫和模擬U盤。

SDK中提供的例程就有虛擬串口CDC、鼠標HID、模擬U盤MSC的功能。

除了這些USB做單項功能的,USB還可以配置復合設備,能同時集成了多個不同類型的外設,可以實現多個功能的同時使用

接下來就嘗試在極海SDK中增加HID KeyBoard+CDC 虛擬串口的復合設備配置,修改就基于極海APM32F10x_SDK_V1.8中已有的USB_CDC_VirtualCOMPort例程,就不用重新配置虛擬串口部分了。

實現要對USB的描述符進行修改,能讓電腦識別出來是個什么設備。

1、USB設備描述符

重點是bDeviceClass改成0xEF,告訴電腦這是個復合設備。

const uint8_t g_usbDeviceDescriptor[USB_DEVICE_DESCRIPTOR_SIZE] ={0x12, ?/*bLength:長度,設備描述符的長度為18字節*/USBD_DESC_DEVICE, /*bDescriptorType*/0x00,0x02, ? ? ? ? ? ? ? ? ? ? /*bcdUSB = 2.00 */0xEF, ? ? ? ? ? ? ? ? ? ? ? /*bDeviceClass*/0x02, ? ? ? ? ? ? ? ? ? ? ? /*bDeviceSubClass*/0x01, ? ? ? ? ? ? ? ? ? ? ? /*bDeviceProtocol*/0x40, ? ? ? ? ? ? ? ? ? ? ? /*bMaxPacketSize40---------------------------*/0x83,0x05, ? ? ? ? ? ? ? ? ?/*idVendor (0x0583)*/0x50,0x57, ? ? ? ? ? ? ? ? ?/*idProduct = 0x5750*/0x00, ? ? ? ? ? ? ? ? ? ? ? /*bcdDevice rel. 2.00*/0x02,1, ? ? ? ? ? ? ? ? ? ? ? ? ?/*Index of string descriptor describingmanufacturer */2, ? ? ? ? ? ? ? ? ? ? ? ? ?/*Index of string descriptor describingproduct*/3, ? ? ? ? ? ? ? ? ? ? ? ? ?/*Index of string descriptor describing thedevice serial number */0x01 ? ? ? ? ? ? ? ? ? ? ? ?/*bNumConfigurations*/};

2、USB配置描述符

這里配置USB的配置描述符、接口描述符和端點描述符。

HID鍵盤使用兩個端點,端點4(IN)和端點4(OUT)

VCP虛擬串口使用三個端點,端點1(IN)、端點1(OUT)和端點2(IN)

const uint8_t g_usbConfigDescriptor[USB_CONFIG_DESCRIPTOR_SIZE] ={0x09, /* bLength: Configuration Descriptor size */USBD_DESC_CONFIGURATION, /* bDescriptorType: Configuration */USB_CONFIG_DESCRIPTOR_SIZE,/* wTotalLength: Bytes returned */0x00,0x03, ? ? ? ? /* bNumInterfaces: 1 interface */0x01, ? ? ? ? /* bConfigurationValue: Configuration value */0x00, ? ? ? ? /* iConfiguration: Index of string descriptor describingthe configuration*/0xC0, ? ? ? ? /* bmAttributes: Self powered */0x32, ? ? ? ? /* MaxPower 100 mA: this current is used for detecting Vbus *//*************************************功能1 HID鍵盤**************************************//*IAD描述符*/0x08, ? //bLength:IAD描述符大小?0x0B, ? //bDescriptorType:IAD描述符類型0x00, ? //bFirstInterface:功能1 HID鍵盤的第一個接口描述符是在總的配置描述符中的第幾個從0開始數0x01, ? //bInferfaceCount:功能1 HID鍵盤有1個接口描述符0x03, ? //bFunctionClass:同單HID功能時,設備符中的bDeviceClass0x00, ? //bFunctionSubClass:同單HID功能時,設備符中的bDeviceSubClass0x01, ? //bFunctionProtocol:同單HID功能時,設備符中的bDeviceProtocol0x00, ? //iFunction:字符串描述中關于此設備的索引(個人理解是一個字符串描述符中有比如0~5是功能1的字符串,//6~10是功能2的字符串,如果是功能2的話,此值為6)/************** Descriptor of Custom HID interface ****************//* 09 */0x09, ? ? ? ? /* bLength: Interface Descriptor size */USBD_DESC_INTERFACE,/* bDescriptorType: Interface descriptor type */0x00, ? ? ? ? /* bInterfaceNumber: Number of Interface */0x00, ? ? ? ? /* bAlternateSetting: Alternate setting */0x02, ? ? ? ? /* bNumEndpoints */0x03, ? ? ? ? /* bInterfaceClass: HID */0x01, ? ? ? ? /* bInterfaceSubClass : 1=BOOT, 0=no boot */0x01, ? ? ? ? /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */0, ? ? ? ? ? ?/* iInterface: Index of string descriptor *//******************** Descriptor of Custom HID HID ********************//* 18 */0x09, ? ? ? ? /* bLength: HID Descriptor size */0x21, /* bDescriptorType: HID */0x10, ? ? ? ? /* bcdHID: HID Class Spec release number */0x01,0x00, ? ? ? ? /* bCountryCode: Hardware target country */0x01, ? ? ? ? /* bNumDescriptors: Number of HID class descriptors to follow */0x22, ? ? ? ? /* bDescriptorType */KEYBOARD_SIZ_REPORT_DESC,//KEYBOARD_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */0x00,/******************** Descriptor of Custom HID endpoints ******************//* 27 */0x07, ? ? ? ? ?/* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT, /* bDescriptorType: */0x84, ? ? ? ? ?/* bEndpointAddress: Endpoint Address (IN) */0x03, ? ? ? ? ?/* bmAttributes: Interrupt endpoint */0x08, ? ? ? ? ?/* wMaxPacketSize: 8 Bytes max */0x00,0x20, ? ? ? ? ?/* bInterval: Polling Interval (32 ms) *//* 34 */ ? ? ? ?0x07, ? ? ? ?/* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT, ? ? ? ?/* bDescriptorType: *//* ? ? ? ?Endpoint descriptor type */0x04, ? ? ? ?/* bEndpointAddress: *//* ? ? ? ?Endpoint Address (OUT) */0x03, ? ? ? ?/* bmAttributes: Interrupt endpoint */0x01, ? ? ? ?/* wMaxPacketSize: 2 Bytes max ?*/0x00,0x20, ? ? ? ?/* bInterval: Polling Interval (20 ms) *//* 41 *//********************************功能2 VCP虛擬串口*****************************//*IAD描述符*//* Interface Association Descriptor(IAD Descriptor) ?*/?0x08, ? /* ?bLength ?*/0x0B, ? /* ?bDescriptorType*/0x01, ? /* ?bFirstInterface*/0x02, ? /* ?bInterfaceCount*/0x02, ? /* ?bFunctionClass --CDC*/0x02, ? /* ?bFunctionSubClass*/0x01, ? /* ?bFunctionProtocoll*/0x00, ? /* ?iFunction *//**VCP虛擬串口**//*Interface Descriptor接口描述符*/0x09, ? /* bLength: Interface Descriptor size */USBD_DESC_INTERFACE, ?/* bDescriptorType: Interface *//* Interface descriptor type */0x01, ? /* bInterfaceNumber: Number of Interface */ ? //<接口 1>0x00, ? /* bAlternateSetting: Alternate setting */0x01, ? /* bNumEndpoints: One endpoints used 該接口非0端點數*/0x02, ? /* bInterfaceClass: Communication Interface Class */0x02, ? /* bInterfaceSubClass: Abstract Control Model */0x01, ? /* bInterfaceProtocol: Common AT commands */0x00, ? /* iInterface: *//*Header Functional Descriptor類描述符*/0x05, ? /* bLength: Endpoint Descriptor size */0x24, ? /* bDescriptorType: CS_INTERFACE */0x00, ? /* bDescriptorSubtype: Header Func Desc */0x10, ? /* bcdCDC: spec release number */0x01,/*Call Management Functional Descriptor*/0x05, ? /* bFunctionLength */0x24, ? /* bDescriptorType: CS_INTERFACE */0x01, ? /* bDescriptorSubtype: Call Management Func Desc */0x00, ? /* bmCapabilities: D0+D1 */0x01, ? /* bDataInterface: 1 *//*ACM Functional Descriptor*/0x04, ? /* bFunctionLength */0x24, ? /* bDescriptorType: CS_INTERFACE */0x02, ? /* bDescriptorSubtype: Abstract Control Management desc */0x02, ? /* bmCapabilities *//*Union Functional Descriptor*/0x05, ? /* bFunctionLength */0x24, ? /* bDescriptorType: CS_INTERFACE */0x06, ? /* bDescriptorSubtype: Union func desc */0x00, ? /* bMasterInterface: Communication class interface */0x01, ? /* bSlaveInterface0: Data Class Interface *//*Endpoint 2 Descriptor端點描述符*/0x07, ? /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT, ? /* bDescriptorType: Endpoint */0x82, ? /* bEndpointAddress: (IN2) */0x03, ? /* bmAttributes: Interrupt */VIRTUAL_COM_PORT_INT_SIZE, ? ? ?/* wMaxPacketSize: */0x00,0xFF, ? /* bInterval: *//*Data class interface descriptor類描述符*/0x09, ? /* bLength: Endpoint Descriptor size */USBD_DESC_INTERFACE, ?/* bDescriptorType: */0x02, ? /* bInterfaceNumber: Number of Interface */0x00, ? /* bAlternateSetting: Alternate setting */0x02, ? /* bNumEndpoints: Two endpoints used */0x0A, ? /* bInterfaceClass: CDC */0x00, ? /* bInterfaceSubClass: */0x00, ? /* bInterfaceProtocol: */0x00, ? /* iInterface: *//*Endpoint 3 Descriptor端點描述符*/0x07, ? /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT, ? /* bDescriptorType: Endpoint */0x01, ? /* bEndpointAddress: (OUT1) */0x02, ? /* bmAttributes: Bulk */VIRTUAL_COM_PORT_DATA_SIZE, ? ? ? ? ? ? /* wMaxPacketSize: */0x00,0x00, ? /* bInterval: ignore for Bulk transfer *//*Endpoint 1 Descriptor 端點描述符*/0x07, ? /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT, ? /* bDescriptorType: Endpoint */0x81, ? /* bEndpointAddress: (IN1) */0x02, ? /* bmAttributes: Bulk */VIRTUAL_COM_PORT_DATA_SIZE, ? ? ? ? ? ? /* wMaxPacketSize: */0x00,0x00 ? ?/* bInterval */};

3、USB HID報告描述符

const uint8_t s_hidKeyboardReportDescriptor[HID_REPORT_DESCRIPTOR_SIZE] ={/*short Item ? D7~D4:bTag;D3~D2:bType;D1~D0:bSize**bTag ---主條目 ? ? ? ? ?1000:輸入(Input) 1001:輸出(Output) 1011:特性(Feature) ? ? ? ?1010:集合(Collection) 1100:關集合(End Collection)?** ? ? ? ? ? ? ? ? ?全局條目 ? ? ? ? 0000:用途頁(Usage Page) 0001:邏輯最小值(Logical Minimum) 0010:邏輯最大值(Logical Maximum) 0011:物理最小值(Physical Minimum)** ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0100:物理最大值(Physical Maximum) 0101:單元指數(Unit Exponet) 0110:單元(Unit) 0111:數據域大小(Report Size)** ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1000:報告ID(Report ID) 1001:數據域數量(Report Count) 1010:壓棧(Push) 1011:出棧(Pop) 1100~1111:保留(Reserved)** ? ? ? ? ? ? ? ? ?局部條目 ? ? ? ?0000:用途(Usage) 0001:用途最小值(Usage Minimum) 0010:用途最大值(Usage Maximum) 0011:標識符索引(Designator Index)** ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0100:標識符最小值(Designator Minimum) 0101:標識符最大值(Designator Maximum) 0111:字符串索引(String Index) 1000:字符串最小值(String Minimum) ??** ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1001:字符串最大值(String Maximum) 1010:分隔符(Delimiter) 其他:保留(Reserved)**bType---00:主條目(main) ?01:全局條目(globle) ?10:局部條目(local) ?11:保留(reserved)**bSize---00:0字節 ?01:1字節 ?10:2字節 ?11:4字節*///0x05:0000 01 01 這是個全局條目,用途頁選擇為普通桌面頁0x05, 0x01, // USAGE_PAGE (Generic Desktop)//0x09:0000 10 01 這是個全局條目,用途選擇為鍵盤0x09, 0x06, // USAGE (Keyboard)//0xa1:1010 00 01 這是個主條目,選擇為應用集合,0xa1, 0x01, // COLLECTION (Application)//0x05:0000 01 11 這是個全局條目,用途頁選擇為鍵盤/按鍵0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)//0x19:0001 10 01 這是個局部條目,用途的最小值為0xe0,對應鍵盤上的左ctrl鍵0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)//0x29:0010 10 01 這是個局部條目,用途的最大值為0xe7,對應鍵盤上的有GUI(WIN)鍵0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)//0x15:0001 01 01 這是個全局條目,說明數據的邏輯值最小值為00x15, 0x00, // LOGICAL_MINIMUM (0)//0x25:0010 01 01 這是個全局條目,說明數據的邏輯值最大值為10x25, 0x01, // LOGICAL_MAXIMUM (1)//0x95:1001 01 01 這是個全局條目,數據域的數量為8個0x95, 0x08, // REPORT_COUNT (8)//0x75:0111 01 01 這是個全局條目,每個數據域的長度為1位0x75, 0x01, // REPORT_SIZE (1) ? ? ? ? ??//0x81:1000 00 01 這是個主條目,有8*1bit數據域作為輸入,屬性為:Data,Var,Abs0x81, 0x02, // INPUT (Data,Var,Abs)//0x95:1001 01 01 這是個全局條目,數據域的數量為1個0x95, 0x01, // REPORT_COUNT (1)//0x75:0111 01 01 這是個全局條目,每個數據域的長度為8位0x75, 0x08, // REPORT_SIZE (8)//0x81:1000 00 01 這是個主條目,有1*8bit數據域作為輸入,屬性為:Cnst,Var,Abs0x81, 0x03, // INPUT (Cnst,Var,Abs)//0x95:1001 01 01 這是個全局條目,數據域的數量為6個0x95, 0x06, // REPORT_COUNT (6)//0x75:0111 01 01 這是個全局條目,每個數據域的長度為8位0x75, 0x08, // REPORT_SIZE (8)//0x25:0010 01 01 這是個全局條目,邏輯最大值為2550x25, 0xFF, // LOGICAL_MAXIMUM (255)//0x19:0001 10 01 這是個局部條目,用途的最小值為00x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))//0x29:0010 10 01 這是個局部條目,用途的最大值為0x650x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)//0x81:1000 00 01 這是個主條目,有6*8bit的數據域作為輸入,屬相為屬性為:Data,Var,Abs0x81, 0x00, // INPUT (Data,Ary,Abs)//0x25:0010 01 01 這是個全局條目,邏輯的最大值為10x25, 0x01, // LOGICAL_MAXIMUM (1)//0x95:1001 01 01 這是個全局條目,數據域的數量為20x95, 0x02, // REPORT_COUNT (2)//0x75:0111 01 01 這是個全局條目,每個數據域的長度為1位0x75, 0x01, // REPORT_SIZE (1)//0x05:0000 01 01 這是個全局條目,用途頁選擇為LED頁0x05, 0x08, // USAGE_PAGE (LEDs)//0x19:0001 10 01 這是個局部條目,用途的最小值為0x01,對應鍵盤上的Num Lock0x19, 0x01, // USAGE_MINIMUM (Num Lock)//0x29:0010 10 01 這是個局部條目,用途的最大值為0x02,對應鍵盤上的Caps Lock0x29, 0x02, // USAGE_MAXIMUM (Caps Lock)//0x91:1001 00 01 這是個主條目,有2*1bit的數據域作為輸出,屬性為:Data,Var,Abs0x91, 0x02, // OUTPUT (Data,Var,Abs)//0x95:1001 01 01 這是個全局條目,數據域的數量為1個0x95, 0x01, // REPORT_COUNT (1)//0x75:0111 01 01 這是個全局條目,每個數據域的長度為6bit,正好與前面的2bit組成1字節0x75, 0x06, // REPORT_SIZE (6)//0x91:1001 00 01 這是個主條目,有1*6bit數據域最為輸出,屬性為:Cnst,Var,Abs0x91, 0x03, // OUTPUT (Cnst,Var,Abs)0xc0 ? ? ? ?// END_COLLECTION};

4、修改端點緩存地址

在 usb_config.h中,調整每個USB端點分配的地址。

#define ENDP0_RXADDR ? ? ? ?(0x40)#define ENDP0_TXADDR ? ? ? ?(0x80)#define ENDP1_TXADDR ? ? ? ?(0xC0)#define ENDP1_RXADDR ? ? ? ?(0x0F0)#define ENDP2_TXADDR ? ? ? ?(0x110)#define ENDP4_RXADDR ? ? ? ?(0x150)#define ENDP4_TXADDR ? ? ? ?(0x190)

這時候就完成基本的配置,可以讓電腦識別到鍵盤和虛擬串口的設備,但不能正常使用。

接下來就是代碼初始化部分的修改。

基于本來虛擬串口的初始化增加HID配置

void CDC_Init(void){USBD_InitParam_T usbParam;USBD_InitParamStructInit(&usbParam);usbParam.classReqHandler = USBD_ClassHandler;usbParam.stdReqExceptionHandler = KeyBoard_ReportDescriptor;//增加HID配置usbParam.resetHandler = VCP_Reset;usbParam.inEpHandler = USBD_VCP_InEpCallback;usbParam.outEpHandler = USBD_VCP_OutEpCallback;usbParam.pDeviceDesc = (USBD_Descriptor_T *)&g_deviceDescriptor;usbParam.pConfigurationDesc = (USBD_Descriptor_T *)&g_configDescriptor;usbParam.pStringDesc = (USBD_Descriptor_T *)g_stringDescriptor;usbParam.pStdReqCallback = &stdReqCallback;USBD_Init(&usbParam);}void KeyBoard_ReportDescriptor(USBD_DevReqData_T *reqData){uint8_t len;if((reqData->byte.bRequest == USBD_GET_DESCRIPTOR) &&(reqData->byte.bmRequestType.bit.recipient == USBD_RECIPIENT_INTERFACE) &&(reqData->byte.bmRequestType.bit.type == USBD_REQ_TYPE_STANDARD)){if(reqData->byte.wValue[1] == 0x21){len = USB_MIN(reqData->byte.wLength[0], 9);USBD_CtrlInData((uint8_t *)&g_configDescriptor.pDesc[0x12], len);}else if(reqData->byte.wValue[1] == 0x22){len = USB_MIN(reqData->byte.wLength[0], g_ReportDescriptor.size);USBD_CtrlInData((uint8_t *)g_ReportDescriptor.pDesc, len);}}else{USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_STALL, USBD_EP_STATUS_STALL);}}

到此配置部分基本完成,接下來到main中增加段測試代碼,驗證USB配置是否正確。

配置虛擬串口一直打印dataBuf[5]= {0xaa,0xbb,0xcc,0xdd,0xff};

HID鍵盤根據鍵值表輸出數字1


?

void Delay(uint32_t i){while(i--);}unsigned char dataBuf[5]= {0xaa,0xbb,0xcc,0xdd,0xff};uint8_t Keyboad_Buf[8]={0,0,0x1E,0,0,0,0,0};int main(void){CDC_Init();while(1){USBD_TxData(USBD_EP_1, dataBuf, 5);USBD_TxData(USBD_EP_4, Keyboad_Buf, 8);Delay(0xFFFFFF);}}

圖片

燒錄代碼到開發板,接上USB線到電腦,可以看到Bushound能看到配置的復合設備。

圖片

使用串口助手能看到虛擬串口能正確打印我們的數據,鍵盤也正常在發送數字1,證明代碼配置沒問題,兩個功能使用一個USB接口實現了。SDK的虛擬串口也有做接收回傳的功能,可以直接使用。

到此鍵盤+虛擬串口的例程就簡單修改完成了。

注:文章作者在原帖中提供了例程文件,有需要請至原文21ic論壇下載

原文地址:https://bbs.21ic.com/icview-3321226-1-1.html

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

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

相關文章

css過渡屬性

前言 該屬性用于元素各種 “改變” 后的過渡效果動畫&#xff0c;包括但不限于顏色、寬高、縮放等。 如下圖所示&#xff0c;使用過渡屬性便可輕松完成。 示例代碼 您可以直接復制運行&#xff0c;查看效果。 <div>demo</div>div {width:100px; height:100px;/* …

云計算核心技術之云存儲技術

一、云存儲技術1.1、云存儲是什么從狹義上來說&#xff0c;云存儲是指通過虛擬化、分布式技術、集群應用、網格技術、負載均衡等技術&#xff0c;將網絡中大量的存儲設備通過軟件集合起來高效協同工作&#xff0c;共同對外提供低成本、高擴展性的數據存儲服務。從廣義上來講&am…

在Ubuntu上安裝并使用Vue2的基本教程

我也準備要嘗試一些前端開發了&#xff01;發現網上有些教程寫得挺好&#xff0c;但是還是有點老&#xff08;并且有點錯誤&#xff09;&#xff0c;所以這里更新一下&#xff1a; 主要參考了這篇教程&#xff1a;Vue2——1. 安裝教程_vue2 cdn-CSDN博客 并且使用NPM方式進行…

任務十九 打包部署

一、本地打包部署 首先在自己的電腦上,下載一個nginx nginx: download 之后再vscode中,進行打包 輸入命令 npm run build 打包過后,會在項目的根目錄下,生成一個dist的文件夾

《飛算Java AI使用教程:從安裝入門到實踐項目》

前引&#xff1a;在當今人工智能技術飛速發展的時代&#xff0c;Java作為企業級開發的主流語言&#xff0c;正與AI技術深度融合。飛算Java AI是一款強大的工具集&#xff0c;旨在幫助開發者輕松構建和部署智能應用&#xff0c;涵蓋機器學習、自然語言處理等核心功能。本教程將帶…

NestJS 依賴注入方式全解

一、基礎注入方式 1. 構造函數注入&#xff08;Constructor Injection&#xff09; 適用場景&#xff1a;模塊間依賴傳遞&#xff0c;服務初始化時必須存在的依賴 實現方式&#xff1a;通過構造函數參數聲明依賴&#xff0c;NestJS 自動解析并注入 Injectable() class UserServ…

完整源碼+技術文檔!基于Hadoop+Spark的鮑魚生理特征大數據分析系統免費分享

&#x1f393; 作者&#xff1a;計算機畢設小月哥 | 軟件開發專家 &#x1f5a5;? 簡介&#xff1a;8年計算機軟件程序開發經驗。精通Java、Python、微信小程序、安卓、大數據、PHP、.NET|C#、Golang等技術棧。 &#x1f6e0;? 專業服務 &#x1f6e0;? 需求定制化開發源碼提…

云原生俱樂部-shell知識點歸納(1)

shell的內容也挺多的&#xff0c;雖然云原生課程主要是講grep、sed、awk三劍客&#xff0c;但是還有結合循環結構&#xff0c;判斷語句&#xff0c;以及函數等內容。還是有點復雜的&#xff0c;并且我對shell的掌握并不多&#xff0c;所以寫的可能并不全。當然&#xff0c;如果…

設計模式(四)——責任鏈模式

1. 責任鏈模式的定義 責任鏈模式&#xff08;Chain of Responsibility&#xff0c;簡稱 CoR&#xff0c;也叫職責鏈模式&#xff09;是一種行為型設計模式&#xff0c;允許一個請求在一系列處理器&#xff08;handlers&#xff09;中傳遞。每個處理器可以選擇自己處理該請求&am…

MyBatis-Plus基礎篇詳解

文章目錄前言一、簡單介紹MyBatis-Plus1.1 特性1.2 架構二、SpringBoot集成MyBatis-Plus2.1 項目搭建2.2 導入所需依賴2.3 配置application.yml2.4 創建實體類2.5 創建Mapper接口2.6 啟動類配置三、DQL操作3.1 基礎查詢3.2 QueryWrapper查詢3.3 LambdaQueryWrapper查詢3.4 分頁…

基于W55MH32Q-EVB 實現 HTTP 服務器配置 OLED 滾動顯示信息

目錄 1 前言 2 項目環境 2.1 硬件準備 2.2 軟件環境 3.硬件連接和方案 3.1 硬件連接 3.2 方案圖示 4.例程修改 1 前言 HTTP&#xff08;超文本傳輸協議&#xff0c;HyperText Transfer Protocol&#xff09;是一種用于分布式、協作式、超媒體信息系統的應用層協議&#xff0c; …

YggJS RLogin暗黑霓虹主題登錄注冊頁面 版本:v0.1.1

項目介紹 yggjs_rlogin 是一個專注于 React 登錄/注冊頁面的組件庫。本文檔介紹“暗黑霓虹”主題&#xff1a;#111 暗色背景 青藍霓虹描邊輸入框 賽博朋克光效按鈕。 安裝說明 安裝&#xff1a;pnpm add yggjs_rlogin react react-dom使用&#xff1a;從 yggjs_rlogin 引入組…

大數據畢業設計選題推薦:護膚品店鋪運營數據可視化分析系統詳解

&#x1f34a;作者&#xff1a;計算機畢設匠心工作室 &#x1f34a;簡介&#xff1a;畢業后就一直專業從事計算機軟件程序開發&#xff0c;至今也有8年工作經驗。擅長Java、Python、微信小程序、安卓、大數據、PHP、.NET|C#、Golang等。 擅長&#xff1a;按照需求定制化開發項目…

【github-action 如何為github action設置secrets/environment】

Using secrets in GitHub Actions 在 GitHub Actions 中使用密鑰 Learn how to create secrets at the repository, environment, and organization levels for GitHub Actions workflows. 學習如何在倉庫、環境和組織級別為 GitHub Actions 工作流創建密鑰。 Creating secre…

寶塔面板Docker安裝n8n漢化中文

一、Docker安裝N8N 安裝配置默認即可&#xff0c;如果端口已被使用&#xff0c;可以自行更改 當狀態為運行中時&#xff0c;就可以點擊端口&#xff1a;訪問N8N 填寫完信息后&#xff0c;點擊下一步&#xff08;郵箱要能接收郵件&#xff1a;接收密鑰&#xff09; 點開始 點擊發…

F003疫情傳染病數據可視化vue+flask+mysql

編號:F003 文章結尾有CSDN官方提供的學長的聯系方式&#xff01;&#xff01; 歡迎關注B站 ? vue flask 前后端分離架構 ? 實現中國地圖、柱狀圖、折線圖、水地圖、環圖等多種圖形的echarts可視化分析 視頻 vueflask爬蟲 新冠疫情大屏實現 python 可視化分析項目源碼1 系統…

plantsimulation知識點25.8.19 工件不在RGV中心怎么辦?

如果出現這種情況&#xff0c;工件不在RGV的中心該怎么處理。首先說一下出現這種情況的原因。因為模擬的是兩臺RGV共同托舉一個工件移動&#xff0c;實際上RGV控制的代碼還是寫在一條軌道的傳感器控制代碼中。另一臺RGV只是從動的&#xff0c;工件也是在其中任意一臺RGV上&…

redis-sentinel基礎概念及部署

一. 引言&#xff1a;Redis Sentinel 是 redis 官方提供的高可用解決方案&#xff0c;主要用于監控 Redis 主從集群&#xff0c;在主節點故障時自動完成故障轉移&#xff0c;確保服務持續可用。二. 核心功能1. 監控&#xff08;monitoring&#xff09;&#xff1a;持續檢查主節…

LangChain RAG 簡述

在 LangChain 中實現 RAG&#xff08;檢索增強生成&#xff0c;Retrieval-Augmented Generation&#xff09;的核心思路是&#xff1a;讓大模型在生成回答前&#xff0c;先從外部知識庫&#xff08;如文檔、數據庫等&#xff09;中檢索相關信息&#xff0c;再基于檢索到的內容生…

GEO 優化專家孟慶濤:技術破壁者重構 AI 時代搜索邏輯

在生成式 AI 重塑全球搜索生態的浪潮中&#xff0c;中國 GEO&#xff08;生成式引擎優化&#xff09;領域的開拓者孟慶濤以 "智能決策革命" 的技術框架&#xff0c;顛覆了傳統 "發發文章" 的簡單認知。作為遼寧粵穗網絡科技有限公司總經理兼 GEO 實驗室主任…