From 3a7ed5922fc27b216004e4a72ca679dc7f35a564 Mon Sep 17 00:00:00 2001 From: windowsair Date: Sun, 28 Jan 2024 20:25:34 +0800 Subject: [PATCH 1/5] ci: update codeql to v3 Use esp32 target to build code for codeql. --- .github/workflows/codeql-analysis.yml | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5a2f484..3348c71 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -17,8 +17,6 @@ on: pull_request: # The branches below must be a subset of the branches above branches: [ master, develop ] - schedule: - - cron: '16 17 * * 2' jobs: analyze: @@ -34,13 +32,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: recursive # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/workflows/codeql/codeql-config.yml @@ -64,16 +62,13 @@ jobs: - if: matrix.language == 'cpp' || matrix.language == 'c' name: Build run: | - ls - sudo apt update - sudo apt install -y gcc git wget make libncurses-dev flex bison python python-setuptools python-serial ninja-build - wget https://dl.espressif.com/dl/xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz - tar -xzf ./xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz - python -m pip install --user -r ./ESP8266_RTOS_SDK/requirements.txt - export IDF_PATH=$PWD/ESP8266_RTOS_SDK - export PATH="$PATH:$PWD/xtensa-lx106-elf/bin" - python ./idf.py fullclean - python ./idf.py build + sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 + wget https://github.com/espressif/esp-idf/releases/download/v4.2.2/esp-idf-v4.2.2.zip + unzip esp-idf-v4.2.2.zip + ./esp-idf-v4.2.2/install.sh esp32 + . ./esp-idf-v4.2.2/export.sh + idf.py set-target esp32 + idf.py build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v3 From acfd967106995133e9a3e62b5efa152272e14e94 Mon Sep 17 00:00:00 2001 From: windowsair Date: Sun, 28 Jan 2024 21:17:39 +0800 Subject: [PATCH 2/5] feat(usb): change usb interface name to "Wireless ESP CMSIS-DAP" pyOCD identifies the debugger by USB interface name, which include substring "CMSIS-DAP". Let's change USB interface name to adapt pyOCD. --- components/USBIP/usb_descriptor.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/USBIP/usb_descriptor.c b/components/USBIP/usb_descriptor.c index 12752c4..13dd078 100644 --- a/components/USBIP/usb_descriptor.c +++ b/components/USBIP/usb_descriptor.c @@ -84,10 +84,12 @@ const uint8_t kUSBd0InterfaceDescriptor[]= USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass USBD_CUSTOM_CLASS0_IF0_PROTOCOL, // bInterfaceProtocol - 0x00, // iInterface + /** + * pyOCD identifies the debugger by USB interface name, which include substring "CMSIS-DAP". + * See `strings_list` in `usb_handle.c` + */ + 0x02, // iInterface // Index of string descriptor describing this interface - ////TODO: fix this 0x04 ? - // Standard Endpoint Descriptor From 8abe565836ff1a9495a63f5f587d2552b323937c Mon Sep 17 00:00:00 2001 From: windowsair Date: Thu, 8 Feb 2024 19:33:59 +0800 Subject: [PATCH 3/5] feat(dap): Add support for cmsis-dap v2.1.0 - Enhanced DAP_Info - Added extra UART support Extra UART for native cmsis-dap is not yet support now. --- components/DAP/config/DAP_config.h | 150 ++++++- components/DAP/include/DAP.h | 72 +++- components/DAP/source/DAP.c | 72 +++- components/DAP/source/UART.c | 652 +++++++++++++++++++++++++++++ 4 files changed, 897 insertions(+), 49 deletions(-) create mode 100644 components/DAP/source/UART.c diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h index eff54a2..9082546 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -17,8 +17,8 @@ * * ---------------------------------------------------------------------- * - * $Date: 1. December 2017 - * $Revision: V2.0.0 + * $Date: 16. June 2021 + * $Revision: V2.1.0 * * Project: CMSIS-DAP Configuration * Title: DAP_config.h CMSIS-DAP Configuration File (Template) @@ -31,10 +31,11 @@ * @brief Adaptation of GPIO and SPI pin * @change: 2021-2-10 Support GPIO and SPI * 2021-2-18 Try to support SWO - * @version 0.1 - * @date 2021-2-10 + * 2024-1-28 Update to CMSIS-DAP v2.1.0 + * @version 0.3 + * @date 2024-1-28 * - * @copyright Copyright (c) 2021 + * @copyright Copyright (c) 2021-2024 * */ @@ -149,6 +150,9 @@ This information includes: /// This information is returned by the command \ref DAP_Info as part of Capabilities. #define SWO_UART SWO_FUNCTION_ENABLE ///< SWO UART: 1 = available, 0 = not available. +/// USART Driver instance number for the UART SWO. +#define SWO_UART_DRIVER 0 ///< USART Driver instance number (Driver_USART#). + /// Maximum SWO UART Baudrate. #define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz @@ -170,22 +174,47 @@ This information includes: #define TIMESTAMP_CLOCK 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported). // <<<<<<<<<<<<<<<<<<<<<5MHz +/// Indicate that UART Communication Port is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_UART 0 ///< DAP UART: 1 = available, 0 = not available. + +/// USART Driver instance number for the UART Communication Port. +#define DAP_UART_DRIVER 1 ///< USART Driver instance number (Driver_USART#). + +/// UART Receive Buffer Size. +#define DAP_UART_RX_BUFFER_SIZE 1024U ///< Uart Receive Buffer Size in bytes (must be 2^n). + +/// UART Transmit Buffer Size. +#define DAP_UART_TX_BUFFER_SIZE 1024U ///< Uart Transmit Buffer Size in bytes (must be 2^n). + +/// Indicate that UART Communication via USB COM Port is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_UART_USB_COM_PORT 0 ///< USB COM Port: 1 = available, 0 = not available. + /// Debug Unit is connected to fixed Target Device. /// The Debug Unit may be part of an evaluation board and always connected to a fixed -/// known device. In this case a Device Vendor and Device Name string is stored which -/// may be used by the debugger or IDE to configure device parameters. -#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown; +/// known device. In this case a Device Vendor, Device Name, Board Vendor and Board Name strings +/// are stored and may be used by the debugger or IDE to configure device parameters. +#define TARGET_FIXED 1 ///< Target: 1 = known, 0 = unknown; -#if TARGET_DEVICE_FIXED -#define TARGET_DEVICE_VENDOR "ARM" ///< String indicating the Silicon Vendor -#define TARGET_DEVICE_NAME "Cortex-M4" ///< String indicating the Target Device +#define TARGET_DEVICE_VENDOR "" ///< String indicating the Silicon Vendor +#define TARGET_DEVICE_NAME "" ///< String indicating the Target Device +#define TARGET_BOARD_VENDOR "windowsair" ///< String indicating the Board Vendor +#define TARGET_BOARD_NAME "ESP wireless DAP" ///< String indicating the Board Name + +#if TARGET_FIXED != 0 +#include +static const char TargetDeviceVendor [] = TARGET_DEVICE_VENDOR; +static const char TargetDeviceName [] = TARGET_DEVICE_NAME; +static const char TargetBoardVendor [] = TARGET_BOARD_VENDOR; +static const char TargetBoardName [] = TARGET_BOARD_NAME; #endif /** * @brief Get Vendor ID string. * - * @param str Pointer to buffer to store the string. - * @return String length. + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length. (including terminating NULL character) or 0 (no string). */ __STATIC_INLINE uint8_t DAP_GetVendorString(char *str) { @@ -199,8 +228,8 @@ __STATIC_INLINE uint8_t DAP_GetVendorString(char *str) /** * @brief Get Product ID string. * - * @param str Pointer to buffer to store the string. - * @return String length. + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length. (including terminating NULL character) or 0 (no string). */ __STATIC_INLINE uint8_t DAP_GetProductString(char *str) { @@ -212,8 +241,8 @@ __STATIC_INLINE uint8_t DAP_GetProductString(char *str) /** * @brief Get Serial Number string. * - * @param str Pointer to buffer to store the string. - * @return String length. + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length. (including terminating NULL character) or 0 (no string). */ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) { @@ -221,6 +250,93 @@ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) return (sizeof("1234")); } +/** + * @brief Get Target Device Vendor string. + * + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length (including terminating NULL character) or 0 (no string). + */ +__STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetDeviceVendor); + len = (uint8_t)(strlen(TargetDeviceVendor) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** + * @brief Get Target Device Name string. + * + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length (including terminating NULL character) or 0 (no string). + */ +__STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetDeviceName); + len = (uint8_t)(strlen(TargetDeviceName) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** + * @brief Get Target Board Vendor string. + * + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length (including terminating NULL character) or 0 (no string). + */ +__STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetBoardVendor); + len = (uint8_t)(strlen(TargetBoardVendor) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** + * @brief Get Target Board Name string. + * + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length (including terminating NULL character) or 0 (no string). + */ +__STATIC_INLINE uint8_t DAP_GetTargetBoardNameString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetBoardName); + len = (uint8_t)(strlen(TargetBoardName) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** + * @brief Get Product Firmware Version string. + * + * @param str Pointer to buffer to store the string (max 60 characters). + * @return String length (including terminating NULL character) or 0 (no string). + */ +__STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString (char *str) { + (void)str; + return (0U); +} + ///@} diff --git a/components/DAP/include/DAP.h b/components/DAP/include/DAP.h index cad17b3..4f61acf 100644 --- a/components/DAP/include/DAP.h +++ b/components/DAP/include/DAP.h @@ -17,8 +17,8 @@ * * ---------------------------------------------------------------------- * - * $Date: 26. November 2019 - * $Revision: V2.0.0 + * $Date: 26. May 2021 + * $Revision: V2.1.0 * * Project: CMSIS-DAP Include * Title: DAP.h Definitions @@ -31,9 +31,9 @@ // DAP Firmware Version #ifdef DAP_FW_V1 -#define DAP_FW_VER "1.2.0" +#define DAP_FW_VER "1.3.0" #else -#define DAP_FW_VER "2.0.0" +#define DAP_FW_VER "2.1.0" #endif // DAP Command IDs @@ -63,6 +63,11 @@ #define ID_DAP_SWO_Status 0x1BU #define ID_DAP_SWO_ExtendedStatus 0x1EU #define ID_DAP_SWO_Data 0x1CU +#define ID_DAP_UART_Transport 0x1FU +#define ID_DAP_UART_Configure 0x20U +#define ID_DAP_UART_Control 0x22U +#define ID_DAP_UART_Status 0x23U +#define ID_DAP_UART_Transfer 0x21U #define ID_DAP_QueueCommands 0x7EU #define ID_DAP_ExecuteCommands 0x7FU @@ -111,11 +116,16 @@ #define DAP_ID_VENDOR 1U #define DAP_ID_PRODUCT 2U #define DAP_ID_SER_NUM 3U -#define DAP_ID_FW_VER 4U +#define DAP_ID_DAP_FW_VER 4U #define DAP_ID_DEVICE_VENDOR 5U #define DAP_ID_DEVICE_NAME 6U +#define DAP_ID_BOARD_VENDOR 7U +#define DAP_ID_BOARD_NAME 8U +#define DAP_ID_PRODUCT_FW_VER 9U #define DAP_ID_CAPABILITIES 0xF0U #define DAP_ID_TIMESTAMP_CLOCK 0xF1U +#define DAP_ID_UART_RX_BUFFER_SIZE 0xFBU +#define DAP_ID_UART_TX_BUFFER_SIZE 0xFCU #define DAP_ID_SWO_BUFFER_SIZE 0xFDU #define DAP_ID_PACKET_COUNT 0xFEU #define DAP_ID_PACKET_SIZE 0xFFU @@ -165,6 +175,30 @@ #define DAP_SWO_STREAM_ERROR (1U<<6) #define DAP_SWO_BUFFER_OVERRUN (1U<<7) +// DAP UART Transport +#define DAP_UART_TRANSPORT_NONE 0U +#define DAP_UART_TRANSPORT_USB_COM_PORT 1U +#define DAP_UART_TRANSPORT_DAP_COMMAND 2U + +// DAP UART Control +#define DAP_UART_CONTROL_RX_ENABLE (1U<<0) +#define DAP_UART_CONTROL_RX_DISABLE (1U<<1) +#define DAP_UART_CONTROL_RX_BUF_FLUSH (1U<<2) +#define DAP_UART_CONTROL_TX_ENABLE (1U<<4) +#define DAP_UART_CONTROL_TX_DISABLE (1U<<5) +#define DAP_UART_CONTROL_TX_BUF_FLUSH (1U<<6) + +// DAP UART Status +#define DAP_UART_STATUS_RX_ENABLED (1U<<0) +#define DAP_UART_STATUS_RX_DATA_LOST (1U<<1) +#define DAP_UART_STATUS_FRAMING_ERROR (1U<<2) +#define DAP_UART_STATUS_PARITY_ERROR (1U<<3) +#define DAP_UART_STATUS_TX_ENABLED (1U<<4) + +// DAP UART Configure Error +#define DAP_UART_CFG_ERROR_DATA_BITS (1U<<0) +#define DAP_UART_CFG_ERROR_PARITY (1U<<1) +#define DAP_UART_CFG_ERROR_STOP_BITS (1U<<2) // Debug Port Register Addresses #define DP_IDCODE 0x00U // IDCODE Register (SW Read only) @@ -270,17 +304,25 @@ extern void SWO_QueueTransfer (uint8_t *buf, uint32_t num); extern void SWO_AbortTransfer (void); extern void SWO_TransferComplete (void); -extern uint32_t UART_SWO_Mode (uint32_t enable); -extern uint32_t UART_SWO_Baudrate (uint32_t baudrate); -extern uint32_t UART_SWO_Control (uint32_t active); -// extern void UART_SWO_Capture (uint8_t *buf, uint32_t num); -// extern uint32_t UART_SWO_GetCount (void); +extern uint32_t SWO_Mode_UART (uint32_t enable); +extern uint32_t SWO_Baudrate_UART (uint32_t baudrate); +extern uint32_t SWO_Control_UART (uint32_t active); +extern void SWO_Capture_UART (uint8_t *buf, uint32_t num); +extern uint32_t SWO_GetCount_UART (void); -extern uint32_t Manchester_SWO_Mode (uint32_t enable); -extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate); -extern uint32_t Manchester_SWO_Control (uint32_t active); -extern void Manchester_SWO_Capture (uint8_t *buf, uint32_t num); -extern uint32_t Manchester_SWO_GetCount (void); +extern uint32_t SWO_Mode_Manchester (uint32_t enable); +extern uint32_t SWO_Baudrate_Manchester (uint32_t baudrate); +extern uint32_t SWO_Control_Manchester (uint32_t active); +extern void SWO_Capture_Manchester (uint8_t *buf, uint32_t num); +extern uint32_t SWO_GetCount_Manchester (void); + +extern uint32_t UART_Transport (const uint8_t *request, uint8_t *response); +extern uint32_t UART_Configure (const uint8_t *request, uint8_t *response); +extern uint32_t UART_Control (const uint8_t *request, uint8_t *response); +extern uint32_t UART_Status (uint8_t *response); +extern uint32_t UART_Transfer (const uint8_t *request, uint8_t *response); + +extern uint8_t USB_COM_PORT_Activate (uint32_t cmd); extern uint32_t DAP_ProcessVendorCommand (const uint8_t *request, uint8_t *response); extern uint32_t DAP_ProcessCommand (const uint8_t *request, uint8_t *response); diff --git a/components/DAP/source/DAP.c b/components/DAP/source/DAP.c index 81acb58..cf05359 100644 --- a/components/DAP/source/DAP.c +++ b/components/DAP/source/DAP.c @@ -17,8 +17,8 @@ * * ---------------------------------------------------------------------- * - * $Date: 1. December 2017 - * $Revision: V2.0.0 + * $Date: 16. June 2021 + * $Revision: V2.1.0 * * Project: CMSIS-DAP Source * Title: DAP.c CMSIS-DAP Commands @@ -63,10 +63,6 @@ volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag static const char DAP_FW_Ver [] = DAP_FW_VER; -#if TARGET_DEVICE_FIXED -static const char TargetDeviceVendor [] = TARGET_DEVICE_VENDOR; -static const char TargetDeviceName [] = TARGET_DEVICE_NAME; -#endif // Get DAP Information @@ -86,21 +82,24 @@ static uint8_t DAP_Info(uint8_t id, uint8_t *info) { case DAP_ID_SER_NUM: length = DAP_GetSerNumString((char *)info); break; - case DAP_ID_FW_VER: + case DAP_ID_DAP_FW_VER: length = (uint8_t)sizeof(DAP_FW_Ver); memcpy(info, DAP_FW_Ver, length); break; case DAP_ID_DEVICE_VENDOR: -#if TARGET_DEVICE_FIXED - length = (uint8_t)sizeof(TargetDeviceVendor); - memcpy(info, TargetDeviceVendor, length); -#endif + length = DAP_GetTargetDeviceVendorString((char *)info); break; case DAP_ID_DEVICE_NAME: -#if TARGET_DEVICE_FIXED - length = (uint8_t)sizeof(TargetDeviceName); - memcpy(info, TargetDeviceName, length); -#endif + length = DAP_GetTargetDeviceNameString((char *)info); + break; + case DAP_ID_BOARD_VENDOR: + length = DAP_GetTargetBoardVendorString((char *)info); + break; + case DAP_ID_BOARD_NAME: + length = DAP_GetTargetBoardNameString((char *)info); + break; + case DAP_ID_PRODUCT_FW_VER: + length = DAP_GetProductFirmwareVersionString((char *)info); break; case DAP_ID_CAPABILITIES: info[0] = ((DAP_SWD != 0) ? (1U << 0) : 0U) | @@ -109,8 +108,11 @@ static uint8_t DAP_Info(uint8_t id, uint8_t *info) { ((SWO_MANCHESTER != 0) ? (1U << 3) : 0U) | /* Atomic Commands */ (1U << 4) | ((TIMESTAMP_CLOCK != 0U) ? (1U << 5) : 0U) | - ((SWO_STREAM != 0U) ? (1U << 6) : 0U); - length = 1U; + ((SWO_STREAM != 0U) ? (1U << 6) : 0U) | + ((DAP_UART != 0U) ? (1U << 7) : 0U); + + info[1] = ((DAP_UART_USB_COM_PORT != 0) ? (1U << 0) : 0U); + length = 2U; break; case DAP_ID_TIMESTAMP_CLOCK: #if (TIMESTAMP_CLOCK != 0U) @@ -119,6 +121,24 @@ static uint8_t DAP_Info(uint8_t id, uint8_t *info) { info[2] = (uint8_t)(TIMESTAMP_CLOCK >> 16); info[3] = (uint8_t)(TIMESTAMP_CLOCK >> 24); length = 4U; +#endif + break; + case DAP_ID_UART_RX_BUFFER_SIZE: +#if (DAP_UART != 0) + info[0] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 0); + info[1] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 8); + info[2] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 16); + info[3] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 24); + length = 4U; +#endif + break; + case DAP_ID_UART_TX_BUFFER_SIZE: +#if (DAP_UART != 0) + info[0] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 0); + info[1] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 8); + info[2] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 16); + info[3] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 24); + length = 4U; #endif break; case DAP_ID_SWO_BUFFER_SIZE: @@ -1751,6 +1771,24 @@ uint32_t DAP_ProcessCommand(const uint8_t *request, uint8_t *response) { break; #endif +#if (DAP_UART != 0) + case ID_DAP_UART_Transport: + num = UART_Transport(request, response); + break; + case ID_DAP_UART_Configure: + num = UART_Configure(request, response); + break; + case ID_DAP_UART_Control: + num = UART_Control(request, response); + break; + case ID_DAP_UART_Status: + num = UART_Status(response); + break; + case ID_DAP_UART_Transfer: + num = UART_Transfer(request, response); + break; +#endif + default: *(response-1) = ID_DAP_Invalid; return ((1U << 16) | 1U); diff --git a/components/DAP/source/UART.c b/components/DAP/source/UART.c new file mode 100644 index 0000000..a29c847 --- /dev/null +++ b/components/DAP/source/UART.c @@ -0,0 +1,652 @@ +/* + * Copyright (c) 2021 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 1. March 2021 + * $Revision: V1.0.0 + * + * Project: CMSIS-DAP Source + * Title: UART.c CMSIS-DAP UART + * + *---------------------------------------------------------------------------*/ + +#include "DAP_config.h" +#include "DAP.h" + +#if (DAP_UART != 0) + +#ifdef DAP_FW_V1 +#error "UART Communication Port not supported in DAP V1!" +#endif + +#include "Driver_USART.h" + +#include "cmsis_os2.h" +#include + +#define UART_RX_BLOCK_SIZE 32U /* Uart Rx Block Size (must be 2^n) */ + +// USART Driver +#define _USART_Driver_(n) Driver_USART##n +#define USART_Driver_(n) _USART_Driver_(n) +extern ARM_DRIVER_USART USART_Driver_(DAP_UART_DRIVER); +#define pUSART (&USART_Driver_(DAP_UART_DRIVER)) + +// UART Configuration +#if (DAP_UART_USB_COM_PORT != 0) +static uint8_t UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT; +#else +static uint8_t UartTransport = DAP_UART_TRANSPORT_NONE; +#endif + +// UART Flags +static uint8_t UartConfigured = 0U; +static uint8_t UartReceiveEnabled = 0U; +static uint8_t UartTransmitEnabled = 0U; +static uint8_t UartTransmitActive = 0U; + +// UART TX Buffer +static uint8_t UartTxBuf[DAP_UART_TX_BUFFER_SIZE]; +static volatile uint32_t UartTxIndexI = 0U; +static volatile uint32_t UartTxIndexO = 0U; + +// UART RX Buffer +static uint8_t UartRxBuf[DAP_UART_RX_BUFFER_SIZE]; +static volatile uint32_t UartRxIndexI = 0U; +static volatile uint32_t UartRxIndexO = 0U; + +// Uart Errors +static volatile uint8_t UartErrorRxDataLost = 0U; +static volatile uint8_t UartErrorFraming = 0U; +static volatile uint8_t UartErrorParity = 0U; + +// UART Transmit +static uint32_t UartTxNum = 0U; + +// Function prototypes +static uint8_t UART_Init (void); +static void UART_Uninit (void); +static uint8_t UART_Get_Status (void); +static uint8_t UART_Receive_Enable (void); +static uint8_t UART_Transmit_Enable (void); +static void UART_Receive_Disable (void); +static void UART_Transmit_Disable (void); +static void UART_Receive_Flush (void); +static void UART_Transmit_Flush (void); +static void UART_Receive (void); +static void UART_Transmit (void); + + +// USART Driver Callback function +// event: event mask +static void USART_Callback (uint32_t event) { + if (event & ARM_USART_EVENT_SEND_COMPLETE) { + UartTxIndexO += UartTxNum; + UartTransmitActive = 0U; + UART_Transmit(); + } + if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { + UartRxIndexI += UART_RX_BLOCK_SIZE; + UART_Receive(); + } + if (event & ARM_USART_EVENT_RX_OVERFLOW) { + UartErrorRxDataLost = 1U; + } + if (event & ARM_USART_EVENT_RX_FRAMING_ERROR) { + UartErrorFraming = 1U; + } + if (event & ARM_USART_EVENT_RX_PARITY_ERROR) { + UartErrorParity = 1U; + } +} + +// Init UART +// return: DAP_OK or DAP_ERROR +static uint8_t UART_Init (void) { + int32_t status; + uint8_t ret = DAP_ERROR; + + UartConfigured = 0U; + UartReceiveEnabled = 0U; + UartTransmitEnabled = 0U; + UartTransmitActive = 0U; + UartErrorRxDataLost = 0U; + UartErrorFraming = 0U; + UartErrorParity = 0U; + UartTxIndexI = 0U; + UartTxIndexO = 0U; + UartRxIndexI = 0U; + UartRxIndexO = 0U; + UartTxNum = 0U; + + status = pUSART->Initialize(USART_Callback); + if (status == ARM_DRIVER_OK) { + status = pUSART->PowerControl(ARM_POWER_FULL); + } + if (status == ARM_DRIVER_OK) { + ret = DAP_OK; + } + + return (ret); +} + +// Un-Init UART +static void UART_Uninit (void) { + UartConfigured = 0U; + + pUSART->PowerControl(ARM_POWER_OFF); + pUSART->Uninitialize(); +} + +// Get UART Status +// return: status +static uint8_t UART_Get_Status (void) { + uint8_t status = 0U; + + if (UartReceiveEnabled != 0U) { + status |= DAP_UART_STATUS_RX_ENABLED; + } + if (UartErrorRxDataLost != 0U) { + UartErrorRxDataLost = 0U; + status |= DAP_UART_STATUS_RX_DATA_LOST; + } + if (UartErrorFraming != 0U) { + UartErrorFraming = 0U; + status |= DAP_UART_STATUS_FRAMING_ERROR; + } + if (UartErrorParity != 0U) { + UartErrorParity = 0U; + status |= DAP_UART_STATUS_PARITY_ERROR; + } + if (UartTransmitEnabled != 0U) { + status |= DAP_UART_STATUS_TX_ENABLED; + } + + return (status); +} + +// Enable UART Receive +// return: DAP_OK or DAP_ERROR +static uint8_t UART_Receive_Enable (void) { + int32_t status; + uint8_t ret = DAP_ERROR; + + if (UartReceiveEnabled == 0U) { + // Flush Buffers + UartRxIndexI = 0U; + UartRxIndexO = 0U; + + UART_Receive(); + status = pUSART->Control(ARM_USART_CONTROL_RX, 1U); + if (status == ARM_DRIVER_OK) { + UartReceiveEnabled = 1U; + ret = DAP_OK; + } + } else { + ret = DAP_OK; + } + + return (ret); +} + +// Enable UART Transmit +// return: DAP_OK or DAP_ERROR +static uint8_t UART_Transmit_Enable (void) { + int32_t status; + uint8_t ret = DAP_ERROR; + + if (UartTransmitEnabled == 0U) { + // Flush Buffers + UartTransmitActive = 0U; + UartTxIndexI = 0U; + UartTxIndexO = 0U; + UartTxNum = 0U; + + status = pUSART->Control(ARM_USART_CONTROL_TX, 1U); + if (status == ARM_DRIVER_OK) { + UartTransmitEnabled = 1U; + ret = DAP_OK; + } + } else { + ret = DAP_OK; + } + + return (ret); +} + +// Disable UART Receive +static void UART_Receive_Disable (void) { + if (UartReceiveEnabled != 0U) { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + UartReceiveEnabled = 0U; + } +} + +// Disable UART Transmit +static void UART_Transmit_Disable (void) { + if (UartTransmitEnabled != 0U) { + pUSART->Control(ARM_USART_ABORT_SEND, 0U); + pUSART->Control(ARM_USART_CONTROL_TX, 0U); + UartTransmitActive = 0U; + UartTransmitEnabled = 0U; + } +} + +// Flush UART Receive buffer +static void UART_Receive_Flush (void) { + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + UartRxIndexI = 0U; + UartRxIndexO = 0U; + if (UartReceiveEnabled != 0U) { + UART_Receive(); + } +} + +// Flush UART Transmit buffer +static void UART_Transmit_Flush (void) { + pUSART->Control(ARM_USART_ABORT_SEND, 0U); + UartTransmitActive = 0U; + UartTxIndexI = 0U; + UartTxIndexO = 0U; + UartTxNum = 0U; +} + +// Receive data from target via UART +static void UART_Receive (void) { + uint32_t index; + + index = UartRxIndexI & (DAP_UART_RX_BUFFER_SIZE - 1U); + pUSART->Receive(&UartRxBuf[index], UART_RX_BLOCK_SIZE); +} + +// Transmit available data to target via UART +static void UART_Transmit (void) { + uint32_t count; + uint32_t index; + + count = UartTxIndexI - UartTxIndexO; + index = UartTxIndexO & (DAP_UART_TX_BUFFER_SIZE - 1U); + + if (count != 0U) { + if ((index + count) <= DAP_UART_TX_BUFFER_SIZE) { + UartTxNum = count; + } else { + UartTxNum = DAP_UART_TX_BUFFER_SIZE - index; + } + UartTransmitActive = 1U; + pUSART->Send(&UartTxBuf[index], UartTxNum); + } +} + +// Process UART Transport command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Transport (const uint8_t *request, uint8_t *response) { + uint8_t transport; + uint8_t ret = DAP_ERROR; + + transport = *request; + switch (transport) { + case DAP_UART_TRANSPORT_NONE: + switch (UartTransport) { + case DAP_UART_TRANSPORT_NONE: + ret = DAP_OK; + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: +#if (DAP_UART_USB_COM_PORT != 0) + USB_COM_PORT_Activate(0U); + UartTransport = DAP_UART_TRANSPORT_NONE; + ret = DAP_OK; +#endif + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + UART_Receive_Disable(); + UART_Transmit_Disable(); + UART_Uninit(); + UartTransport = DAP_UART_TRANSPORT_NONE; + ret= DAP_OK; + break; + } + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: + switch (UartTransport) { + case DAP_UART_TRANSPORT_NONE: +#if (DAP_UART_USB_COM_PORT != 0) + if (USB_COM_PORT_Activate(1U) == 0U) { + UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT; + ret = DAP_OK; + } +#endif + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: + ret = DAP_OK; + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + UART_Receive_Disable(); + UART_Transmit_Disable(); + UART_Uninit(); + UartTransport = DAP_UART_TRANSPORT_NONE; +#if (DAP_UART_USB_COM_PORT != 0) + if (USB_COM_PORT_Activate(1U) == 0U) { + UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT; + ret = DAP_OK; + } +#endif + break; + } + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + switch (UartTransport) { + case DAP_UART_TRANSPORT_NONE: + ret = UART_Init(); + if (ret == DAP_OK) { + UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND; + } + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: +#if (DAP_UART_USB_COM_PORT != 0) + USB_COM_PORT_Activate(0U); + UartTransport = DAP_UART_TRANSPORT_NONE; +#endif + ret = UART_Init(); + if (ret == DAP_OK) { + UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND; + } + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + ret = DAP_OK; + break; + } + break; + default: + break; + } + + *response = ret; + + return ((1U << 16) | 1U); +} + +// Process UART Configure command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Configure (const uint8_t *request, uint8_t *response) { + uint8_t control, status; + uint32_t baudrate; + int32_t result; + + if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) { + status = DAP_UART_CFG_ERROR_DATA_BITS | + DAP_UART_CFG_ERROR_PARITY | + DAP_UART_CFG_ERROR_STOP_BITS; + baudrate = 0U; // baudrate error + } else { + + status = 0U; + control = *request; + baudrate = (uint32_t)(*(request+1) << 0) | + (uint32_t)(*(request+2) << 8) | + (uint32_t)(*(request+3) << 16) | + (uint32_t)(*(request+4) << 24); + + result = pUSART->Control(control | + ARM_USART_MODE_ASYNCHRONOUS | + ARM_USART_FLOW_CONTROL_NONE, + baudrate); + if (result == ARM_DRIVER_OK) { + UartConfigured = 1U; + } else { + UartConfigured = 0U; + switch (result) { + case ARM_USART_ERROR_BAUDRATE: + status = 0U; + baudrate = 0U; + break; + case ARM_USART_ERROR_DATA_BITS: + status = DAP_UART_CFG_ERROR_DATA_BITS; + break; + case ARM_USART_ERROR_PARITY: + status = DAP_UART_CFG_ERROR_PARITY; + break; + case ARM_USART_ERROR_STOP_BITS: + status = DAP_UART_CFG_ERROR_STOP_BITS; + break; + default: + status = DAP_UART_CFG_ERROR_DATA_BITS | + DAP_UART_CFG_ERROR_PARITY | + DAP_UART_CFG_ERROR_STOP_BITS; + baudrate = 0U; + break; + } + } + } + + *response++ = status; + *response++ = (uint8_t)(baudrate >> 0); + *response++ = (uint8_t)(baudrate >> 8); + *response++ = (uint8_t)(baudrate >> 16); + *response = (uint8_t)(baudrate >> 24); + + return ((5U << 16) | 5U); +} + +// Process UART Control command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Control (const uint8_t *request, uint8_t *response) { + uint8_t control; + uint8_t result; + uint8_t ret = DAP_OK; + + if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) { + ret = DAP_ERROR; + } else { + + control = *request; + + if ((control & DAP_UART_CONTROL_RX_DISABLE) != 0U) { + // Receive disable + UART_Receive_Disable(); + } else if ((control & DAP_UART_CONTROL_RX_ENABLE) != 0U) { + // Receive enable + if (UartConfigured != 0U) { + result = UART_Receive_Enable(); + if (result != DAP_OK) { + ret = DAP_ERROR; + } + } else { + ret = DAP_ERROR; + } + } + if ((control & DAP_UART_CONTROL_RX_BUF_FLUSH) != 0U) { + UART_Receive_Flush(); + } + + if ((control & DAP_UART_CONTROL_TX_DISABLE) != 0U) { + // Transmit disable + UART_Transmit_Disable(); + } else if ((control & DAP_UART_CONTROL_TX_ENABLE) != 0U) { + // Transmit enable + if (UartConfigured != 0U) { + result = UART_Transmit_Enable(); + if (result != DAP_OK) { + ret = DAP_ERROR; + } + } else { + ret = DAP_ERROR; + } + } + if ((control & DAP_UART_CONTROL_TX_BUF_FLUSH) != 0U) { + UART_Transmit_Flush(); + } + } + + *response = ret; + + return ((1U << 16) | 1U); +} + +// Process UART Status command and prepare response +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Status (uint8_t *response) { + uint32_t rx_cnt, tx_cnt; + uint32_t cnt; + uint8_t status; + + if ((UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) || + (UartConfigured == 0U)) { + rx_cnt = 0U; + tx_cnt = 0U; + status = 0U; + } else { + + rx_cnt = UartRxIndexI - UartRxIndexO; + rx_cnt += pUSART->GetRxCount(); + if (rx_cnt > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) { + // Overflow + UartErrorRxDataLost = 1U; + rx_cnt = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2)); + UartRxIndexO = UartRxIndexI - rx_cnt; + } + + tx_cnt = UartTxIndexI - UartTxIndexO; + cnt = pUSART->GetTxCount(); + if (UartTransmitActive != 0U) { + tx_cnt -= cnt; + } + + status = UART_Get_Status(); + } + + *response++ = status; + *response++ = (uint8_t)(rx_cnt >> 0); + *response++ = (uint8_t)(rx_cnt >> 8); + *response++ = (uint8_t)(rx_cnt >> 16); + *response++ = (uint8_t)(rx_cnt >> 24); + *response++ = (uint8_t)(tx_cnt >> 0); + *response++ = (uint8_t)(tx_cnt >> 8); + *response++ = (uint8_t)(tx_cnt >> 16); + *response = (uint8_t)(tx_cnt >> 24); + + return ((0U << 16) | 9U); +} + +// Process UART Transfer command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Transfer (const uint8_t *request, uint8_t *response) { + uint32_t rx_cnt, tx_cnt; + uint32_t rx_num, tx_num; + uint8_t *rx_data; + const + uint8_t *tx_data; + uint32_t num; + uint32_t index; + uint8_t status; + + if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) { + status = 0U; + rx_cnt = 0U; + tx_cnt = 0U; + } else { + + // RX Data + rx_cnt = ((uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8)); + + if (rx_cnt > (DAP_PACKET_SIZE - 6U)) { + rx_cnt = (DAP_PACKET_SIZE - 6U); + } + rx_num = UartRxIndexI - UartRxIndexO; + rx_num += pUSART->GetRxCount(); + if (rx_num > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) { + // Overflow + UartErrorRxDataLost = 1U; + rx_num = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2)); + UartRxIndexO = UartRxIndexI - rx_num; + } + if (rx_cnt > rx_num) { + rx_cnt = rx_num; + } + + rx_data = (response+5); + index = UartRxIndexO & (DAP_UART_RX_BUFFER_SIZE - 1U); + if ((index + rx_cnt) <= DAP_UART_RX_BUFFER_SIZE) { + memcpy( rx_data, &UartRxBuf[index], rx_cnt); + } else { + num = DAP_UART_RX_BUFFER_SIZE - index; + memcpy( rx_data, &UartRxBuf[index], num); + memcpy(&rx_data[num], &UartRxBuf[0], rx_cnt - num); + } + UartRxIndexO += rx_cnt; + + // TX Data + tx_cnt = ((uint32_t)(*(request+2) << 0) | + (uint32_t)(*(request+3) << 8)); + tx_data = (request+4); + + if (tx_cnt > (DAP_PACKET_SIZE - 5U)) { + tx_cnt = (DAP_PACKET_SIZE - 5U); + } + tx_num = UartTxIndexI - UartTxIndexO; + num = pUSART->GetTxCount(); + if (UartTransmitActive != 0U) { + tx_num -= num; + } + if (tx_cnt > (DAP_UART_TX_BUFFER_SIZE - tx_num)) { + tx_cnt = (DAP_UART_TX_BUFFER_SIZE - tx_num); + } + + index = UartTxIndexI & (DAP_UART_TX_BUFFER_SIZE - 1U); + if ((index + tx_cnt) <= DAP_UART_TX_BUFFER_SIZE) { + memcpy(&UartTxBuf[index], tx_data, tx_cnt); + } else { + num = DAP_UART_TX_BUFFER_SIZE - index; + memcpy(&UartTxBuf[index], tx_data, num); + memcpy(&UartTxBuf[0], &tx_data[num], tx_cnt - num); + } + UartTxIndexI += tx_cnt; + + if (UartTransmitActive == 0U) { + UART_Transmit(); + } + + status = UART_Get_Status(); + } + + *response++ = status; + *response++ = (uint8_t)(tx_cnt >> 0); + *response++ = (uint8_t)(tx_cnt >> 8); + *response++ = (uint8_t)(rx_cnt >> 0); + *response = (uint8_t)(rx_cnt >> 8); + + return (((4U + tx_cnt) << 16) | (5U + rx_cnt)); +} + +#endif /* DAP_UART */ From 16f8b53a76acccc99b8894693d274a3932637518 Mon Sep 17 00:00:00 2001 From: windowsair Date: Fri, 16 Feb 2024 18:46:50 +0800 Subject: [PATCH 4/5] refactor(network): Refactor usbip and tcp process code In previous versions, parsing of the usbip protocol was implemented via a global state machine and shared with elaphureLink. The refactored code removes these global state machines and handles them with the corresponding protocol header commands. --- .../elaphureLink/elaphureLink_protocol.c | 38 ++- .../elaphureLink/elaphureLink_protocol.h | 2 + main/CMakeLists.txt | 2 +- main/DAP_handle.c | 85 +++---- main/DAP_handle.h | 3 +- main/tcp_server.c | 93 +++----- main/usbip_server.c | 225 +++++++++--------- main/usbip_server.h | 14 +- 8 files changed, 219 insertions(+), 243 deletions(-) diff --git a/components/elaphureLink/elaphureLink_protocol.c b/components/elaphureLink/elaphureLink_protocol.c index c86db73..ab8ec4b 100644 --- a/components/elaphureLink/elaphureLink_protocol.c +++ b/components/elaphureLink/elaphureLink_protocol.c @@ -1,11 +1,13 @@ #include "components/elaphureLink/elaphureLink_protocol.h" +#include "main/DAP_handle.h" #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" #include +extern int kRestartDAPHandle; extern int kSock; extern int usbip_network_send(int s, const void *dataptr, size_t size, int flags); @@ -25,7 +27,6 @@ void el_process_buffer_malloc() { el_process_buffer = malloc(1500); } - void el_process_buffer_free() { if (el_process_buffer != NULL) { free(el_process_buffer); @@ -33,7 +34,6 @@ void el_process_buffer_free() { } } - int el_handshake_process(int fd, void *buffer, size_t len) { if (len != sizeof(el_request_handshake)) { return -1; @@ -59,10 +59,42 @@ int el_handshake_process(int fd, void *buffer, size_t len) { return 0; } - void el_dap_data_process(void* buffer, size_t len) { int res = DAP_ExecuteCommand(buffer, (uint8_t *)el_process_buffer); res &= 0xFFFF; usbip_network_send(kSock, el_process_buffer, res, 0); } + +int el_dap_work(uint8_t* base, size_t len) +{ + uint8_t *data; + int sz, ret; + + // read command code and protocol version + data = base + 4; + sz = 8; + do { + ret = recv(kSock, data, sz, 0); + if (ret <= 0) + return ret; + sz -= ret; + data += ret; + } while (sz > 0); + + ret = el_handshake_process(kSock, base, 12); + if (ret) + return ret; + + kRestartDAPHandle = DELETE_HANDLE; + el_process_buffer_malloc(); + // data process + while(1) { + ret = recv(kSock, base, len, 0); + if (ret <= 0) + return ret; + el_dap_data_process(base, ret); + } + + return 0; +} diff --git a/components/elaphureLink/elaphureLink_protocol.h b/components/elaphureLink/elaphureLink_protocol.h index 751c024..2ba65e6 100644 --- a/components/elaphureLink/elaphureLink_protocol.h +++ b/components/elaphureLink/elaphureLink_protocol.h @@ -47,6 +47,8 @@ int el_handshake_process(int fd, void* buffer, size_t len); void el_dap_data_process(void* buffer, size_t len); +int el_dap_work(uint8_t* base, size_t len); + void el_process_buffer_malloc(); void el_process_buffer_free(); diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 3572cc8..9a7536b 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,6 +1,6 @@ set(COMPONENT_ADD_INCLUDEDIRS "${PROJECT_PATH}") set(COMPONENT_SRCS main.c timer.c tcp_server.c usbip_server.c DAP_handle.c - kcp_server.c tcp_netconn.c uart_bridge.c wifi_handle.c) + uart_bridge.c wifi_handle.c) register_component() diff --git a/main/DAP_handle.c b/main/DAP_handle.c index 95f7731..4b26058 100644 --- a/main/DAP_handle.c +++ b/main/DAP_handle.c @@ -111,7 +111,7 @@ void handle_dap_data_request(usbip_stage2_header *header, uint32_t length) // Point to the beginning of the URB packet #if (USE_WINUSB == 1) - send_stage2_submit(header, 0, 0); + send_stage2_submit_data_fast(header, NULL, 0); // always send constant size buf -> cuz we don't care about the IN packet size // and to unify the style, we set aside the length of the section @@ -119,7 +119,7 @@ void handle_dap_data_request(usbip_stage2_header *header, uint32_t length) xTaskNotifyGive(kDAPTaskHandle); #else - send_stage2_submit(header, 0, 0); + send_stage2_submit_data_fast(header, NULL, 0); xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY); xTaskNotifyGive(kDAPTaskHandle); @@ -131,22 +131,6 @@ void handle_dap_data_request(usbip_stage2_header *header, uint32_t length) // send_stage2_submit(header, 0, 0); } -void handle_dap_data_response(usbip_stage2_header *header) -{ - return; - // int resLength = dap_respond & 0xFFFF; - // if (resLength) - // { - - // send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength); - // dap_respond = 0; - // } - // else - // { - // send_stage2_submit(header, 0, 0); - // } -} - void handle_swo_trace_response(usbip_stage2_header *header) { #if (SWO_FUNCTION_ENABLE == 1) @@ -261,54 +245,43 @@ void DAP_Thread(void *argument) } } -int fast_reply(uint8_t *buf, uint32_t length) +int fast_reply(uint8_t *buf, uint32_t length, int dap_req_num) { usbip_stage2_header *buf_header = (usbip_stage2_header *)buf; - if (length == 48 && - buf_header->base.command == PP_HTONL(USBIP_STAGE2_REQ_SUBMIT) && - buf_header->base.direction == PP_HTONL(USBIP_DIR_IN) && - buf_header->base.ep == PP_HTONL(1)) - { - if (dap_respond > 0) - { - DapPacket_t *item; - size_t packetSize = 0; - item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize, - pdMS_TO_TICKS(10), DAP_HANDLE_SIZE); - if (packetSize == DAP_HANDLE_SIZE) - { + + if (dap_req_num > 0) { + DapPacket_t *item; + size_t packetSize = 0; + item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize, + portMAX_DELAY, DAP_HANDLE_SIZE); + if (packetSize == DAP_HANDLE_SIZE) { #if (USE_WINUSB == 1) - send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, item->length); + send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, item->length); #else - send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, DAP_HANDLE_SIZE); + send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, DAP_HANDLE_SIZE); #endif - if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE) - { - --dap_respond; - xSemaphoreGive(data_response_mux); - } + if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE) { + --dap_respond; + xSemaphoreGive(data_response_mux); + } - vRingbufferReturnItem(dap_dataOUT_handle, (void *)item); - return 1; - } - else if (packetSize > 0) - { - os_printf("Wrong data out packet size:%d!\r\n", packetSize); - } - ////TODO: fast reply - } - else - { - buf_header->base.command = PP_HTONL(USBIP_STAGE2_RSP_SUBMIT); - buf_header->base.direction = PP_HTONL(USBIP_DIR_OUT); - buf_header->u.ret_submit.status = 0; - buf_header->u.ret_submit.data_length = 0; - buf_header->u.ret_submit.error_count = 0; - usbip_network_send(kSock, buf, 48, 0); + vRingbufferReturnItem(dap_dataOUT_handle, (void *)item); return 1; + } else if (packetSize > 0) { + os_printf("Wrong data out packet size:%d!\r\n", packetSize); } + ////TODO: fast reply + } else { + buf_header->base.command = PP_HTONL(USBIP_STAGE2_RSP_SUBMIT); + buf_header->base.direction = PP_HTONL(USBIP_DIR_OUT); + buf_header->u.ret_submit.status = 0; + buf_header->u.ret_submit.data_length = 0; + buf_header->u.ret_submit.error_count = 0; + usbip_network_send(kSock, buf, 48, 0); + return 1; } + return 0; } diff --git a/main/DAP_handle.h b/main/DAP_handle.h index a7871df..d32979c 100644 --- a/main/DAP_handle.h +++ b/main/DAP_handle.h @@ -11,10 +11,9 @@ enum reset_handle_t }; void handle_dap_data_request(usbip_stage2_header *header, uint32_t length); -void handle_dap_data_response(usbip_stage2_header *header); void handle_swo_trace_response(usbip_stage2_header *header); void handle_dap_unlink(); -int fast_reply(uint8_t *buf, uint32_t length); +int fast_reply(uint8_t *buf, uint32_t length, int dap_req_num); #endif \ No newline at end of file diff --git a/main/tcp_server.c b/main/tcp_server.c index 2e44308..dd990e8 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -34,15 +34,18 @@ extern TaskHandle_t kDAPTaskHandle; extern int kRestartDAPHandle; -uint8_t kState = ACCEPTING; int kSock = -1; void tcp_server_task(void *pvParameters) { uint8_t tcp_rx_buffer[1500]; char addr_str[128]; + enum usbip_server_state_t usbip_state = WAIT_DEVLIST; + uint8_t *data; int addr_family; int ip_protocol; + int header; + int ret, sz; int on = 1; while (1) @@ -111,75 +114,39 @@ void tcp_server_task(void *pvParameters) setsockopt(kSock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)); os_printf("Socket accepted\r\n"); - while (1) - { - int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0); - // Error occured during receiving - if (len < 0) - { - os_printf("recv failed: errno %d\r\n", errno); - break; - } - // Connection closed - else if (len == 0) - { - os_printf("Connection closed\r\n"); - break; - } - // Data received + // Read header + sz = 4; + data = &tcp_rx_buffer[0]; + do { + ret = recv(kSock, data, sz, 0); + if (ret <= 0) + goto cleanup; + sz -= ret; + data += ret; + } while (sz > 0); + + header = *((int *)(tcp_rx_buffer)); + header = ntohl(header); + + if (header == EL_LINK_IDENTIFIER) { + el_dap_work(tcp_rx_buffer, sizeof(tcp_rx_buffer)); + } else if ((header & 0xFFFF) == 0x8003 || + (header & 0xFFFF) == 0x8005) { // usbip OP_REQ_DEVLIST/OP_REQ_IMPORT + if ((header & 0xFFFF) == 0x8005) + usbip_state = WAIT_DEVLIST; else - { - // #ifdef CONFIG_EXAMPLE_IPV6 - // // Get the sender's ip address as string - // if (sourceAddr.sin6_family == PF_INET) - // { - // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); - // } - // else if (sourceAddr.sin6_family == PF_INET6) - // { - // inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); - // } - // #else - // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); - // #endif - - switch (kState) - { - case ACCEPTING: - kState = ATTACHING; - - case ATTACHING: - // elaphureLink handshake - if (el_handshake_process(kSock, tcp_rx_buffer, len) == 0) { - // handshake successed - kState = EL_DATA_PHASE; - kRestartDAPHandle = DELETE_HANDLE; - el_process_buffer_malloc(); - break; - } - - attach(tcp_rx_buffer, len); - break; - - case EMULATING: - emulate(tcp_rx_buffer, len); - break; - case EL_DATA_PHASE: - el_dap_data_process(tcp_rx_buffer, len); - break; - default: - os_printf("unkonw kstate!\r\n"); - } - } + usbip_state = WAIT_IMPORT; + usbip_worker(tcp_rx_buffer, sizeof(tcp_rx_buffer), &usbip_state); + } else { + os_printf("Unknown protocol\n"); } - // kState = ACCEPTING; + +cleanup: if (kSock != -1) { os_printf("Shutting down socket and restarting...\r\n"); //shutdown(kSock, 0); close(kSock); - if (kState == EMULATING || kState == EL_DATA_PHASE) - kState = ACCEPTING; // Restart DAP Handle el_process_buffer_free(); diff --git a/main/usbip_server.c b/main/usbip_server.c index e41c00f..585b6a6 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -28,8 +28,6 @@ static void send_interface_info(); // emulate helper function static void pack(void *data, int size); static void unpack(void *data, int size); -static int handle_submit(usbip_stage2_header *header, uint32_t length); -static int read_stage2_command(usbip_stage2_header *header, uint32_t length); static void handle_unlink(usbip_stage2_header *header); // unlink helper function @@ -45,7 +43,7 @@ int usbip_network_send(int s, const void *dataptr, size_t size, int flags) { #endif } -int attach(uint8_t *buffer, uint32_t length) +static int attach(uint8_t *buffer, uint32_t length) { int command = read_stage1_command(buffer, length); if (command < 0) @@ -102,8 +100,6 @@ static void handle_device_attach(uint8_t *buffer, uint32_t length) send_stage1_header(USBIP_STAGE1_CMD_DEVICE_ATTACH, 0); send_device_info(); - - kState = EMULATING; } static void send_stage1_header(uint16_t command, uint32_t status) @@ -181,57 +177,126 @@ static void send_interface_info() usbip_network_send(kSock, (uint8_t *)&interface, sizeof(usbip_stage1_usb_interface), 0); } -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// - -int emulate(uint8_t *buffer, uint32_t length) +static int usbip_urb_process(uint8_t *base, uint32_t length) { + usbip_stage2_header *header = (usbip_stage2_header *)base; + uint8_t *data; + uint32_t command, dir, ep; + uint32_t unlink_count = 0; + bool may_has_data; + int sz, ret; + int dap_req_num = 0; - if(fast_reply(buffer, length)) - { - return 0; + while (1) { + // header + data = base; + sz = 48; // for USBIP_CMD_SUBMIT/USBIP_CMD_UNLINK + do { + ret = recv(kSock, data, sz, 0); + if (ret <= 0) + goto out; + sz -= ret; + data += ret; + } while (sz > 0); + + command = ntohl(header->base.command); + dir = ntohl(header->base.direction); + ep = ntohl(header->base.ep); + may_has_data = (command == USBIP_STAGE2_REQ_SUBMIT && dir == USBIP_DIR_OUT); + sz = may_has_data ? ntohl(header->u.cmd_submit.data_length) : 0; + + while (sz) { + ret = recv(kSock, data, sz, 0); + if (ret <= 0) + goto out; + sz -= ret; + data += ret; + } + + if (likely(command == USBIP_STAGE2_REQ_SUBMIT)) { + if (likely(ep == 1 && dir == USBIP_DIR_IN)) { + fast_reply(base, sizeof(usbip_stage2_header), dap_req_num); + if (dap_req_num > 0) + dap_req_num--; + } else if (likely(ep == 1 && dir == USBIP_DIR_OUT)) { + dap_req_num++; + handle_dap_data_request(header, length); + } else if (ep == 0) { + unpack(base, sizeof(usbip_stage2_header)); + handleUSBControlRequest(header); + } else { + // ep3 reserved for SWO + os_printf("ep reserved:%d\r\n", ep); + send_stage2_submit(header, 0, 0); + } + } else if (command == USBIP_STAGE2_REQ_UNLINK) { + if (unlink_count == 0 || unlink_count % 100 == 0) + os_printf("unlink\r\n"); + unlink_count++; + unpack(base, sizeof(usbip_stage2_header)); + handle_unlink(header); + } else { + os_printf("emulate unknown command:%d\r\n", command); + return -1; + } } - int command = read_stage2_command((usbip_stage2_header *)buffer, length); - if (command < 0) - { - return -1; - } - - switch (command) - { - case USBIP_STAGE2_REQ_SUBMIT: - handle_submit((usbip_stage2_header *)buffer , length); - break; - - case USBIP_STAGE2_REQ_UNLINK: - handle_unlink((usbip_stage2_header *)buffer); - break; - - default: - os_printf("emulate unknown command:%d\r\n", command); - //handle_submit((usbip_stage2_header *)buffer, length); - return -1; - } - return 0; +out: + if (ret < 0) + os_printf("recv failed: errno %d\r\n", errno); + return ret; } -static int read_stage2_command(usbip_stage2_header *header, uint32_t length) +int usbip_worker(uint8_t *base, uint32_t length, enum usbip_server_state_t *state) { - if (length < sizeof(usbip_stage2_header)) - { - return -1; + uint8_t *data; + int pre_read_sz = 4; + int sz, ret; + + // OP_REQ_DEVLIST status field + if (*state == WAIT_DEVLIST) { + data = base + 4; + sz = 8 - pre_read_sz; + do { + ret = recv(kSock, data, sz, 0); + if (ret <= 0) + return ret; + sz -= ret; + data += ret; + } while (sz > 0); + + ret = attach(base, 8); + if (ret) + return ret; + + pre_read_sz = 0; } - //client.readBytes((uint8_t *)&header, sizeof(usbip_stage2_header)); - unpack((uint32_t *)header, sizeof(usbip_stage2_header)); - return header->base.command; + *state = WAIT_IMPORT; + // OP_REQ_IMPORT + data = base + pre_read_sz; + sz = 40 - pre_read_sz; + do { + ret = recv(kSock, data, sz, 0); + if (ret <= 0) + return ret; + sz -= ret; + data += ret; + } while (sz > 0); + + ret = attach(base, 40); + if (ret) + return ret; + + // URB process + *state = WAIT_URB; + ret = usbip_urb_process(base, length); + if (ret) { + *state = WAIT_DEVLIST; + return ret; + } + + return 0; } /** @@ -281,65 +346,6 @@ static void unpack(void *data, int size) } } -/** - * @brief USB transaction processing - * - */ -static int handle_submit(usbip_stage2_header *header, uint32_t length) -{ - switch (header->base.ep) - { - // control endpoint(endpoint 0) - case 0x00: - //// TODO: judge usb setup 8 byte? - handleUSBControlRequest(header); - break; - - // endpoint 1 data receicve and response - case 0x01: - if (header->base.direction == 0) - { - //os_printf("EP 01 DATA FROM HOST"); - handle_dap_data_request(header ,length); - } - else - { - // os_printf("EP 01 DATA TO HOST\r\n"); - handle_dap_data_response(header); - } - break; - // endpoint 2 for SWO trace - case 0x02: - if (header->base.direction == 0) - { - // os_printf("EP 02 DATA FROM HOST"); - send_stage2_submit(header, 0, 0); - } - else - { - // os_printf("EP 02 DATA TO HOST"); - handle_swo_trace_response(header); - } - break; - // request to save data to device - case 0x81: - if (header->base.direction == 0) - { - os_printf("*** WARN! EP 81 DATA TX"); - } - else - { - os_printf("*** WARN! EP 81 DATA RX"); - } - return -1; - - default: - os_printf("*** WARN ! UNKNOWN ENDPOINT: %d\r\n", (int)header->base.ep); - return -1; - } - return 0; -} - void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length) { @@ -376,16 +382,15 @@ void send_stage2_submit_data_fast(usbip_stage2_header *req_header, const void *c memset(&(req_header->u.ret_submit), 0, sizeof(usbip_stage2_header_ret_submit)); req_header->u.ret_submit.data_length = htonl(data_length); - // payload - memcpy(&send_buf[sizeof(usbip_stage2_header)], data, data_length); + if (data) + memcpy(&send_buf[sizeof(usbip_stage2_header)], data, data_length); usbip_network_send(kSock, send_buf, sizeof(usbip_stage2_header) + data_length, 0); } static void handle_unlink(usbip_stage2_header *header) { - os_printf("s2 handling cmd unlink...\r\n"); handle_dap_unlink(); send_stage2_unlink(header); } @@ -407,4 +412,4 @@ static void send_stage2_unlink(usbip_stage2_header *req_header) pack(req_header, sizeof(usbip_stage2_header)); usbip_network_send(kSock, req_header, sizeof(usbip_stage2_header), 0); -} \ No newline at end of file +} diff --git a/main/usbip_server.h b/main/usbip_server.h index 5bfc296..0925ec7 100644 --- a/main/usbip_server.h +++ b/main/usbip_server.h @@ -5,18 +5,16 @@ #include "components/USBIP/usbip_defs.h" -enum state_t +enum usbip_server_state_t { - ACCEPTING, - ATTACHING, - EMULATING, - EL_DATA_PHASE + WAIT_DEVLIST = 0, + WAIT_IMPORT, + WAIT_URB, }; -extern uint8_t kState; + extern int kSock; -int attach(uint8_t *buffer, uint32_t length); -int emulate(uint8_t *buffer, uint32_t length); +int usbip_worker(uint8_t *base, uint32_t length, enum usbip_server_state_t *state); void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, const void * const data, int32_t data_length); void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length); void send_stage2_submit_data_fast(usbip_stage2_header *req_header, const void *const data, int32_t data_length); From fa3e6ec92fab9328cd6e9a2c6a4ac687f6bf055a Mon Sep 17 00:00:00 2001 From: windowsair Date: Fri, 16 Feb 2024 19:22:10 +0800 Subject: [PATCH 5/5] fix: fix compile error --- main/usbip_server.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/main/usbip_server.c b/main/usbip_server.c index 585b6a6..8a970bd 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -15,6 +15,13 @@ #include "lwip/sys.h" #include +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif + +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif // attach helper function static int read_stage1_command(uint8_t *buffer, uint32_t length);