Commit 87be42b7 authored by 时昊's avatar 时昊

Merge branch 'shihao_esp32' of...

Merge branch 'shihao_esp32' of http://tyw-server.synology.me:12345/rt200t/rt200t_esp32 into shihao_esp32
parent 2429b9a8
FROM espressif/idf
ARG DEBIAN_FRONTEND=nointeractive
ARG CONTAINER_USER=esp
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN apt-get update \
&& apt install -y -q \
cmake \
git \
libglib2.0-0 \
libnuma1 \
libpixman-1-0 \
&& rm -rf /var/lib/apt/lists/*
# QEMU
ENV QEMU_REL=esp_develop_8.2.0_20240122
ENV QEMU_SHA256=e7c72ef5705ad1444d391711088c8717fc89f42e9bf6d1487f9c2a326b8cfa83
ENV QEMU_DIST=qemu-xtensa-softmmu-${QEMU_REL}-x86_64-linux-gnu.tar.xz
ENV QEMU_URL=https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/${QEMU_DIST}
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
RUN wget --no-verbose ${QEMU_URL} \
&& echo "${QEMU_SHA256} *${QEMU_DIST}" | sha256sum --check --strict - \
&& tar -xf $QEMU_DIST -C /opt \
&& rm ${QEMU_DIST}
ENV PATH=/opt/qemu/bin:${PATH}
RUN groupadd --gid $USER_GID $CONTAINER_USER \
&& adduser --uid $USER_UID --gid $USER_GID --disabled-password --gecos "" ${CONTAINER_USER} \
&& usermod -a -G root $CONTAINER_USER && usermod -a -G dialout $CONTAINER_USER
RUN chmod -R 775 /opt/esp/python_env/
USER ${CONTAINER_USER}
ENV USER=${CONTAINER_USER}
WORKDIR /home/${CONTAINER_USER}
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
CMD ["/bin/bash", "-c"]
\ No newline at end of file
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/ubuntu
{
"name": "ESP-IDF QEMU",
"build": {
"dockerfile": "Dockerfile"
},
// Add the IDs of extensions you want installed when the container is created
"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind",
/* the path of workspace folder to be opened after container is running
*/
"workspaceFolder": "${localWorkspaceFolder}",
"mounts": [
"source=extensionCache,target=/root/.vscode-server/extensions,type=volume"
],
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"idf.espIdfPath": "/opt/esp/idf",
"idf.customExtraPaths": "",
"idf.pythonBinPath": "/opt/esp/python_env/idf5.3_py3.10_env/bin/python",
"idf.toolsPath": "/opt/esp",
"idf.gitPath": "/usr/bin/git"
},
"extensions": [
"espressif.esp-idf-extension"
],
},
"codespaces": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"idf.espIdfPath": "/opt/esp/idf",
"idf.customExtraPaths": "",
"idf.pythonBinPath": "/opt/esp/python_env/idf5.3_py3.10_env/bin/python",
"idf.toolsPath": "/opt/esp",
"idf.gitPath": "/usr/bin/git"
},
"extensions": [
"espressif.esp-idf-extension"
],
}
},
"runArgs": ["--privileged"]
}
\ No newline at end of file
......@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common "./source/wifi" )
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(RT200T-2)
# Name, Type, SubType, Offset, Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs, data, nvs, , 0x4000,
otadata, data, ota, , 0x2000,
phy_init, data, phy, , 0x1000,
ota_0, app, ota_0, , 0x800K,
ota_1, app, ota_1, , 0x800K,
\ No newline at end of file
nvs, data, nvs, , 0x4000,
otadata, data, ota, , 0x2000,
phy_init, data, phy, , 0x1000,
ota_0, app, ota_0, , 0x800K,
ota_1, app, ota_1, , 0x800K,
assert, data, spiffs, , 300K,
\ No newline at end of file
# Embed the server root certificate into the final binary
# Embed the server root certificate into the final binary "simple_ota_example.c"
idf_build_get_property(project_dir PROJECT_DIR)
idf_component_register(SRCS "app_BT_User.c" "bt_app_main.c" "bt_app_hf.c" "bt_app_core.c" "gatts_table_creat_demo.c"
"simple_ota_example.c"
idf_component_register(SRCS "mcudata.c" "app_BT_User.c" "bt_app_main.c" "bt_app_hf.c" "bt_app_core.c" "gatts_table_creat_demo.c"
"Protocol_CRC16.c"
"Protocol_Lib.c"
"Protocol_User.c"
"MCU_Core_Protocol.c"
"app_Ble_User.c"
"main_user.c"
"../source/wifi"
"gattc_demo.c"
INCLUDE_DIRS "."
EMBED_TXTFILES ${project_dir}/server_certs/ca_cert.pem)
......@@ -21,6 +21,8 @@ static ProtocolSetData ProtocolSetData_Cbk;
static Protocol_uint8_t *mDataBufPtr = Protocol_NULL;
static Protocol_uint16_t mDataBufLen = 0;
static Protocol_uint32_t DataBufMaxLen = 0;
BAT32A239_ACK_Structure BAT32A239_ACK;
//#define DEBUG_PRO_DATA 0
/**
* @brief 初始化函数
......@@ -52,7 +54,8 @@ void Protocol_Init(Protocol_uint8_t *pMemSpace, Protocol_uint32_t MemLen, Protoc
return;
}
extern Protocol_uint32_t UpdateBAT32A239Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_t len);
extern uint32_t SwitchMode;
/**
* @brief 串口协议服务函数,包括读取数据,解析数据,如在外部读取数据,可不调用此函数
*
......@@ -72,7 +75,15 @@ void Protocol_Service(void)
{
mDataBufLen += readNum;
// 解析协议
len = Protocol_Parse(mDataBufPtr, mDataBufLen);
if(SwitchMode==0)//处理升级协议
{
len = Protocol_Parse(mDataBufPtr, mDataBufLen);
}
else//处理应用协议
{
len = UpdateBAT32A239Protocol_Parse(mDataBufPtr, mDataBufLen);
}
if ( (len > 0) && (len < mDataBufLen) )
{
// 将未解析的数据移到头部
......@@ -203,7 +214,7 @@ Protocol_uint32_t Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_
#endif
}
}
pData += frameLen;
remainLen -= frameLen;
}
......@@ -224,16 +235,16 @@ Protocol_uint32_t Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_
*
* @since 1.0.0
*/
Protocol_uint32_t Protocol_Send(const Protocol_uint16_t cmdID, const Protocol_uint8_t *pData, Protocol_uint8_t len)
{
int i = 0;
Protocol_uint16_t checksum = 0;
Protocol_uint8_t dataBuf [ 256 ];
Protocol_uint32_t frameLen;
if ( len + DATA_PACKAGE_MIN_LEN > 256 )
{
// printf("sendProtocol data is too len !!!\n");
// printf("sendProtocol data is too len !!!\n");
return 0;
}
......@@ -241,7 +252,7 @@ Protocol_uint32_t Protocol_Send(const Protocol_uint16_t cmdID, const Protocol_ui
dataBuf [ 1 ] = CMD_HEAD2; // 同步帧头 Sync frame header
dataBuf [ 2 ] = len + 4;
dataBuf [ 3 ] = len; // 命令字节 Command byte
dataBuf [ 3 ] = 0; // 命令字节 Command byte
dataBuf [ 4 ] = ( Protocol_uint8_t )cmdID;
......@@ -254,7 +265,6 @@ Protocol_uint32_t Protocol_Send(const Protocol_uint16_t cmdID, const Protocol_ui
frameLen++;
}
// 校验码 Checksum
checksum = getCheckSum(dataBuf + 2, frameLen - 2);
dataBuf [ frameLen ] = (checksum >> 8) & 0x00FF;
......@@ -262,7 +272,79 @@ Protocol_uint32_t Protocol_Send(const Protocol_uint16_t cmdID, const Protocol_ui
dataBuf [ frameLen ] = checksum & 0x00FF;
frameLen++;
if ( UARTSend_Cbk != Protocol_NULL )
{
return UARTSend_Cbk(dataBuf, frameLen);
}
else
{
return 0;
}
}
Protocol_uint32_t CalcCrc32(Protocol_uint8_t buf[], int Len);
/**
* 根据协议格式进行拼接
*/
/**
* @brief 串口协议数据拼接,如初始化发送函数,调用此函数后,数据已通过串口发送
* @param[in] cmdID 命令字
* @param[in] pData 协议数据内容(不包括协议头、长度、帧序号、命令字、校验和,从数据域算起)
* @param[in] len 数据域长度
*
* @return 已发送的数据长度
*
* @since 1.0.0
*/
Protocol_uint32_t UpdateBAT32A239Protocol_Send(UpdateProtocolStructure SendPd)
{
int i = 0;
Protocol_uint16_t checksum = 0;
Protocol_uint8_t dataBuf [ 256 ];
Protocol_uint16_t checksumXor = 0;
Protocol_uint32_t frameLen = 0;
Protocol_uint32_t DAT_CRC;
if ( SendPd.LEN > 256 )
{
// printf("sendProtocol data is too len !!!\n");
return 0;
}
frameLen = SendPd.LEN + 7;
dataBuf [ 0 ] = 0xAA;
dataBuf [ 1 ] = 0x55; // 同步帧头 Sync frame header
dataBuf [ 2 ] = SendPd.CMDH; //CMDH
dataBuf [ 3 ] = SendPd.CMDL; // CMDL
dataBuf [ 4 ] = frameLen;
dataBuf [ 5 ] = frameLen >> 8; // 命令字节 Command byte
if(SendPd.CMDH == CMD_FLASH_DWNLD)
{
if(SendPd.LEN > 4)
{
memcpy(&dataBuf[6],&SendPd.DAT[0],SendPd.LEN - 4);
DAT_CRC=CalcCrc32(&SendPd.DAT[0], SendPd.LEN - 4 );//计算Address + Data的CRC 32
dataBuf[frameLen-5]=(Protocol_uint8_t)(DAT_CRC);
dataBuf[frameLen-4]=(Protocol_uint8_t)(DAT_CRC>>8);
dataBuf[frameLen-3]=(Protocol_uint8_t)(DAT_CRC>>16);
dataBuf[frameLen-2]=(Protocol_uint8_t)(DAT_CRC>>24);
}
}
if(SendPd.CMDH == CMD_FLASH_ERASE)
{
memcpy(&dataBuf[6],&SendPd.DAT[0],SendPd.LEN);
}
for(i = 0 ;i < (frameLen - 1); i++)
{
checksumXor^=dataBuf[i];
}
dataBuf[frameLen - 1]=(Protocol_uint8_t)checksumXor;
//printf("dataBuf[frameLen - 1] = %2x\n", dataBuf[frameLen - 1]);
//printf("frameLen = %d\n", frameLen);
if ( UARTSend_Cbk != Protocol_NULL )
{
return UARTSend_Cbk(dataBuf, frameLen);
......
......@@ -39,6 +39,61 @@ typedef struct
Protocol_uint8_t Data [ 256 ]; /**< 有效数据内容 DATA0-DATAN*/
} Protocol_Data_t;
// #define UPGRADE_BAT32A239
// #ifdef UPGRADE_BAT32A239
#define CMD_FLASH_ERASE 0x30//擦除 FLASH
#define CMD_FLASH_DWNLD 0x31//下载用户程序到 FLASH
#define CMD_DATA_CRC_CHECK 0x32//CRC 校验下载用户程
#define CMD_SYS_RESET 0x50//系统复位
typedef struct
{
Protocol_uint8_t CMDH; //宏定义所包含的
Protocol_uint8_t CMDL;
Protocol_uint16_t LEN; //不关心发送的端格式
Protocol_uint8_t DAT[160];//补充的数据直接补充好再传到下层
}UpdateProtocolStructure;//上层协议数据结构
typedef struct
{
Protocol_uint8_t CMDH ;
Protocol_uint8_t CMDL ;
Protocol_uint8_t LEN[2];
union
{
Protocol_uint8_t DAT[128];
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}Erase;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}download;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}verification;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}reset;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}appgo;
}dat;
}BAT32A239_ACK_Structure;//下层应答协议
extern BAT32A239_ACK_Structure BAT32A239_ACK;
typedef Protocol_uint8_t (*UARTOpen)(void);
typedef Protocol_uint32_t (*UARTSend)(const Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
typedef Protocol_uint32_t (*UARTRead)(Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
......@@ -63,5 +118,6 @@ void Protocol_Init(Protocol_uint8_t *pMemSpace, Protocol_uint32_t M
void Protocol_Service(void);
Protocol_uint32_t Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_t len);
Protocol_uint32_t Protocol_Send(const Protocol_uint16_t cmdID, const Protocol_uint8_t *pData, Protocol_uint8_t len);
Protocol_uint32_t UpdateBAT32A239Protocol_Send(UpdateProtocolStructure SendPd);
#endif
This diff is collapsed.
......@@ -24,7 +24,108 @@ typedef struct
extern Protocol_User_Ctrl_Struct Prot_User;
void Protocol_User_Ctrl_Init(void );
void BAT32A239_MCU_Update(void);
void Prot_Send_Msg_Process(void );
Protocol_uint32_t CalcCrc32(Protocol_uint8_t buf[], int Len);
extern Protocol_uint32_t UpdateBAT32A239Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_t len);
extern void SendCmd_ResetComond(void);
#ifdef UPGRADE_N32G031
#define CMD_SET_BR 0x01//设置串口波特率
#define CMD_GET_INF 0x10//读取芯片型号索引、BOOT 版本号、芯片 ID
#define CMD_FLASH_ERASE 0x30//擦除 FLASH
#define CMD_FLASH_DWNLD 0x31//下载用户程序到 FLASH
#define CMD_DATA_CRC_CHECK 0x32//CRC 校验下载用户程
#define CMD_OPT_RW 0x40//读取/配置选项字节(包含了读保护等级、FLASH 页写保护、Data0/1 配置等)
#define CMD_SYS_RESET 0x50//系统复位
#define CMD_APP_GO 0x51//跳转到用户区执行程序
typedef struct
{
Protocol_uint8_t CMDH; //宏定义所包含的
Protocol_uint8_t CMDL;
Protocol_uint16_t LEN; //不关心发送的端格式
Protocol_uint8_t PAR[4];//需要处理好段格式
Protocol_uint8_t DAT[160];//补充的数据直接补充好再传到下层
}UpdateProtocolStructure;//上层协议数据结构
typedef struct
{
Protocol_uint8_t CMDH ;
Protocol_uint8_t CMDL ;
Protocol_uint8_t LEN[2];
union
{
Protocol_uint8_t DAT[128];
struct
{
Protocol_uint8_t unused_0 :8;
Protocol_uint8_t BootVer :8;
Protocol_uint8_t BootCmdVer :8;
Protocol_uint8_t UCID [16];
Protocol_uint8_t ChipID_UID [12];
Protocol_uint8_t DBGMCU_IDCODE[4];
Protocol_uint8_t Other [16];
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}Chipinf;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}Erase;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}download;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}verification;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}reset;
struct
{
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}appgo;
struct
{
struct Protocol_Lib
{
Protocol_uint8_t RDP ;
Protocol_uint8_t nRDP ;
Protocol_uint8_t USER ;
Protocol_uint8_t nUSER ;
Protocol_uint8_t Data0;
Protocol_uint8_t nData0;
Protocol_uint8_t Data1;
Protocol_uint8_t nData1;
Protocol_uint8_t WRP0;
Protocol_uint8_t nWRP0;
Protocol_uint8_t WRP1;
Protocol_uint8_t nWRP1;
Protocol_uint8_t RDP2;
Protocol_uint8_t nRDP2;
Protocol_uint8_t Reserved;
Protocol_uint8_t nReserved;
}optionbyte;
Protocol_uint8_t CR1 :8;
Protocol_uint8_t CR2 :8;
}flashOpt;
}dat;
}N32G031_ACK_Structure;//下层应答协议
extern N32G031_ACK_Structure N32G031_ACK;
Protocol_uint32_t UpdateN32G031Protocol_Send(UpdateProtocolStructure SendPd);
Protocol_uint32_t UpdateN32G031Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_t len);
#endif
#endif
......@@ -448,6 +448,8 @@ void Ble_User_Task(void *pvParameter)
vTaskDelete(NULL);
}
TaskHandle_t Ble_User_Task_hdl=NULL;
void Ble_User_Init(void )
{
BleRecSuc_Semaphore = xSemaphoreCreateBinary();
......@@ -474,6 +476,5 @@ void Ble_User_Init(void )
Ble_Clear_Rx_Buffer();
xTaskCreatePinnedToCore(Ble_User_Task, "Ble_User", 4096, NULL, 10, NULL, 0);
xTaskCreatePinnedToCore(Ble_User_Task, "Ble_User", 4096, NULL, 10, Ble_User_Task_hdl, 0);
}
......@@ -19,8 +19,8 @@ static void bt_app_task_handler(void *arg);
static bool bt_app_send_msg(bt_app_msg_t *msg);
static void bt_app_work_dispatched(bt_app_msg_t *msg);
static QueueHandle_t bt_app_task_queue = NULL;
static TaskHandle_t bt_app_task_handle = NULL;
QueueHandle_t bt_app_task_queue = NULL;
TaskHandle_t bt_app_task_handle = NULL;
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
{
......
......@@ -104,12 +104,12 @@ static void Uart_Rx_Task(void *arg)
}
free(data);
}
TaskHandle_t Uart_Rx_Taskhdl;
void bsp_Uart_Init(void )
{
init_Uart();
Protocol_KL30_Wakeup_Init();
xTaskCreatePinnedToCore(Uart_Rx_Task, "Ble_User", 4096, NULL, 4, NULL, 1);
xTaskCreatePinnedToCore(Uart_Rx_Task, "Ble_User", 4096, NULL, 4, Uart_Rx_Taskhdl, 1);
}
......@@ -119,16 +119,16 @@ void bsp_Uart_Init(void )
extern void simple_ota_main(void);
void simple_ota_service(void)
{
if(Wifi_OTA_Request == 1)
{
Wifi_OTA_Request = 2;
simple_ota_main();
vTaskDelay(portMAX_DELAY);
}
}
// extern void simple_ota_main(void);
// void simple_ota_service(void)
// {
// if(Wifi_OTA_Request == 1)
// {
// Wifi_OTA_Request = 2;
// simple_ota_main();
// vTaskDelay(portMAX_DELAY);
// }
// }
......
......@@ -73,7 +73,7 @@ void bsp_Uart_Init(void );
int bsp_Ble_Gatts_Send_Indicate(uint8_t len, uint8_t *data);
void simple_ota_service(void);
// void simple_ota_service(void);
extern uint8_t BT_Device_Name[14];
......
......@@ -28,7 +28,7 @@
#include "app_BT_User.h"
#include "bt_app_hf.h"
#include "wifi_service.h"
#define TAG "MAIN_USER"
extern esp_bd_addr_t peer_addr;
......@@ -45,11 +45,16 @@ uint32_t Sys_1ms_Cnt;
uint32_t testcnt;
extern uint32_t SwitchMode;
static void Sys_Run_Tasks(void *arg)
{
uint8_t i = 0;
while(1)
{
if(SwitchMode!=0)
{
break;
}
if(Sys_1ms_Cnt < 499)
{
Sys_1ms_Cnt ++ ;
......@@ -86,7 +91,7 @@ static void Sys_Run_Tasks(void *arg)
if(SYS_RUN_TASK_1000MS)
{
simple_ota_service();
// simple_ota_service();
testcnt++;
if(testcnt >= 10)
......@@ -120,9 +125,29 @@ static void Sys_Run_Tasks(void *arg)
vTaskDelay(1);
}
vTaskDelete(NULL);
}
TaskHandle_t wifi_service_hdl=NULL;
extern uint32_t SwitchMode;
extern void wifiServiceStart(void);
extern void Upgrade_BAT32A239_Task(void *arg);
static void wifi_service_task(void *arg)
{
while (1)
{
// if(SwitchMode == 1)
// {
// //delele_tasks();
// xTaskCreatePinnedToCore(Upgrade_BAT32A239_Task, "Upgrade_BAT32A239_Task", 1024 * 4, NULL, 5, NULL, 1);
// SwitchMode=2;
// }
// wifi_service_timer();
wifi_service();
vTaskDelay(pdMS_TO_TICKS(100));
}
}
TaskHandle_t Sys_Run_Taskshdl=NULL;
void app_main(void)
{
Protocol_User_Ctrl_Init();
......@@ -135,9 +160,16 @@ void app_main(void)
bsp_Uart_Init();
printf("KL30 INIT OVER~~~~~~\r\n");
xTaskCreatePinnedToCore(Sys_Run_Tasks, "Sys_Run_Tasks", 4096, NULL, 3, NULL, 1);
xTaskCreatePinnedToCore(Sys_Run_Tasks, "Sys_Run_Tasks", 4096, NULL, 3, Sys_Run_Taskshdl, 1);
xTaskCreatePinnedToCore(wifi_service_task, "wifi_service_task", 4096, NULL, 5, &wifi_service_hdl, 1);
xTaskCreatePinnedToCore(Upgrade_BAT32A239_Task, "Upgrade_BAT32A239_Task", 1024 * 4, NULL, 5, NULL, 1);
}
void delele_tasks(void)
{
// vTaskSuspend(Sys_Run_Taskshdl);
// vTaskSuspend(Ble_User_Task_hdl);
// bt_app_task_shut_down( );
// vTaskDelay(pdMS_TO_TICKS(100));
}
#ifndef _MAIN_USER_H_
#define _MAIN_USER_H_
extern TaskHandle_t Ble_User_Task_hdl;
extern TaskHandle_t Sys_Run_Taskshdl;
extern TaskHandle_t Uart_Rx_Taskhdl;
extern void bt_app_task_shut_down(void);
extern void delateBleUser_Task(void);
#endif
\ No newline at end of file
This diff is collapsed.
......@@ -213,11 +213,11 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
CONFIG_BOOTLOADER_LOG_LEVEL=2
CONFIG_BOOTLOADER_LOG_LEVEL=3
#
# Serial Flash Configurations
......@@ -985,7 +985,7 @@ CONFIG_RTC_CLK_CAL_CYCLES=1024
#
# Peripheral Control
#
# CONFIG_PERIPH_CTRL_FUNC_IN_IRAM is not set
CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y
# end of Peripheral Control
#
......@@ -1298,7 +1298,7 @@ CONFIG_FREERTOS_CORETIMER_0=y
# CONFIG_FREERTOS_CORETIMER_1 is not set
CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y
# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set
# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set
CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y
# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y
......@@ -1899,11 +1899,11 @@ CONFIG_WPA_MBEDTLS_TLS_CLIENT=y
# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y
# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
CONFIG_LOG_BOOTLOADER_LEVEL=2
CONFIG_LOG_BOOTLOADER_LEVEL=3
# CONFIG_APP_ROLLBACK_ENABLE is not set
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
# CONFIG_FLASHMODE_QIO is not set
......
idf_component_register(SRCS "http_server.c" "wifi_service.c" "softap.c"
INCLUDE_DIRS "." "../../main"
PRIV_REQUIRES nvs_flash esp_netif esp_wifi esp_http_server app_update driver
EMBED_FILES "favicon.ico" "ota_page.html")
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" charset="utf-8">
<title>ESP32</title>
</head>
<body>
<h2>ESP32</h2>
<hr><br>
<button id="ota" type="button" onclick="ota()">ESP32 固件升级</button>
<script>
function ota() {
window.location.href = "http://192.168.4.1/ota";
}
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" charset="utf-8">
<title>固件升级</title>
</head>
<body>
<h2>固件升级</h2>
<hr>
<a href="http://192.168.4.1" style="font-size: smaller;">[返回首页]</a><br><br>
<!-- 选择文本按钮 -->
<label for="newFile">加载文件:</label>
<input id="newFile" type="file" accept=".bin" onchange="checkFile()">
<br><br>
<!-- 上传操作 -->
<label for="otaStart">执行操作:</label>
<button id="otaStart" type="button" onclick="otaStart()">开始升级</button>
<button id="reload" type="button" onclick="reload()">刷新界面</button>
<br><br>
<!-- 进度显示 -->
<label for="otaPercent">进度显示:</label>
<input id="otaPercent" type="text" value="0.00%" style="width: 75px;border: none;font-size:large;">
<progress id="otaProgress" value="0" max="100"></progress>
<br><br><hr>
<p id="viewName"></p>
<p id="viewSize"></p>
<p id="viewFlashStart"></p>
<p id="viewFlashResult"></p>
<script>
function reload() {
location.reload();
}
function getFileSize(size) {
if (!size) return "";
var num = 1024.00;
if (size < num) {
return size + "B";
}
if (size < Math.pow(num, 2)) {
return (size / num).toFixed(2) + "KB";
}
if (size < Math.pow(num, 3)) {
return (size / Math.pow(num, 2)).toFixed(2) + "MB";
}
}
function checkFile() {
var newFile = document.getElementById("newFile").files[0];
var newFileName = newFile.name;
var newFileSize = newFile.size;
if (newFileSize > 2 * 1024 * 1024) {
alert('所选文件超出最大限制\n点击确定后将自动刷新页面');
location.reload();
}
else {
document.getElementById("viewName").innerHTML = "文件名称:" + newFileName;
document.getElementById("viewSize").innerHTML = "文件大小:" + getFileSize(newFileSize);
}
}
function otaStart() {
var res = document.getElementById("newFile").files[0];
if (typeof (res) == "undefined") {
alert('未选择文件!');
}
else {
var filepath = document.getElementById("newFile").files[0].name;
var upload_path = "/ota/" + filepath;
document.getElementById("viewFlashStart").innerHTML = "锁定页面,请务必保持WiFi在线,正在上传...";
document.getElementById("newFile").disabled = true;
document.getElementById("otaStart").disabled = true;
var file = document.getElementById("newFile").files[0];
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
document.getElementById("viewFlashResult").innerHTML = "上传成功!";
} else if (xhttp.status == 0) {
document.getElementById("viewFlashResult").innerHTML = "服务器断开!<br><br>请检查服务器是否在线,刷新页面后重新上传...";
} else {
alert(xhttp.status + " Error!\n" + xhttp.responseText);
}
}
};
let progressBar = document.getElementById("otaProgress");
xhttp.upload.onprogress = function (e) {
var percentage = (event.loaded * 100.00) / (event.total * 1.00);
percentage = percentage.toFixed(2);
progressBar.value = Math.round(percentage);
document.getElementById("otaPercent").value = percentage + "%";
}
xhttp.open("POST", upload_path, true);
xhttp.send(file);
}
}
</script>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
#ifndef _GTTP_SERVER_H_
#define _GTTP_SERVER_H_
#include "esp_event.h"
#include "esp_http_server.h"
#define HTTP_SERVER_STOP 0
#define HTTP_SERVER_INIT 1
#define HTTP_SERVER_START 2
#define HTTP_SERVER_DEINIT 3
#define MAX_OTA_BUFF 4096u
#define MAX_RETRY_COUNT 5
extern char buf[MAX_OTA_BUFF];
extern httpd_handle_t http_server;
void set_softap_ota_status(unsigned char status);
unsigned char get_softap_ota_status(void);
void connect_handler(void *arg);
void disconnect_handler(void *arg);
httpd_handle_t http_service(void);
extern void delele_tasks(void);
extern void Catch_data(unsigned char *p, uint32_t len);
extern void SetUpgradeFlashSize(uint32_t size,uint32_t len);
extern void SetUpgradeStart(void); // ��ʼ״̬
void Nat32G031_ReqReset(void);
#endif
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" charset="utf-8">
<title>OTA Page</title>
</head>
<body>
<h2>OTA Page</h2>
<hr>
<!-- 下拉菜单 -->
<label for="selectPartition">目标分区:</label>
<select id="selectPartition" name="selectPartition">
<option selected value="RT200T-2.bin">Application</option>
<option value="BAT32G139.bin">MCU_app</option>
</select>
<br><br>
<!-- 选择文本按钮 -->
<label for="newfile">目标文件:</label>
<input id="newfile" type="file" accept=".bin" onchange="checkFile()">
<br><br>
<!-- 上传操作 -->
<label for="upload">执行操作:</label>
<button id="upload" type="button" onclick="upload()">开始上传</button>
<button id="home" type="button" onclick="homePage()">重置页面</button>
<br><br>
<!-- 进度显示 -->
<label for="uploadPercent">进度显示:</label>
<input id="uploadPercent" type="text" value="0.00%" style="width: 75px;border: none;font-size:large;">
<progress id="uploadProgress" value="0" max="100"></progress>
<hr>
<p id="view_name"></p>
<p id="view_size"></p>
<p id="view_flash_start"></p>
<p id="view_flash_result"></p>
<script>
function homePage() {
location.reload();
}
function getfilesize(size) {
if (!size) return "";
var num = 1024.00;
if (size < num) {
return size + "B";
}
if (size < Math.pow(num, 2)) {
return (size / num).toFixed(2) + "KB";
}
if (size < Math.pow(num, 3)) {
return (size / Math.pow(num, 2)).toFixed(2) + "MB";
}
}
function checkFile() {
var currentPartition = document.getElementById("selectPartition").value;
var newFile = document.getElementById("newfile").files[0];
var newFileName = newFile.name;
var newFileSize = newFile.size;
filepath = newFileName;
if (newFileName != currentPartition) {
alert('所选文件与目标分区不匹配\n点击确定后将自动刷新页面\n');
homePage();
}
if (newFileSize > 16 * 1024 * 1024) {
alert('所选文件超出最大限制\n点击确定后将自动刷新页面');
homePage();
}
else {
document.getElementById("view_name").innerHTML = "文件名称:" + newFileName;
document.getElementById("view_size").innerHTML = "文件大小:" + getfilesize(newFileSize);
}
}
function upload() {
var res = document.getElementById("newfile").files[0];
if (typeof (res) == "undefined") {
alert('未选择文件!');
}
else {
var filepath = document.getElementById("newfile").files[0].name;
var upload_path = "/upload/" + filepath;
document.getElementById("view_flash_start").innerHTML = "锁定页面,请务必保持WiFi在线,正在上传...";
document.getElementById("selectPartition").disabled = true;
document.getElementById("newfile").disabled = true;
document.getElementById("upload").disabled = true;
var file = document.getElementById("newfile").files[0];
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
document.getElementById("view_flash_result").innerHTML = "上传成功!";
} else if (xhttp.status == 0) {
document.getElementById("view_flash_result").innerHTML = "服务器断开!<br><br>请检查服务器是否在线,刷新页面后重新上传...";
} else {
alert(xhttp.status + " Error!\n" + xhttp.responseText);
}
}
};
let progressBar = document.getElementById("uploadProgress");
xhttp.upload.onprogress = function (e) {
var percentage = (event.loaded * 100.00) / (event.total * 1.00);
percentage = percentage.toFixed(2);
progressBar.value = Math.round(percentage);
document.getElementById("uploadPercent").value = percentage + "%";
}
xhttp.open("POST", upload_path, true);
xhttp.send(file);
}
}
</script>
</body>
</html>
\ No newline at end of file
#include <stdio.h>
#include <string.h>
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_mac.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "softap.h"
#include "wifi_service.h"
static const char *TAG = "softAP";
esp_netif_t *softap_netif = NULL;
wifi_sta_list_t softap_sta_list;
unsigned char softap_sta_connect = STA_CONNECTED_NEVER;
static void softap_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED)
{
wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
ESP_LOGI(TAG, "---- 设备加入网络, MAC地址 :" MACSTR ", 编号(AID) = %d.", MAC2STR(event->mac), event->aid);
softap_sta_connect = STA_CONNECTED_ONCE;
connect_handler(event_handler_arg);
wifi_service_stop_timer_clear();
}
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED)
{
wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
ESP_LOGI(TAG, "---- 设备退出网络, MAC地址 :" MACSTR ", 编号(AID) = %d.", MAC2STR(event->mac), event->aid);
disconnect_handler(event_handler_arg);
wifi_service_stop_timer_clear();
}
}
void softap_service_start(void)
{
// NVS分区初始化
ESP_LOGI(TAG, "---- nvs分区初始化...");
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// 创建系统事件循环
ESP_LOGI(TAG, "---- 创建系统事件循环...");
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 将WiFi的所有事件作为实例注册进系统事件循环中
ESP_LOGI(TAG, "---- 注册WiFi事件实例...");
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, softap_event_handler, &http_server));
// 初始化网卡相关的底层配置
ESP_LOGI(TAG, "---- 网卡初始化...");
ESP_ERROR_CHECK(esp_netif_init());
// 以默认的方式创建一个ap类型的网卡
ESP_LOGI(TAG, "---- 创建AP类型网卡...");
softap_netif = esp_netif_create_default_wifi_ap();
// 初始化WiFi底层配置
ESP_LOGI(TAG, "---- WiFi初始化...");
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// 将WiFi设置成AP模式
ESP_LOGI(TAG, "---- 配置WiFi为AP模式...");
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
// 创建AP配置
ESP_LOGI(TAG, "---- 创建AP配置...");
wifi_config_t wifi_config = {
.ap = {
.ssid = ESP_WIFI_SSID,
.ssid_len = strlen(ESP_WIFI_SSID),
.password = ESP_WIFI_PASSWD,
.max_connection = 1,
.authmode = WIFI_AUTH_WPA_WPA2_PSK}};
// 获取当前AP的MAC地址
unsigned char softap_mac[6];
esp_wifi_get_mac(WIFI_IF_AP, softap_mac);
// 将MAC地址后两个字节转为字符串
char softap_temp[5];
sprintf(softap_temp, "%02X%02X", softap_mac[4], softap_mac[5]);
// 将MAC地址拼接到 ESP_WIFI_SSID 后面
char softap_ssid[32] = ESP_WIFI_SSID;
strcat(softap_ssid, softap_temp);
// 重新配置 ssid 和 ssid_len
memcpy(wifi_config.ap.ssid, softap_ssid, sizeof(softap_ssid));
wifi_config.ap.ssid_len = strlen(softap_ssid);
// 配置AP的属性
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
// 开启WiFi
ESP_LOGI(TAG, "---- 开启WiFi, 名称 : %s 密码 : %s", wifi_config.ap.ssid, wifi_config.ap.password);
ESP_ERROR_CHECK(esp_wifi_start());
// 首次开启http_server
ESP_LOGI(TAG, "---- 首次开启HTTP服务器...");
http_server = http_service();
// 启动服务关闭计时器
ESP_LOGI(TAG, "---- 启动服务关闭计时器...");
wifi_service_stop_timer_clear();
}
void softap_service_stop(void)
{
// 关闭http_server
ESP_LOGI(TAG, "---- 关闭HTTP服务器...");
disconnect_handler(&http_server);
// 关闭WiFi
ESP_LOGI(TAG, "---- 关闭WiFi...");
ESP_ERROR_CHECK(esp_wifi_stop());
// WiFi反初始化
ESP_LOGI(TAG, "---- WiFi反初始化...");
ESP_ERROR_CHECK(esp_wifi_deinit());
// 销毁网卡实例
ESP_LOGI(TAG, "---- 销毁网卡实例...");
esp_netif_destroy_default_wifi(softap_netif);
// 网卡反初始化 - 官方未实现的功能
// ESP_LOGI(TAG, "---- 网卡反初始化...");
// ESP_ERROR_CHECK(esp_netif_deinit());
// 注销WiFi事件实例
ESP_LOGI(TAG, "---- 注销WiFi事件实例...");
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, softap_event_handler));
// 删除系统事件循环
ESP_LOGI(TAG, "---- 删除系统事件循环...");
ESP_ERROR_CHECK(esp_event_loop_delete_default());
// NVS分区反初始化
ESP_LOGI(TAG, "---- NVS分区反初始化...");
ESP_ERROR_CHECK(nvs_flash_deinit());
ESP_LOGI(TAG, "---- WiFi服务已关闭, 重置WiFi参数");
wifi_service_init();
}
#ifndef _SOFTAP_H_
#define _SOFTAP_H_
#include "esp_wifi.h"
#include "http_server.h"
#define SOFTAP_STOP 0
#define SOFTAP_INIT 1
#define SOFTAP_START 2
#define SOFTAP_DEINIT 3
#define STA_CONNECTED_NEVER 0
#define STA_CONNECTED_ONCE 1
#define ESP_WIFI_SSID "ESP32S3_AP_"
#define ESP_WIFI_PASSWD "12345677"
extern wifi_sta_list_t softap_sta_list;
extern unsigned char softap_sta_connect;
void softap_service_start(void);
void softap_service_stop(void);
#endif
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "esp_wifi.h"
#include "wifi_service.h"
#include "main_user.h"
static const char *TAG = "wifi_service";
extern void delele_tasks(void);
/*****************************************************
* 首次启动HTTP服务器后, 如果一直没有STA设备加入
* 就不能触发STA disconnect事件,也就不会自动关闭HTTP服务器
* 所以需要额外判断这种情况, 当30秒关闭的定时器触发2次后直接关闭
******************************************************/
static unsigned char http_server_stop_counter = 0;
static unsigned char softap_service_stop_flag = 0;
static unsigned short wifi_service_stop_timer = 0;
wifi_service_t wifi_service_info;
void wifi_service_init(void)
{
wifi_service_stop_timer = 0;
softap_service_stop_flag = 0;
http_server_stop_counter = 0;
wifi_service_info.status = WIFI_SERVICE_STOP;
wifi_service_info.softap_status = SOFTAP_STOP;
wifi_service_info.http_server_status = HTTP_SERVER_STOP;
wifi_service_info.ota_partition = 0;
}
void wifi_service_timer(void)
{
if (wifi_service_info.status == WIFI_SERVICE_START)
{
if (wifi_service_stop_timer < 300)
{
++wifi_service_stop_timer;
}
// 每30秒尝试关闭WiFi服务
if (wifi_service_stop_timer == 300)
{
wifi_service_info.status = WIFI_SERVICE_DEINIT;
}
}
}
void wifi_service_stop_timer_clear(void)
{
wifi_service_stop_timer = 0;
}
void wifi_service(void)
{
if (wifi_service_info.status == WIFI_SERVICE_INIT) // 收到指令: WiFi服务初始化
{
wifi_service_info.status = WIFI_SERVICE_START;
ESP_LOGI(TAG, "---- 开启WiFi服务...\n");
// Bsp_Can_Sleep_Init();
// uart_driver_delete(UART_NUM_1);
// delele_tasks();
softap_service_start();
}
else
{
if (wifi_service_info.status == WIFI_SERVICE_DEINIT) // 收到指令: WiFi服务反初始化, 先读取当前连接的STA数量
{
esp_err_t ret = esp_wifi_ap_get_sta_list(&softap_sta_list);
if (ret == ESP_OK)
{
if (softap_sta_list.num == 0) // 当前没有STA连接
{
if (softap_sta_connect == STA_CONNECTED_NEVER) // 从未有STA接入过
{
if (http_server_stop_counter == 1)
{
softap_service_stop_flag = 1;
}
else
{
ESP_LOGI(TAG, "首次启动HTTP服务器, 1分钟内不会关闭WiFi");
++http_server_stop_counter; // 服务器开启状态且没有设备接入过, 延后30秒再关闭
}
}
else
{
softap_service_stop_flag = 1; // 关闭WiFi服务
}
}
else
{
ESP_LOGI(TAG, "---- 有STA设备在线, 拒绝关闭WiFi");
}
}
else
{
ESP_LOGI(TAG, "---- 读取当前连接的STA数量失败, 打印错误信息");
esp_err_to_name(ret);
}
if (softap_service_stop_flag == 1)
{
wifi_service_info.status = WIFI_SERVICE_STOP;
ESP_LOGI(TAG, "---- 关闭WiFi服务, 开启CAN总线, 重装LIN driver...");
softap_service_stop();
// Bsp_Can_Wakeup_Init();
// bsp_Uart1_Init();
}
else
{
wifi_service_info.status = WIFI_SERVICE_START;
wifi_service_stop_timer = 0; // 重置HTTP服务器关闭的定时器
}
}
}
}
void wifiServiceStart(void)
{
if(wifi_service_info.status == WIFI_SERVICE_STOP)
{
// 开启WiFi服务
wifi_service_info.status = WIFI_SERVICE_INIT;
}
}
\ No newline at end of file
#ifndef _WIFI_SERVICE_H_
#define _WIFI_SERVICE_H_
#include "softap.h"
#define WIFI_SERVICE_STOP 0
#define WIFI_SERVICE_INIT 1
#define WIFI_SERVICE_START 2
#define WIFI_SERVICE_DEINIT 3
typedef struct
{
unsigned char status;
unsigned char softap_status; // 暂时用不上 2024.05.08
unsigned char http_server_status; // 暂时用不上 2024.05.08
unsigned char ota_partition; // 暂时用不上 2024.05.08
} wifi_service_t;
extern wifi_service_t wifi_service_info;
void wifi_service_init(void);
void wifi_service_timer(void);
void wifi_service_stop_timer_clear(void);
void wifi_service(void);
extern void Bsp_Can_Sleep_Init(void);
extern void Bsp_Can_Wakeup_Init(void);
extern void bsp_Uart1_Init(void);
extern void wifiServiceStart(void);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment