/** * @file qdx_port_template.c * @brief Template Implementation of the HAL Port for QDX Network Stack * * Instructions: * 1. Rename this file to qdx_port.c in your MCU project. * 2. Implement these functions using your specific OS/Network APIs * (e.g., LwIP, FreeRTOS, RT-Thread, CMSIS-OS). * 3. Ensure qdx_port_tcp_recv is non-blocking or uses a short timeout, * so the background thread can periodically check connection status. */ #include "qdx_port.h" #include /* For NULL */ /* Include your system headers here * #include "FreeRTOS.h" * #include "task.h" * #include "lwip/sockets.h" * #include "lwip/sys.h" */ /* ============================================================ * Time & Delay * ============================================================ */ uint32_t qdx_port_get_tick_ms(void) { /* TODO: Return current system uptime in milliseconds. * Example (FreeRTOS): return (uint32_t)(xTaskGetTickCount() * * portTICK_PERIOD_MS); Example (HAL): return HAL_GetTick(); */ return 0; } void qdx_port_delay_ms(uint32_t ms) { /* TODO: Block current thread for ms milliseconds. * Example (FreeRTOS): vTaskDelay(pdMS_TO_TICKS(ms)); * Example (HAL): HAL_Delay(ms); */ } /* ============================================================ * Network (TCP Socket) * ============================================================ */ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port) { /* TODO: Create socket and connect to IP:PORT. * Example (LwIP/BSD Sockets): * int sock = socket(AF_INET, SOCK_STREAM, 0); * if (sock < 0) return NULL; * struct sockaddr_in dest_addr; * dest_addr.sin_addr.s_addr = inet_addr(ip); * dest_addr.sin_family = AF_INET; * dest_addr.sin_port = htons(port); * if (connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) == 0) * { * // Optional: Set receive timeout * return (qdx_socket_t)(intptr_t)sock; * } * close(sock); */ return NULL; } void qdx_port_tcp_close(qdx_socket_t sock) { /* TODO: Close the socket gracefully. * Example: * if (sock) { * close((int)(intptr_t)sock); * } */ } int32_t qdx_port_tcp_send(qdx_socket_t sock, const uint8_t *data, uint32_t len) { /* TODO: Send data through the socket. * Example: * if (!sock) return -1; * return send((int)(intptr_t)sock, data, len, 0); */ return -1; } int32_t qdx_port_tcp_recv(qdx_socket_t sock, uint8_t *buf, uint32_t max_len) { /* TODO: Receive data from the socket. * Should return actual bytes read. If no bytes are available (timeout), * return 0. If socket is closed or an error occurs, return < 0. Example: if * (!sock) return -1; * // Assume socket was set with SO_RCVTIMEO to prevent hanging forever * int bytes = recv((int)(intptr_t)sock, buf, max_len, 0); * if (bytes < 0) { * if (errno == EAGAIN || errno == EWOULDBLOCK) return 0; // Timeout * return -1; // Actual error * } * return bytes; // Includes bytes == 0 (graceful close) -> might want to * map to -1 */ return -1; } /* ============================================================ * Mutex & Threading * ============================================================ */ qdx_mutex_t qdx_port_mutex_create(void) { /* TODO: Create and return a mutex handle. * Example (FreeRTOS): * SemaphoreHandle_t mutex = xSemaphoreCreateMutex(); * return (qdx_mutex_t)mutex; */ return NULL; } void qdx_port_mutex_lock(qdx_mutex_t mutex) { /* TODO: Lock the given mutex. * Example (FreeRTOS): * if (mutex) xSemaphoreTake((SemaphoreHandle_t)mutex, portMAX_DELAY); */ } void qdx_port_mutex_unlock(qdx_mutex_t mutex) { /* TODO: Unlock the given mutex. * Example (FreeRTOS): * if (mutex) xSemaphoreGive((SemaphoreHandle_t)mutex); */ } void qdx_port_mutex_delete(qdx_mutex_t mutex) { /* TODO: Delete the given mutex. * Example (FreeRTOS): * if (mutex) vSemaphoreDelete((SemaphoreHandle_t)mutex); */ } int8_t qdx_port_thread_create(const char *name, qdx_thread_entry_t entry, void *arg, uint32_t stack_size, uint8_t priority) { /* TODO: Create a background thread/task to run the entry function. * Example (FreeRTOS): * BaseType_t res = xTaskCreate(entry, name, stack_size / * sizeof(StackType_t), arg, priority, NULL); return (res == pdPASS) ? 0 : -1; */ return -1; }