From 123c2ae44a072687781d2f5108ab431e79caa189 Mon Sep 17 00:00:00 2001 From: "ethan.du" Date: Fri, 7 Aug 2020 17:40:19 +0800 Subject: [PATCH] unify download api --- platform/os/freertos/HAL_Flash_freertos.c | 120 ++++++++++++++++++++++ platform/os/linux/HAL_Flash_linux.c | 43 ++++++++ platform/os/nos/HAL_Flash_nos.c | 120 ++++++++++++++++++++++ samples/ota/ota_sample.c | 9 +- src/ota/src/ota_client.c | 27 ++--- src/sdk-impl/uiot_export_ota.h | 9 +- src/sdk-impl/uiot_import.h | 104 ++++++++++++++----- 7 files changed, 383 insertions(+), 49 deletions(-) create mode 100644 platform/os/freertos/HAL_Flash_freertos.c create mode 100644 platform/os/linux/HAL_Flash_linux.c create mode 100644 platform/os/nos/HAL_Flash_nos.c diff --git a/platform/os/freertos/HAL_Flash_freertos.c b/platform/os/freertos/HAL_Flash_freertos.c new file mode 100644 index 0000000..453d7ce --- /dev/null +++ b/platform/os/freertos/HAL_Flash_freertos.c @@ -0,0 +1,120 @@ +/* +* Copyright (C) 2012-2019 UCloud. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* or in the "license" file accompanying this file. This file is distributed +* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ +#include "uiot_import.h" + +uint32_t download_addr = DOWNLOAD_START_ADDR; + +void * HAL_Download_Init(_IN_ void * name) +{ + int i,ret; + char version_info[VERSION_BYTE_NUM]; + uint32_t info_addr = CURRENT_VERSION_START_ADDR; + for(i=0; i < VERSION_BYTE_NUM; i++) + { + version_info[i] = HAL_FLASH_Read_Byte(info_addr); + info_addr++; + } + if(FAILURE_RET == HAL_FLASH_Erase_Sector(FLASH_SECTOR_3, 1)) + return NULL; + info_addr = CURRENT_VERSION_START_ADDR; + for(i = 0; i < VERSION_BYTE_NUM; i++) + { + ret = HAL_FLASH_Write_Byte(info_addr++,version_info[i]); + if(SUCCESS_RET != ret) + return NULL; + } + ret = HAL_FLASH_Write_Byte(DOWNLOAD_FINISH_FLG_ADDR,DOWNLOAD_FAILED); + if(SUCCESS_RET != ret) + return NULL; + ret = HAL_FLASH_Erase_Sector(FLASH_SECTOR_8, 4); + if(SUCCESS_RET != ret) + return NULL; + download_addr = DOWNLOAD_START_ADDR; + return &download_addr; +} + +int HAL_Download_Write(_IN_ void * handle,_IN_ uint32_t total_length,_IN_ uint8_t *buffer_read,_IN_ uint32_t length) +{ + uint8_t *readptr = buffer_read; + int i = 0,ret; + for(i = length; i > 0; i--){ + ret = HAL_FLASH_Write_Byte(download_addr++, *readptr++); + if(ret == FAILURE_RET){ + printf("HAL_Download_Write failed!\r\n"); + return FAILURE_RET; + } + } + + return SUCCESS_RET; +} + +int HAL_Download_End(_IN_ void * handle) +{ + HAL_FLASH_Write_Byte(DOWNLOAD_FINISH_FLG_ADDR,DOWNLOAD_SUCESS); + + //reset here + __set_FAULTMASK(1); + HAL_NVIC_SystemReset(); + return SUCCESS_RET; +} + + +int HAL_FLASH_Write_Byte(_IN_ uint32_t sddr,_IN_ uint32_t data) +{ + HAL_StatusTypeDef ret; + ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, sddr, data); + if(ret == HAL_ERROR){ + printf("write data byte to flash failed!\r\n"); + return FAILURE_RET; + } + else + return SUCCESS_RET; +} +int HAL_FLASH_Erase_Sector(_IN_ uint8_t sector, _IN_ int sector_num) +{ + uint32_t flash_error; + HAL_StatusTypeDef ret; + FLASH_EraseInitTypeDef flash_erase; + flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; + flash_erase.Sector = sector; + flash_erase.NbSectors = sector_num; + flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | + FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY); + ret = HAL_FLASHEx_Erase(&flash_erase, &flash_error); + FLASH_WaitForLastOperation(50000); + if(ret == HAL_ERROR){ + printf("erase sector in flash failed!\r\n"); + return FAILURE_RET; + } + else + return SUCCESS_RET; +} +uint8_t HAL_FLASH_Read_Byte(_IN_ uint8_t addr) +{ + uint8_t data; + data=*(__IO uint8_t*)( addr); + return data; +} + +/* +void version_get(char * verptr) +{ + int i; + uint32_t version_addr=CURRENT_VERSION_START_ADDR; + for(i=0;i 0; i--){ + ret = HAL_FLASH_Write_Byte(download_addr++, *readptr++); + if(ret == FAILURE_RET){ + printf("HAL_Download_Write failed!\r\n"); + return FAILURE_RET; + } + } + + return SUCCESS_RET; +} + +int HAL_Download_End(_IN_ void * handle) +{ + HAL_FLASH_Write_Byte(DOWNLOAD_FINISH_FLG_ADDR,DOWNLOAD_SUCESS); + + //reset here + __set_FAULTMASK(1); + HAL_NVIC_SystemReset(); + return SUCCESS_RET; +} + + +int HAL_FLASH_Write_Byte(_IN_ uint32_t sddr,_IN_ uint32_t data) +{ + HAL_StatusTypeDef ret; + ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, sddr, data); + if(ret == HAL_ERROR){ + printf("write data byte to flash failed!\r\n"); + return FAILURE_RET; + } + else + return SUCCESS_RET; +} +int HAL_FLASH_Erase_Sector(_IN_ uint8_t sector, _IN_ uint8_t sector_num) +{ + uint32_t flash_error; + HAL_StatusTypeDef ret; + FLASH_EraseInitTypeDef flash_erase; + flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS; + flash_erase.Sector = sector; + flash_erase.NbSectors = sector_num; + flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | + FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY); + ret = HAL_FLASHEx_Erase(&flash_erase, &flash_error); + FLASH_WaitForLastOperation(50000); + if(ret == HAL_ERROR){ + printf("erase sector in flash failed!\r\n"); + return FAILURE_RET; + } + else + return SUCCESS_RET; +} +uint8_t HAL_FLASH_Read_Byte(_IN_ uint8_t addr) +{ + uint8_t data; + data=*(__IO uint8_t*)( addr); + return data; +} + +/* +void version_get(char * verptr) +{ + int i; + uint32_t version_addr=CURRENT_VERSION_START_ADDR; + for(i=0;idownload_file_name, state); - return SUCCESS_RET; -} - int main(int argc, char **argv) { int rc; @@ -122,7 +115,7 @@ int main(int argc, char **argv) return FAILURE_RET; } - void *h_ota = IOT_OTA_Init(UIOT_MY_PRODUCT_SN, UIOT_MY_DEVICE_SN, client, IOT_OTA_FetchCallback_func); + void *h_ota = IOT_OTA_Init(UIOT_MY_PRODUCT_SN, UIOT_MY_DEVICE_SN, client); if (NULL == h_ota) { IOT_MQTT_Destroy(&client); LOG_ERROR("init OTA failed"); diff --git a/src/ota/src/ota_client.c b/src/ota/src/ota_client.c index 385a055..d18cc39 100644 --- a/src/ota/src/ota_client.c +++ b/src/ota/src/ota_client.c @@ -301,7 +301,7 @@ do_exit: return ret; } -void *IOT_OTA_Init(const char *product_sn, const char *device_sn, void *ch_signal, IOT_OTA_FetchCallback fetch_callback_func) +void *IOT_OTA_Init(const char *product_sn, const char *device_sn, void *ch_signal) { POINTER_VALID_CHECK(product_sn, NULL); POINTER_VALID_CHECK(device_sn, NULL); @@ -321,8 +321,6 @@ void *IOT_OTA_Init(const char *product_sn, const char *device_sn, void *ch_signa LOG_ERROR("initialize signal channel failed"); goto do_exit; } - - h_ota->fetch_callback_func = fetch_callback_func; h_ota->md5 = ota_lib_md5_init(); if (NULL == h_ota->md5) { @@ -702,15 +700,17 @@ int IOT_OTA_fw_download(void *handle) int file_size = 0, length, firmware_valid, total_length = 0; char *buffer_read = NULL; OTA_Struct_t * h_ota = (OTA_Struct_t *) handle; + void * download_handle = NULL; // 用于存放云端下发的固件版本 char msg_version[33]; - void *fp; IOT_OTA_Ioctl(h_ota, OTA_IOCTL_FILE_SIZE, &file_size, 4); - - if (NULL == (fp = HAL_FileOpen(h_ota->download_file_name))) { - LOG_ERROR("open file failed"); - return ERR_OTA_INVALID_PARAM; + + download_handle = HAL_Download_Init(h_ota->download_file_name); + if(download_handle == NULL) + { + ret = FAILURE_RET; + goto __exit; } buffer_read = (char *)HAL_Malloc(HTTP_OTA_BUFF_LEN); @@ -729,11 +729,12 @@ int IOT_OTA_fw_download(void *handle) if (length > 0) { /* Write the data to the corresponding partition address */ - if (SUCCESS_RET != HAL_FileWrite(fp, total_length, buffer_read, length)) { - LOG_ERROR("write data to file failed"); + if(HAL_Download_Write(download_handle, total_length, buffer_read, length) == FAILURE_RET){ + ret = FAILURE_RET; goto __exit; } - total_length += length; + + total_length += length; //wait cancel cmd IOT_OTA_Yield(handle, 100); } @@ -758,6 +759,9 @@ int IOT_OTA_fw_download(void *handle) IOT_OTA_Ioctl(h_ota, OTA_IOCTL_VERSION, msg_version, 33); IOT_OTA_ReportSuccess(h_ota, msg_version); } + + if(HAL_Download_End(download_handle)) + ret = FAILURE_RET; LOG_INFO("Download firmware to flash success."); } @@ -766,7 +770,6 @@ __exit: if (buffer_read != NULL) HAL_Free(buffer_read); IOT_OTA_Clear(h_ota); - HAL_FileClose(fp); return ret; } diff --git a/src/sdk-impl/uiot_export_ota.h b/src/sdk-impl/uiot_export_ota.h index 1cf3db3..941a1fb 100644 --- a/src/sdk-impl/uiot_export_ota.h +++ b/src/sdk-impl/uiot_export_ota.h @@ -107,14 +107,13 @@ typedef struct { * @brief 初始化OTA模块和返回句柄 * MQTT客户端必须在调用此接口之前进行初始化 * - * @param product_sn: 指定产品序列号 - * @param device_sn: 指定设备序列号 - * @param ch_signal: 指定的信号通道. - * @param fetch_callback_func: ota下载完成后的回调函数指针. + * @param product_sn: 指定产品序列号 + * @param device_sn: 指定设备序列号 + * @param ch_signal: 指定的信号通道. * * @retval : 成功则返回句柄,失败返回NULL */ -void *IOT_OTA_Init(const char *product_sn, const char *device_sn, void *ch_signal, IOT_OTA_FetchCallback fetch_callback_func); +void *IOT_OTA_Init(const char *product_sn, const char *device_sn, void *ch_signal); /** diff --git a/src/sdk-impl/uiot_import.h b/src/sdk-impl/uiot_import.h index 2ec4dc0..9bff657 100644 --- a/src/sdk-impl/uiot_import.h +++ b/src/sdk-impl/uiot_import.h @@ -128,30 +128,6 @@ uint64_t HAL_UptimeMs(void); */ void HAL_SleepMs(_IN_ uint32_t ms); -/** - * @brief 打开要写的文件. - * - * @param file_path 文件路径. - */ -void *HAL_FileOpen(char *file_path); - -/** - * @brief 写文件. - * - * @param dest 目标文件指针. - * @param offset 目标文件指针已经写入的文件大小. - * @param src 存放文件内容的指针. - * @param size 要写入内容的字节数. - */ -int HAL_FileWrite(void *dest, uint32_t offset, void *src, uint32_t size); - -/** - * @brief 关闭要写的文件. - * - * @param fp 文件指针. - */ -void HAL_FileClose(void *fp); - /** * @brief 获取产品序列号。从设备持久化存储(例如FLASH)中读取产品序列号。 * @@ -341,19 +317,99 @@ int32_t HAL_TCP_Write(_IN_ uintptr_t fd, _IN_ unsigned char *buf, _IN_ size_t le * @return <0: TCP读取错误; =0: TCP读超时, 且没有读取任何数据; >0: TCP成功读取的字节数 */ int32_t HAL_TCP_Read(_IN_ uintptr_t fd, _OU_ unsigned char *buf, _IN_ size_t len, _IN_ uint32_t timeout_ms); + +/** + * @brief 下载的准备工作 + * + * @param name 文件名 + * @return 文件描述符 + */ +void * HAL_Download_Init(_IN_ void * name); + +/** +* @brief 将长度为length的buffer_read的数据写入到FLASH中 + * + * @param handle 文件描述符 + * @param total_length 未用到 + * @param buffer_read 数据的指针 + * @param length 数据的长度,单位为字节 + * @return + */ +int HAL_Download_Write(_IN_ void * handle,_IN_ uint32_t total_length,_IN_ char *buffer_read,_IN_ uint32_t length); + +/** + * @brief STM32F767 FLASH的information分区的下载标志置位成功 + * + * @param handle 文件描述符 + * @return -1失败 0成功 + */ +int HAL_Download_End(_IN_ void * handle); + #ifdef SUPPORT_AT_CMD + +/** + * @brief 通讯模组初始化。 + * + * @param 无 + * @return 无 + */ void HAL_AT_Init(); +/** + * @brief 向指定的通讯模组读AT命令执行结果。 + * + * @param pNetwork 网络句柄 + * @param buf 指向数据接收缓冲区的指针 + * @param len 数据接收缓冲区的字节大小 + * @return <0: TCP读取错误; =0: TCP读超时, 且没有读取任何数据; >0: TCP成功读取的字节数 + */ int HAL_AT_Read(_IN_ utils_network_pt pNetwork, _OU_ unsigned char *buffer, _IN_ size_t len); +/** + * @brief 向指定的通讯模组写AT命令。 + * + * @param buf 指向数据发送缓冲区的指针 + * @param len 数据发送缓冲区的字节大小 + * @return <0: TCP写入错误; =0: TCP写超时, 且没有写入任何数据; >0: TCP成功写入的字节数 + */ int HAL_AT_Write(_IN_ unsigned char *buffer, _IN_ size_t len); +/** + * @brief 断开TCP连接, 并释放相关对象资源。 + * + * @param pNetwork 网络句柄 + * @return 成功返回SUCCESS,失败返回FAILURE + */ int HAL_AT_TCP_Disconnect(utils_network_pt pNetwork); +/** + * @brief 建立TCP连接。根据指定的HOST地址, 服务器端口号建立TCP连接, 返回对应的连接句柄。 + * + * @param pNetwork 网络句柄 + * @param host 指定的TCP服务器网络地址 + * @param port 指定的TCP服务器端口 + * @return 连接成功, 返回TCP连接句柄,连接失败,返回NULL + */ int HAL_AT_TCP_Connect(_IN_ utils_network_pt pNetwork, _IN_ const char *host, _IN_ uint16_t port); +/** + * @brief 向指定的TCP连接写入数据。 + * + * @param pNetwork 网络句柄 + * @param buf 指向数据发送缓冲区的指针 + * @param len 数据发送缓冲区的字节大小 + * @return <0: TCP写入错误; =0: TCP写超时, 且没有写入任何数据; >0: TCP成功写入的字节数 + */ int HAL_AT_Write_Tcp(_IN_ utils_network_pt pNetwork, _IN_ unsigned char *buffer, _IN_ size_t len); +/** + * @brief 从指定的TCP连接读取数据。 + * + * @param pNetwork 网络句柄 + * @param buf 指向数据接收缓冲区的指针 + * @param len 数据接收缓冲区的字节大小 + * @return <0: TCP读取错误; =0: TCP读超时, 且没有读取任何数据; >0: TCP成功读取的字节数 + */ int HAL_AT_Read_Tcp(_IN_ utils_network_pt pNetwork, _IN_ unsigned char *buffer, _IN_ size_t len); #endif