feat: 完成TCP2UART透传核心集成
集成CH390驱动、LwIP协议栈和FreeRTOS多任务透传框架,确保TCP Server/Client与UART链路按配置稳定联动。
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* @file flash_param.c
|
||||
* @brief Flash parameter storage module implementation
|
||||
*/
|
||||
|
||||
#include "flash_param.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Private Definitions
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/* CRC32 polynomial (IEEE 802.3) */
|
||||
#define CRC32_POLYNOMIAL 0xEDB88320
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Private Variables
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/* CRC32 lookup table */
|
||||
static uint32_t g_crc_table[256];
|
||||
static bool g_crc_table_initialized = false;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Private Functions
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize CRC32 lookup table
|
||||
*/
|
||||
static void crc32_init_table(void)
|
||||
{
|
||||
uint32_t i, j, crc;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
crc = i;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (crc & 1)
|
||||
{
|
||||
crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
g_crc_table[i] = crc;
|
||||
}
|
||||
|
||||
g_crc_table_initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlock Flash for writing
|
||||
*/
|
||||
static HAL_StatusTypeDef flash_unlock(void)
|
||||
{
|
||||
return HAL_FLASH_Unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock Flash after writing
|
||||
*/
|
||||
static void flash_lock(void)
|
||||
{
|
||||
HAL_FLASH_Lock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase Flash page
|
||||
*/
|
||||
static HAL_StatusTypeDef flash_erase_page(uint32_t page_addr)
|
||||
{
|
||||
FLASH_EraseInitTypeDef erase_init;
|
||||
uint32_t page_error;
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
erase_init.PageAddress = page_addr;
|
||||
erase_init.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&erase_init, &page_error);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program Flash half-word (16-bit)
|
||||
*/
|
||||
static HAL_StatusTypeDef flash_program_halfword(uint32_t addr, uint16_t data)
|
||||
{
|
||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr, data);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Public Functions
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize Flash parameter storage
|
||||
*/
|
||||
int flash_param_init(void)
|
||||
{
|
||||
/* Initialize CRC table */
|
||||
if (!g_crc_table_initialized)
|
||||
{
|
||||
crc32_init_table();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read parameters from Flash
|
||||
*/
|
||||
int flash_param_read(void *data, uint32_t len)
|
||||
{
|
||||
if (data == NULL || len == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if length exceeds available space */
|
||||
if (len > FLASH_PARAM_PAGE_SIZE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Direct memory read from Flash */
|
||||
memcpy(data, (const void *)FLASH_PARAM_START_ADDR, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write parameters to Flash
|
||||
*/
|
||||
int flash_param_write(const void *data, uint32_t len)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
uint32_t addr;
|
||||
const uint8_t *src;
|
||||
uint16_t halfword;
|
||||
uint32_t i;
|
||||
|
||||
if (data == NULL || len == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if length exceeds available space */
|
||||
if (len > FLASH_PARAM_PAGE_SIZE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Unlock Flash */
|
||||
status = flash_unlock();
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Erase the page */
|
||||
status = flash_erase_page(FLASH_PARAM_START_ADDR);
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
flash_lock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Program Flash (half-word at a time for STM32F1) */
|
||||
addr = FLASH_PARAM_START_ADDR;
|
||||
src = (const uint8_t *)data;
|
||||
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
/* Build half-word (little-endian) */
|
||||
halfword = src[i];
|
||||
if (i + 1 < len)
|
||||
{
|
||||
halfword |= ((uint16_t)src[i + 1]) << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
halfword |= 0xFF00; /* Pad with 0xFF */
|
||||
}
|
||||
|
||||
status = flash_program_halfword(addr, halfword);
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
flash_lock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr += 2;
|
||||
}
|
||||
|
||||
/* Lock Flash */
|
||||
flash_lock();
|
||||
|
||||
/* Verify write */
|
||||
if (memcmp((const void *)FLASH_PARAM_START_ADDR, data, len) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase parameter storage area
|
||||
*/
|
||||
int flash_param_erase(void)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Unlock Flash */
|
||||
status = flash_unlock();
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Erase the page */
|
||||
status = flash_erase_page(FLASH_PARAM_START_ADDR);
|
||||
|
||||
/* Lock Flash */
|
||||
flash_lock();
|
||||
|
||||
return (status == HAL_OK) ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate CRC32
|
||||
*/
|
||||
uint32_t flash_param_crc32(const void *data, uint32_t len)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)data;
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
uint32_t i;
|
||||
|
||||
/* Initialize table if needed */
|
||||
if (!g_crc_table_initialized)
|
||||
{
|
||||
crc32_init_table();
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
crc = g_crc_table[(crc ^ p[i]) & 0xFF] ^ (crc >> 8);
|
||||
}
|
||||
|
||||
return crc ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Verify parameter storage integrity
|
||||
*/
|
||||
int flash_param_verify(void)
|
||||
{
|
||||
uint32_t magic;
|
||||
|
||||
/* Read magic number */
|
||||
memcpy(&magic, (const void *)FLASH_PARAM_START_ADDR, sizeof(magic));
|
||||
|
||||
/* Check if Flash is erased (all 0xFF) */
|
||||
if (magic == 0xFFFFFFFF)
|
||||
{
|
||||
return -1; /* Empty/erased */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user