144 lines
4.4 KiB
C
144 lines
4.4 KiB
C
/**
|
|
* @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 <stddef.h> /* 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;
|
|
}
|