22 changed files with 506 additions and 76 deletions
-
6.vscode/settings.json
-
2LWIP/Target/ethernetif.c
-
18README.md
-
11iflytop_xsync/iflytop_xsync.h
-
99iflytop_xsync/xs_flash.c
-
59iflytop_xsync/xs_flash.h
-
31iflytop_xsync/xs_id.c
-
12iflytop_xsync/xs_id.h
-
36iflytop_xsync/xs_log.h
-
0iflytop_xsync_protocol/iflytop_xsync_protocol.c
-
83iflytop_xsync_protocol/iflytop_xsync_protocol.h
-
4usrc/base_service/base_service.h
-
52usrc/base_service/config_service.c
-
30usrc/base_service/config_service.h
-
0usrc/base_service/mac_generator.h
-
36usrc/main.cpp
-
12usrc/project_dep.h
-
8usrc/service/device.cpp
-
0usrc/service/device.hpp
-
3xsync_stm32.ioc
@ -0,0 +1,99 @@ |
|||
#include "xs_flash.h" |
|||
#include "xs_log.h" |
|||
#include <stdbool.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
static uint32_t* _rawstartadd; |
|||
static uint32_t* _defaultdata; |
|||
static uint32_t _rawsize; |
|||
static bool _is_first_run = false; |
|||
|
|||
static bool _xs_check_raw_data() { |
|||
uint32_t checksum = 0; |
|||
ZLOGI("flash", "_rawstartadd[0] = %x", _rawstartadd[0]); |
|||
if (_rawstartadd[0] != FLASH_MASK_VAL) { |
|||
return false; |
|||
} |
|||
for (uint32_t i = 0; i < _rawsize - 1; i++) { |
|||
checksum += _rawstartadd[i]; |
|||
} |
|||
if (checksum != _rawstartadd[_rawsize - 1]) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
static HAL_StatusTypeDef _flash_erase(void) { |
|||
HAL_StatusTypeDef status; |
|||
uint32_t sector_error_point; |
|||
FLASH_EraseInitTypeDef flash_erase_structer = { |
|||
// |
|||
.TypeErase = FLASH_TYPEERASE_SECTORS, // |
|||
.Sector = FLASH_EARSE_SECTOR, // |
|||
.NbSectors = 1, // |
|||
.VoltageRange = FLASH_VOLTAGE_RANGE_3 // |
|||
}; |
|||
|
|||
HAL_FLASH_Unlock(); // 解锁 |
|||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); // 清除一些错误标志 |
|||
status = HAL_FLASHEx_Erase(&flash_erase_structer, §or_error_point); |
|||
if (status != HAL_OK) { |
|||
ZLOGE("flash", "erase error"); |
|||
} |
|||
HAL_FLASH_Lock(); // 上锁 |
|||
return status; |
|||
} |
|||
/******************************************************************************* |
|||
* EXTERN * |
|||
*******************************************************************************/ |
|||
|
|||
void xs_flash_init(uint32_t* rawstartadd, uint32_t* defaultdata, uint32_t rawsize) { |
|||
_rawstartadd = rawstartadd; |
|||
_defaultdata = defaultdata; |
|||
_rawsize = rawsize; |
|||
|
|||
// 读取flash数据 |
|||
memcpy(_rawstartadd, (uint32_t*)(FLASH_START_ADD), _rawsize); |
|||
|
|||
// 校验数据 |
|||
if (_xs_check_raw_data()) { |
|||
return; |
|||
} |
|||
_is_first_run = true; |
|||
xs_flash_factory_reset(); |
|||
|
|||
// 初始化flash数据 |
|||
} |
|||
|
|||
bool xs_flash_is_first_run(void) { return _is_first_run; } |
|||
|
|||
uint32_t xs_compute_checksum(uint32_t* data, uint32_t size) { |
|||
uint32_t checksum = 0; |
|||
for (uint32_t i = 0; i < size; i++) { |
|||
checksum += data[i]; |
|||
} |
|||
return checksum; |
|||
} |
|||
bool xs_flash_factory_reset(void) { |
|||
memcpy(_rawstartadd, _defaultdata, _rawsize * 4); |
|||
xs_flash_flush(); |
|||
return true; |
|||
} |
|||
|
|||
bool xs_flash_flush(void) { |
|||
_rawstartadd[0] = FLASH_MASK_VAL; |
|||
_rawstartadd[_rawsize - 1] = xs_compute_checksum(_rawstartadd, _rawsize - 1); |
|||
|
|||
_flash_erase(); |
|||
HAL_FLASH_Unlock(); // 解锁 |
|||
HAL_StatusTypeDef status; |
|||
for (uint32_t i = 0; i < _rawsize; i++) { |
|||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_START_ADD + i * 4, _rawstartadd[i]); |
|||
if (status != HAL_OK) { |
|||
ZLOGE("flash", "write error"); |
|||
} |
|||
} |
|||
HAL_FLASH_Lock(); // 上锁 |
|||
return true; |
|||
} |
@ -0,0 +1,59 @@ |
|||
#pragma once |
|||
#include <stdbool.h> |
|||
|
|||
#include "main.h" |
|||
|
|||
/** |
|||
* @brief |
|||
* STM32F407VETx 512k |
|||
* |
|||
* index startAdd size |
|||
* 0 0x08000000 16k |
|||
* 1 0x08004000 16k |
|||
* 2 0x08008000 16k |
|||
* 3 0x0800C000 16k |
|||
* 4 0x08010000 64k |
|||
* 5 0x08020000 128k |
|||
* 6 0x08040000 128k |
|||
* 7 0x08060000 128k |
|||
* |
|||
* |
|||
* @WARNING: |
|||
* 1. 我们使用第7个扇区,即0x08060000~0x0807FFFF |
|||
* 2. 程序最大不能超过75% |
|||
* 3. rawstartadd第一位必须是0xABCD,最后一位是校验和 |
|||
*/ |
|||
|
|||
#define FLASH_MASK_VAL 0xABCD |
|||
#define FLASH_START_ADD 0x08078000 // |
|||
#define FLASH_EARSE_SECTOR FLASH_SECTOR_7 |
|||
|
|||
/** |
|||
* @brief 初始化flash |
|||
* |
|||
* @param rawstartadd flash内存映射的地址 |
|||
* @param defaultdata 默认数据 |
|||
* @param rawsize flash内存映射的地址大小 |
|||
*/ |
|||
void xs_flash_init(uint32_t* rawstartadd, uint32_t* defaultdata, uint32_t rawsize); |
|||
/** |
|||
* @brief 判断是否是第一次初始化flash |
|||
* |
|||
* @return true |
|||
* @return false |
|||
*/ |
|||
bool xs_flash_is_first_run(void); |
|||
/** |
|||
* @brief 刷新内存输出到flash中 |
|||
* |
|||
* @return true |
|||
* @return false |
|||
*/ |
|||
bool xs_flash_flush(void); |
|||
/** |
|||
* @brief 恢复出厂设置 |
|||
* |
|||
* @return true |
|||
* @return false |
|||
*/ |
|||
bool xs_flash_factory_reset(void); |
@ -0,0 +1,31 @@ |
|||
#include "xs_id.h" |
|||
|
|||
#include "main.h" |
|||
#include "rng.h" |
|||
|
|||
extern RNG_HandleTypeDef hrng; |
|||
|
|||
void xs_id_generate_random_mac(mac_t* id) { |
|||
id->mac[0] = 0x00; // 00 80 E1 ÊÇSTM32µÄMACµØÖ·Ç°Èýλ |
|||
id->mac[1] = 0x80; |
|||
id->mac[2] = 0xE1; |
|||
|
|||
uint32_t random0 = 0; |
|||
uint32_t random1 = 0; |
|||
uint32_t random2 = 0; |
|||
HAL_RNG_GenerateRandomNumber(&hrng, &random0); |
|||
HAL_RNG_GenerateRandomNumber(&hrng, &random1); |
|||
HAL_RNG_GenerateRandomNumber(&hrng, &random2); |
|||
|
|||
id->mac[3] = random0 % 256; |
|||
id->mac[4] = random1 % 256; |
|||
id->mac[5] = random2 % 256; |
|||
} |
|||
void xs_id_get_uuid(device_id_t* id) { |
|||
// UID_BASE |
|||
uint8_t* uid_base = (uint8_t*)UID_BASE; |
|||
for (int32_t i = 0; i < 12; i++) { |
|||
id->id[i] = uid_base[i]; |
|||
} |
|||
return; |
|||
} |
@ -0,0 +1,12 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
typedef struct { |
|||
uint8_t mac[6]; |
|||
} mac_t; |
|||
|
|||
typedef struct { |
|||
uint8_t id[12]; // 96bit |
|||
} device_id_t; |
|||
|
|||
void xs_id_generate_random_mac(mac_t* id); |
|||
void xs_id_get_uuid(device_id_t* id); |
@ -0,0 +1,83 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
|
|||
/** |
|||
* @brief XSYNC协议端口 |
|||
*/ |
|||
#define IFLYTOP_XSYNC_PORT 19973 |
|||
|
|||
/** |
|||
* @brief |
|||
* 协议说明 |
|||
* |
|||
* kxsync_packet_type_reg_read: |
|||
* tx: regadd |
|||
* rx: ecode,regdata |
|||
* |
|||
* kxsync_packet_type_reg_write |
|||
* tx: regadd,regdata |
|||
* rx: ecode,regdata |
|||
* |
|||
* kxsync_packet_type_reg_read_regs |
|||
* tx: regstartadd,nreg |
|||
* rx: ecode,regdatas |
|||
* |
|||
*/ |
|||
typedef enum { |
|||
kxsync_packet_type_none = 0, |
|||
kxsync_packet_type_reg_read = 1, |
|||
kxsync_packet_type_reg_write = 2, |
|||
kxsync_packet_type_reg_read_regs = 3, |
|||
} xsync_protocol_cmd_t; |
|||
|
|||
typedef enum { |
|||
kxsync_packet_type_cmd = 0, |
|||
kxsync_packet_type_receipt = 1, |
|||
} xsync_protocol_packet_type_t; |
|||
|
|||
#pragma pack(1) |
|||
|
|||
typedef struct { |
|||
uint16_t type; |
|||
uint16_t index; |
|||
uint16_t cmd; |
|||
uint16_t ndata; |
|||
uint32_t data[]; // first is always checksum |
|||
/*uint8_t checksum*/ |
|||
} iflytop_xsync_packet_header_t; |
|||
|
|||
#define XYSNC_REG_DEVICE_INFO_START_ADD 0 |
|||
#define XYSNC_REG_STM32_CONFIG_START_ADD 16 |
|||
|
|||
typedef enum { |
|||
/** |
|||
* @brief |
|||
* REG 0(16) 设备信息基础寄存器 |
|||
*/ |
|||
kxsync_reg_software_version = 0, |
|||
kxsync_reg_manufacturer = 1, |
|||
kxsync_reg_product_type_id = 2, |
|||
|
|||
/** |
|||
* @brief |
|||
* REG 16(32) STM32配置寄存器0 |
|||
*/ |
|||
kxsync_reg_stm32_obtaining_ip_mode = XYSNC_REG_STM32_CONFIG_START_ADD + 0, |
|||
kxsync_reg_stm32_ip = XYSNC_REG_STM32_CONFIG_START_ADD + 1, |
|||
kxsync_reg_stm32_gw = XYSNC_REG_STM32_CONFIG_START_ADD + 2, |
|||
kxsync_reg_stm32_netmask = XYSNC_REG_STM32_CONFIG_START_ADD + 3, |
|||
|
|||
} xsync_reg_add_t; |
|||
|
|||
typedef enum { obtaining_ip_mode_type_static = 0, obtaining_ip_mode_type_dhcp = 1 } obtaining_ip_mode_t; |
|||
static inline const char* obtaining_ip_mode_to_string(obtaining_ip_mode_t mode) { |
|||
switch (mode) { |
|||
case obtaining_ip_mode_type_static: |
|||
return "static"; |
|||
case obtaining_ip_mode_type_dhcp: |
|||
return "dhcp"; |
|||
default: |
|||
return "unknown"; |
|||
} |
|||
} |
|||
#pragma pack() |
@ -0,0 +1,4 @@ |
|||
#pragma once |
|||
#include "project_dep.h" |
|||
// |
|||
#include "config_service.h" |
@ -0,0 +1,52 @@ |
|||
#include "config_service.h" |
|||
|
|||
#include "project_dep.h" |
|||
|
|||
static config_t _config; |
|||
static config_t _default_val_config; |
|||
|
|||
#define TAG "config" |
|||
static void dump_config(config_t *pcfg) { |
|||
ZLOGI(TAG, "=============== config ==============="); |
|||
ZLOGI(TAG, "obtaining_ip_mode : %s", obtaining_ip_mode_to_string(pcfg->obtaining_ip_mode)); |
|||
ZLOGI(TAG, "ip : %s", inet_ntoa(pcfg->ip)); |
|||
ZLOGI(TAG, "gw : %s", inet_ntoa(pcfg->gw)); |
|||
ZLOGI(TAG, "netmask : %s", inet_ntoa(pcfg->netmask)); |
|||
ZLOGI(TAG, "mac : %02x:%02x:%02x:%02x:%02x:%02x", pcfg->mac[0], pcfg->mac[1], pcfg->mac[2], pcfg->mac[3], pcfg->mac[4], pcfg->mac[5]); |
|||
ZLOGI(TAG, "======================================"); |
|||
} |
|||
static void create_default_config() { // |
|||
_default_val_config.config_mark = FLASH_MASK_VAL; |
|||
IP4_ADDR((ip4_addr_t *)&_default_val_config.ip, 192, 168, 8, 10); |
|||
IP4_ADDR((ip4_addr_t *)&_default_val_config.gw, 192, 168, 8, 1); |
|||
IP4_ADDR((ip4_addr_t *)&_default_val_config.netmask, 255, 255, 255, 0); |
|||
_default_val_config.obtaining_ip_mode = obtaining_ip_mode_type_static; // dhcp |
|||
|
|||
static mac_t mac; |
|||
xs_id_generate_random_mac(&mac); |
|||
memcpy(&_default_val_config.mac[0], mac.mac, 6); |
|||
ZLOGD(TAG, "random mac is %02x:%02x:%02x:%02x:%02x:%02x", mac.mac[0], mac.mac[1], mac.mac[2], mac.mac[3], mac.mac[4], mac.mac[5]); |
|||
dump_config(&_default_val_config); |
|||
} |
|||
|
|||
void config_init(void) { |
|||
/** |
|||
* @brief 构造默认配置 |
|||
*/ |
|||
create_default_config(); |
|||
/** |
|||
* @brief flash初始化 |
|||
*/ |
|||
xs_flash_init(&_config, &_default_val_config, sizeof(config_t) / 4); |
|||
|
|||
ZLOGI(TAG, "xs_flash_is_first_run: %d", xs_flash_is_first_run()); |
|||
ZLOGI(TAG, ""); |
|||
|
|||
/** |
|||
* @brief 打印配置信息 |
|||
*/ |
|||
dump_config(&_config); |
|||
} |
|||
config_t *config_get(void) { return &_config; } |
|||
void config_flush(void) { return xs_flash_flush(); } |
|||
void config_factory_reset(void) { xs_flash_factory_reset(); } |
@ -0,0 +1,30 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
|
|||
#include "iflytop_xsync\iflytop_xsync.h" |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
typedef struct { |
|||
uint32_t config_mark; |
|||
|
|||
uint32_t obtaining_ip_mode; |
|||
uint32_t ip; |
|||
uint32_t gw; |
|||
uint32_t netmask; |
|||
|
|||
uint8_t mac[8]; // mac[5:0] is mac, mac[7:6] is pad for 32bit align |
|||
|
|||
uint32_t checksum; // ²»ÐèÒª±à¼ |
|||
} config_t; |
|||
|
|||
void config_init(void); |
|||
config_t* config_get(void); |
|||
void config_flush(void); |
|||
void config_factory_reset(void); |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
@ -1,24 +1,44 @@ |
|||
#include <stddef.h>
|
|||
#include <stdio.h>
|
|||
|
|||
#include "device.hpp"
|
|||
#include "project_configs.h"
|
|||
//
|
|||
#include "base_service/base_service.h"
|
|||
//
|
|||
#define TAG "main"
|
|||
using namespace iflytop; |
|||
using namespace std; |
|||
|
|||
extern void umain(); |
|||
extern "C" { |
|||
extern void MX_LWIP_Init(void); |
|||
void StartDefaultTask(void const* argument) { |
|||
MX_LWIP_Init(); |
|||
// MX_LWIP_Init();
|
|||
umain(); |
|||
} |
|||
} |
|||
/*******************************************************************************
|
|||
* MAIN * |
|||
*******************************************************************************/ |
|||
|
|||
xs_gpio_t m_debug_led; |
|||
|
|||
void umain() { |
|||
XS_LOGI(TAG, "%s:%s", PC_PROJECT_NAME, PC_VERSION); |
|||
/**
|
|||
* @brief µ÷ÊÔָʾµÆ³õʼ»¯ |
|||
*/ |
|||
xs_gpio_init_as_output(&m_debug_led, PC_DEBUG_LIGHT_GPIO, kxs_gpio_nopull, false, false); |
|||
|
|||
/**
|
|||
* @brief ÅäÖóõʼ»¯ |
|||
*/ |
|||
|
|||
config_init(); |
|||
|
|||
|
|||
Device device; |
|||
void umain() { |
|||
device.init(); |
|||
device.loop(); |
|||
while (true) { |
|||
xs_gpio_write(&m_debug_led, true); |
|||
xs_delay_ms(100); |
|||
xs_gpio_write(&m_debug_led, false); |
|||
xs_delay_ms(100); |
|||
} |
|||
} |
@ -0,0 +1,12 @@ |
|||
#pragma once |
|||
|
|||
#include <lwip/sockets.h> |
|||
|
|||
#include "project_configs.h" |
|||
|
|||
#include "lwip/api.h" |
|||
#include "lwip/opt.h" |
|||
#include "lwip/sys.h" |
|||
|
|||
#include "iflytop_xsync_protocol\iflytop_xsync_protocol.h" |
|||
#include "iflytop_xsync\iflytop_xsync.h" |
Write
Preview
Loading…
Cancel
Save
Reference in new issue