Initial commit: Livox SDK2 source (excluding build artifacts)
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2022 Livox. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "firmware.h"
|
||||
|
||||
namespace livox {
|
||||
namespace lidar {
|
||||
|
||||
Firmware::Firmware() : data_(nullptr), file_size_(0) {
|
||||
memset((void *)&header_, 0, sizeof(header_));
|
||||
memset((void *)&tail_, 0, sizeof(tail_));
|
||||
}
|
||||
|
||||
Firmware::~Firmware() {
|
||||
if (data_) {
|
||||
delete[] data_;
|
||||
}
|
||||
}
|
||||
void Firmware::Close() {
|
||||
file_.close();
|
||||
}
|
||||
|
||||
bool Firmware::Open(const char *firmware_path) {
|
||||
if (!firmware_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file_.open(firmware_path,
|
||||
std::ios::in | std::ifstream::binary | std::ios_base::ate);
|
||||
if (!file_.is_open()) {
|
||||
printf("Open %s firmware file fail!\n", firmware_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
file_size_ = file_.tellg();
|
||||
file_.seekg(0, std::ios::beg);
|
||||
if (file_size_ < MiniFileSize()) {
|
||||
printf("Firmware file size is too small!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ReadAndCheckHeader()) {
|
||||
printf("Firmware file header is wrong!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//printf("Firmware file total size %lu\n", file_size_);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t Firmware::MiniFileSize() {
|
||||
return sizeof(header_) + sizeof(tail_) + 1;
|
||||
}
|
||||
|
||||
bool Firmware::ReadAndCheckHeader() {
|
||||
file_.seekg(0, std::ios::beg);
|
||||
file_.read((char *)(&header_), sizeof(header_));
|
||||
printf("This firmware is used for device[%d].\n", header_.device_type);
|
||||
|
||||
uint16_t crc = crc16_.mcrf4xx(
|
||||
(uint8_t *)(&header_), (uint16_t)(sizeof(header_) - sizeof(uint16_t)));
|
||||
if (crc != header_.header_checksum) {
|
||||
printf("Header checksum[%4x %4x] error!\n", crc, header_.header_checksum);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("Firmware raw data size : %d\n", header_.firmware_length);
|
||||
data_ = new uint8_t[header_.firmware_length];
|
||||
file_.read((char *)(data_), header_.firmware_length);
|
||||
file_.read((char *)(&tail_), sizeof(tail_));
|
||||
|
||||
if (file_) {
|
||||
printf("All firmware data have be read successfully.\n");
|
||||
} else {
|
||||
printf("Read firmware fail[%ld]!\n", file_.gcount());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2022 Livox. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#ifndef LIVOX_UPGRADE_FIRMWARE_H_
|
||||
#define LIVOX_UPGRADE_FIRMWARE_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
|
||||
#include "FastCRC/FastCRC.h"
|
||||
|
||||
namespace livox {
|
||||
namespace lidar {
|
||||
|
||||
const uint32_t kMd5SignatureLength = 16;
|
||||
const uint32_t kEnlFileVersionV2 = 0x02000000;
|
||||
const uint32_t kEnlFileVersionV3 = 0x03000000;
|
||||
|
||||
typedef enum {
|
||||
kFirmwareMultiApp = 0,
|
||||
kFirmwareApp = 1,
|
||||
kFirmwareLoader = 2,
|
||||
kFirmwareUnknown = 3,
|
||||
} FirmwareType;
|
||||
|
||||
typedef enum {
|
||||
kFirmwareDeviceTypeHub = 0, /**< Livox Hub. */
|
||||
kFirmwareDeviceTypeLidarMid40 = 1, /**< Mid-40. */
|
||||
kFirmwareDeviceTypeLidarTele = 2, /**< Tele. */
|
||||
kFirmwareDeviceTypeLidarHorizon = 3, /**< Horizon. */
|
||||
kFirmwareDeviceTypeLidarHubV2 = 4, /**< HubV2. */
|
||||
kFirmwareDeviceTypeLidarMidLite = 5, /**< Mid-Lite. */
|
||||
kFirmwareDeviceTypeLidarMid70 = 6, /**< Mid-70. */
|
||||
kFirmwareDeviceTypeLidarAvia = 7, /**< Avia. */
|
||||
kFirmwareDeviceTypeLidarXxx1 = 8, /**< xxx1. */
|
||||
kFirmwareDeviceTypeLidarXxx2 = 9, /**< xxx2. */
|
||||
kFirmwareDeviceTypeLidarHap = 10, /**< Hap */
|
||||
kFirmwareDeviceUnkown
|
||||
} FirmwareDeviceType;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// typedef struct {
|
||||
// uint32_t file_version;
|
||||
// uint32_t firmware_version;
|
||||
// uint32_t firmware_length;
|
||||
// uint8_t firmware_type;
|
||||
// uint8_t device_type;
|
||||
// uint8_t encrypt_type;
|
||||
// uint8_t rsvd[2];
|
||||
// uint8_t checksum_type;
|
||||
// uint16_t checksum_length;
|
||||
// uint8_t checksum[256];
|
||||
// uint64_t modify_time;
|
||||
// uint16_t header_checksum;
|
||||
// } LivoxEncryptFirmwareHeader;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t file_version;
|
||||
uint32_t firmware_version;
|
||||
uint32_t firmware_length;
|
||||
uint8_t firmware_type;
|
||||
uint8_t device_type;
|
||||
uint8_t encrypt_type;
|
||||
uint8_t rsvd[2];
|
||||
uint8_t checksum_type;
|
||||
uint16_t checksum_length;
|
||||
uint8_t checksum[128];
|
||||
uint8_t hw_whitelist[128];
|
||||
uint64_t modify_time;
|
||||
uint16_t header_checksum;
|
||||
} LivoxEncryptFirmwareHeader;
|
||||
|
||||
typedef struct {
|
||||
uint8_t overall_signature[kMd5SignatureLength];
|
||||
} LivoxEncryptFirmwareTail;
|
||||
|
||||
/** Lidar feature. */
|
||||
typedef enum {
|
||||
kEverythingIsOk = 0,
|
||||
kFirmwareOutOfLength = 1,
|
||||
kSystemIsNotReady = 2,
|
||||
kFirmwareTypeMismatch = 3,
|
||||
kUpgradeStateMismatch = 4,
|
||||
} RequestUpgradeReturnCode;
|
||||
|
||||
const uint32_t kGeneralTryCountLimit = 10;
|
||||
const uint32_t kGetProcessTryCountLimit = 30;
|
||||
const uint32_t kGetProgressTryCountLimit = 10;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
class Firmware {
|
||||
public:
|
||||
Firmware();
|
||||
~Firmware();
|
||||
bool Open(const char *firmware_path);
|
||||
void Close();
|
||||
|
||||
const uint32_t FirmwarePackageVersion() const { return header_.file_version; }
|
||||
|
||||
|
||||
LivoxEncryptFirmwareHeader header_;
|
||||
uint8_t *data_;
|
||||
LivoxEncryptFirmwareTail tail_;
|
||||
uint64_t file_size_;
|
||||
|
||||
private:
|
||||
uint64_t MiniFileSize();
|
||||
bool ReadAndCheckHeader();
|
||||
std::ifstream file_;
|
||||
|
||||
FastCRC16 crc16_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif //LIVOX_UPGRADE_FIRMWARE_H_
|
||||
@@ -0,0 +1,357 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2022 Livox. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#include "livox_lidar_upgrader.h"
|
||||
#include "../command_handler/command_impl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace livox {
|
||||
namespace lidar {
|
||||
|
||||
typedef int32_t (LivoxLidarUpgrader::*FnFsmEvent)();
|
||||
|
||||
typedef struct {
|
||||
uint32_t state;
|
||||
uint32_t event;
|
||||
FnFsmEvent event_handler;
|
||||
uint32_t next_state;
|
||||
} FsmEventTable;
|
||||
|
||||
const FsmEventTable upgrade_event_table[] = {
|
||||
{kLivoxLidarUpgradeIdle, kLivoxLidarEventRequestUpgrade, &LivoxLidarUpgrader::StartUpgrade, kLivoxLidarUpgradeRequest},
|
||||
{kLivoxLidarUpgradeRequest, kLivoxLidarEventRequestUpgrade, &LivoxLidarUpgrader::StartUpgrade, kLivoxLidarUpgradeRequest},
|
||||
{kLivoxLidarUpgradeRequest, kLivoxLidarEventXferFirmware, &LivoxLidarUpgrader::XferFirmware, kLivoxLidarUpgradeXferFirmware},
|
||||
{kLivoxLidarUpgradeXferFirmware, kLivoxLidarEventXferFirmware, &LivoxLidarUpgrader::XferFirmware, kLivoxLidarUpgradeXferFirmware},
|
||||
{kLivoxLidarUpgradeXferFirmware, kLivoxLidarEventCompleteXferFirmware, &LivoxLidarUpgrader::CompleteXferFirmware, kLivoxLidarUpgradeCompleteXferFirmware},
|
||||
{kLivoxLidarUpgradeCompleteXferFirmware, kLivoxLidarEventCompleteXferFirmware, &LivoxLidarUpgrader::CompleteXferFirmware, kLivoxLidarUpgradeCompleteXferFirmware},
|
||||
{kLivoxLidarUpgradeCompleteXferFirmware, kLivoxLidarEventGetUpgradeProgress, &LivoxLidarUpgrader::GetUpgradeProgress, kLivoxLidarUpgradeGetUpgradeProgress},
|
||||
{kLivoxLidarUpgradeGetUpgradeProgress, kLivoxLidarEventGetUpgradeProgress, &LivoxLidarUpgrader::GetUpgradeProgress, kLivoxLidarUpgradeGetUpgradeProgress},
|
||||
{kLivoxLidarUpgradeGetUpgradeProgress, kLivoxLidarEventComplete, &LivoxLidarUpgrader::UpgradeComplete, kLivoxLidarUpgradeComplete},
|
||||
{kLivoxLidarUpgradeComplete, kLivoxLidarEventComplete, &LivoxLidarUpgrader::UpgradeComplete, kLivoxLidarUpgradeComplete},
|
||||
{kLivoxLidarUpgradeComplete, kLivoxLidarEventReinit, nullptr, kLivoxLidarUpgradeIdle}
|
||||
// {kUpgradeRebootDevice, kLivoxLidarEventReinit, nullptr, kLivoxLidarUpgradeIdle},
|
||||
};
|
||||
|
||||
LivoxLidarUpgrader::LivoxLidarUpgrader(const Firmware& firmware, const uint32_t handle)
|
||||
: firmware_(firmware), read_offset_(0), read_length_(1024), handle_(handle), fsm_state_(0),
|
||||
upgrade_error_(0), progress_(0), try_count_(0) {}
|
||||
|
||||
LivoxLidarUpgrader::~LivoxLidarUpgrader() {
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
if (IsUpgradeError()) {
|
||||
printf("LivoxLidar lidar[%u] upgrade error, try again please!\r\n", handle_);
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsUpgradeComplete()) {
|
||||
printf("LivoxLidar lidar[%u] upgrade successfully.\r\n", handle_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (upgrade_thread_ && upgrade_thread_->joinable()) {
|
||||
upgrade_thread_->join();
|
||||
upgrade_thread_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LivoxLidarUpgrader::AddUpgradeProgressObserver(UpgradeProgressCallback observer) {
|
||||
observer_ = observer;
|
||||
return;
|
||||
}
|
||||
|
||||
bool LivoxLidarUpgrader::StartUpgradeLivoxLidar() {
|
||||
upgrade_thread_ = std::make_shared<std::thread>([this](){
|
||||
this->FsmEventHandler(kLivoxLidarEventRequestUpgrade, 10);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void LivoxLidarUpgrader::FsmEventHandler(LivoxLidarFsmEvent event, uint8_t progress) {
|
||||
FnFsmEvent event_handler = nullptr;
|
||||
if ((event == kLivoxLidarEventTimeout) || (event == kLivoxLidarEventErr)) {
|
||||
LivoxLidarFsmStateChange(event);
|
||||
}
|
||||
printf("Fsm event handler, the livox_lidar[%u] State[%d] | Event[%d]\r\n", handle_, fsm_state_, event);
|
||||
for (uint32_t i = 0; i < sizeof(upgrade_event_table) / sizeof(upgrade_event_table[0]); i++) {
|
||||
if ((fsm_state_ == upgrade_event_table[i].state) && (event == upgrade_event_table[i].event)) {
|
||||
event_handler = upgrade_event_table[i].event_handler;
|
||||
fsm_state_ = upgrade_event_table[i].next_state;
|
||||
printf("Fsm event handler, the livox_lidar[%u] New State[%d] | Event[%d]\r\n", handle_, fsm_state_, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (event_handler) {
|
||||
(this->*event_handler)();
|
||||
}
|
||||
|
||||
if (observer_) {
|
||||
LivoxLidarUpgradeState upgrade_state = {event, progress};
|
||||
observer_(handle_, upgrade_state);
|
||||
}
|
||||
}
|
||||
|
||||
livox_status LivoxLidarUpgrader::StartUpgrade() {
|
||||
read_offset_ = 0;
|
||||
upgrade_error_ = 0;
|
||||
progress_ = 0;
|
||||
|
||||
uint8_t request_buf[1024] = { 0 };
|
||||
LivoxLidarStartUpgradeRequest *request = (LivoxLidarStartUpgradeRequest *)request_buf;
|
||||
request->firmware_type = firmware_.header_.firmware_type;
|
||||
request->firmware_length = firmware_.header_.firmware_length;
|
||||
request->encrypt_type = firmware_.header_.encrypt_type;
|
||||
request->dev_type = firmware_.header_.device_type;
|
||||
printf("Start upgrade, the livox_lidar[%u] device type [%d]\r\n", handle_, request->dev_type);
|
||||
|
||||
if (kEnlFileVersionV3 == firmware_.FirmwarePackageVersion()) {
|
||||
LivoxLidarStartUpgradeRequestV3 *request_v3 = (LivoxLidarStartUpgradeRequestV3 *)request_buf;
|
||||
request_v3->firmware_version = firmware_.header_.firmware_version;
|
||||
request_v3->firmware_buildtime = firmware_.header_.modify_time;
|
||||
memcpy(request_v3->hw_whitelist, firmware_.header_.hw_whitelist, sizeof(request_v3->hw_whitelist));
|
||||
|
||||
return CommandImpl::LivoxLidarStartUpgrade(handle_, request_buf, sizeof(LivoxLidarStartUpgradeRequestV3), StartUpgradeResponseHandler, this);
|
||||
} else {
|
||||
return CommandImpl::LivoxLidarStartUpgrade(handle_, request_buf, sizeof(LivoxLidarStartUpgradeRequest), StartUpgradeResponseHandler, this);
|
||||
}
|
||||
}
|
||||
|
||||
livox_status LivoxLidarUpgrader::XferFirmware() {
|
||||
uint8_t send_bufer[2048];
|
||||
LivoxLidarXferFirmwareResquest* request = (LivoxLidarXferFirmwareResquest*)send_bufer;
|
||||
uint32_t firmware_length = firmware_.header_.firmware_length;
|
||||
uint32_t read_length = read_length_;
|
||||
|
||||
if (read_offset_ < firmware_length) {
|
||||
if (read_length > (firmware_length - read_offset_)) {
|
||||
read_length = firmware_length - read_offset_;
|
||||
}
|
||||
} else {
|
||||
printf("The livox_lidar[%u] xfer firmware failed, Read_offset is err, firmware_length[%d], read_offset[%d].\r\n",
|
||||
handle_, firmware_length, read_offset_);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(request->data, &firmware_.data_[read_offset_], read_length);
|
||||
request->offset = read_offset_;
|
||||
request->length = read_length;
|
||||
request->encrypt_type = firmware_.header_.encrypt_type;
|
||||
// read_offset_ += read_length;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
|
||||
printf("The livox_lidar[%u] xfer firmware read offset %d\r\n", handle_, request->offset);
|
||||
|
||||
return CommandImpl::LivoxLidarXferFirmware(handle_, (uint8_t *)request,
|
||||
sizeof(LivoxLidarXferFirmwareResquest) + read_length - sizeof(request->data),
|
||||
XferFirmwareResponseHandler, this);
|
||||
}
|
||||
|
||||
livox_status LivoxLidarUpgrader::CompleteXferFirmware() {
|
||||
uint8_t send_bufer[2048];
|
||||
LivoxLidarCompleteXferFirmwareResquest* request = (LivoxLidarCompleteXferFirmwareResquest*)send_bufer;
|
||||
|
||||
request->checksum_type = firmware_.header_.checksum_type;
|
||||
request->checksum_length = firmware_.header_.checksum_length;
|
||||
memcpy(request->checksum, firmware_.header_.checksum, request->checksum_length);
|
||||
|
||||
return CommandImpl::LivoxLidarCompleteXferFirmware(handle_, (uint8_t *)request,
|
||||
sizeof(LivoxLidarCompleteXferFirmwareResquest) +
|
||||
request->checksum_length - sizeof(request->checksum),
|
||||
CompleteXferFirmwareResponseHandler, this);
|
||||
}
|
||||
|
||||
livox_status LivoxLidarUpgrader::GetUpgradeProgress() {
|
||||
return CommandImpl::LivoxLidarGetUpgradeProgress(handle_, nullptr, 0, GetProgressResponseHandler, this);
|
||||
}
|
||||
|
||||
livox_status LivoxLidarUpgrader::UpgradeComplete() {
|
||||
return CommandImpl::LivoxLidarRequestReboot(handle_, UpgradeCompleteResponseHandler, this);
|
||||
}
|
||||
|
||||
int32_t LivoxLidarUpgrader::LivoxLidarFsmStateChange(LivoxLidarFsmEvent event) {
|
||||
if (event < kLivoxLidarEventUndef) {
|
||||
fsm_state_ = event;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade Callback handler
|
||||
*/
|
||||
void LivoxLidarUpgrader::StartUpgradeResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarStartUpgradeResponse* response, void* client_data) {
|
||||
LivoxLidarUpgrader* upgrade = static_cast<LivoxLidarUpgrader *>(client_data);
|
||||
|
||||
if (status == kLivoxLidarStatusSuccess) {
|
||||
upgrade->try_count_ = 0;
|
||||
printf("Start upgrade the livox_lidar[%u]\r\n", handle);
|
||||
if (response->ret_code) {
|
||||
if (response->ret_code == kSystemIsNotReady) {
|
||||
printf("Start upgrade failed, the livox_lidar[%u] is busy, try again!\r\n", handle);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventRequestUpgrade, 10);
|
||||
} else if (response->ret_code == EraseFirmware) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
printf("Start upgrade, erase livox_lidar[%u] firmware!\r\n", handle);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventRequestUpgrade, 10);
|
||||
} else {
|
||||
printf("Start upgrade failed, the livox_lidar[%u] ret_code[%d], try again!\r\n", handle, response->ret_code);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
}
|
||||
} else {
|
||||
printf("Start upgrade succ, the livox_lidar[%u] start to xfer data!\r\n", handle);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventXferFirmware, 20);
|
||||
}
|
||||
} else {
|
||||
printf("Start upgrade failed, the livox_lidar[%u] status:%d start upgrade is timeout[%d], try again!\r\n", handle, status, upgrade->try_count_);
|
||||
++upgrade->try_count_;
|
||||
if (upgrade->try_count_ < kGeneralTryCountLimit) {
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventRequestUpgrade, 10);
|
||||
} else {
|
||||
upgrade->try_count_ = 0;
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
printf("Start upgrade failed, the livox_lidar[%u] start upgrade exceed limit! exit!\r\n", handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LivoxLidarUpgrader::XferFirmwareResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarXferFirmwareResponse* response, void* client_data) {
|
||||
LivoxLidarUpgrader* upgrade = static_cast<LivoxLidarUpgrader *>(client_data);
|
||||
|
||||
if (status == kLivoxLidarStatusSuccess) {
|
||||
upgrade->try_count_ = 0;
|
||||
if (response->ret_code) {
|
||||
printf("The livox_lidar[%u] Xfer firmware fail[%d]\r\n", handle, response->ret_code);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
} else {
|
||||
upgrade->read_offset_ += upgrade->read_length_;
|
||||
if (upgrade->read_offset_ < upgrade->firmware_.header_.firmware_length) {
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventXferFirmware, 20);
|
||||
} else {
|
||||
printf("Xfer firmware succ, the livox_lidar[%u] last offset[%d]\r\n", handle, upgrade->read_offset_);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventCompleteXferFirmware, 40);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("Xfer firmware failed, the livox_lidar[%u] xfer firmware timeout, try_count:%d, try again!\r\n", handle, upgrade->try_count_);
|
||||
++upgrade->try_count_;
|
||||
if (upgrade->try_count_ < kGeneralTryCountLimit) {
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventXferFirmware, 20);
|
||||
} else {
|
||||
upgrade->try_count_ = 0;
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
printf("Xfer firmware failed, the livox_lidar[%u] exceed limit! exit!\r\n", handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LivoxLidarUpgrader::CompleteXferFirmwareResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarCompleteXferFirmwareResponse* response, void* client_data) {
|
||||
LivoxLidarUpgrader* upgrade = static_cast<LivoxLidarUpgrader *>(client_data);
|
||||
|
||||
if (status == kLivoxLidarStatusSuccess) {
|
||||
upgrade->try_count_ = 0;
|
||||
if (response->ret_code) {
|
||||
printf("Complete xfer failed, the livox_lidar[%u] ret_code:%d.\r\n", handle, response->ret_code);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
} else {
|
||||
printf("The livox_lidar[%u] complete xfer succ.\n", handle);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventGetUpgradeProgress, 50);
|
||||
}
|
||||
} else {
|
||||
printf("Complete xfer failed, the livox_lidar[%u] complete xfer is timeout, try_count:%d, try again!\r\n", handle, upgrade->try_count_);
|
||||
++upgrade->try_count_;
|
||||
if (upgrade->try_count_ < kGeneralTryCountLimit) {
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventCompleteXferFirmware, 50);
|
||||
} else {
|
||||
upgrade->try_count_ = 0;
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
printf("Complete xfer failed, the livox_lidar[%u] complete xfer exceed limit! exit!\r\n", handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LivoxLidarUpgrader::GetProgressResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarGetUpgradeProgressResponse* response, void* client_data) {
|
||||
LivoxLidarUpgrader* upgrade = static_cast<LivoxLidarUpgrader *>(client_data);
|
||||
if (status == kLivoxLidarStatusSuccess) {
|
||||
upgrade->try_count_ = 0;
|
||||
if (response->ret_code) {
|
||||
printf("Get progress failed, the livox_lidar[%u] ret_code:%d.\r\n", handle, response->ret_code);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
} else {
|
||||
if (response->progress < 100) {
|
||||
printf("The livox_lidar[%u] get progress[%u]\r\n", handle, response->progress);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventGetUpgradeProgress, response->progress/2 + 50);
|
||||
} else {
|
||||
printf("The livox_lidar[%u] Get progress[%u]\r\n", handle, response->progress);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventComplete, 100);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//printf("Get progress failed, the livox_lidar[%d] get progress timeout, try_count:%d, try again!\r\n", handle, upgrade->try_count_);
|
||||
++upgrade->try_count_;
|
||||
if (upgrade->try_count_ < kGetProcessTryCountLimit) {
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventGetUpgradeProgress, upgrade->progress_/2 + 50);
|
||||
} else {
|
||||
upgrade->try_count_ = 0;
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
printf("Get progress failed, the livox_lidar[%u] get progress exceed limit! exit!\r\n", handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LivoxLidarUpgrader::UpgradeCompleteResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarRebootResponse* response, void* client_data) {
|
||||
LivoxLidarUpgrader* upgrade = static_cast<LivoxLidarUpgrader *>(client_data);
|
||||
|
||||
if (status == kLivoxLidarStatusSuccess) {
|
||||
upgrade->try_count_ = 0;
|
||||
if (response->ret_code) {
|
||||
printf("Upgrade complete failed, the livox_lidar[%u], ret_code[%d] reboot device fail!\r\n", handle, response->ret_code);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventErr, 100);
|
||||
} else {
|
||||
printf("The livox_lidar[%u] upgrade complete succ.\n", handle);
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventReinit, 100);
|
||||
}
|
||||
} else {
|
||||
printf("Upgrade complete failed, the livox_lidar[%u] reboot device timeout, try_count:%d, try again!\r\n",
|
||||
handle, upgrade->try_count_);
|
||||
++upgrade->try_count_;
|
||||
if (upgrade->try_count_ < kGeneralTryCountLimit) {
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventComplete, 100);
|
||||
} else {
|
||||
upgrade->try_count_ = 0;
|
||||
upgrade->FsmEventHandler(kLivoxLidarEventReinit, 100);
|
||||
printf("Upgrade complete failed, the livox_lidar[%u] reboot device exceed limit! exit!\r\n", handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace comm
|
||||
} // namespace livox
|
||||
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2022 Livox. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#ifndef LIVOX_LIDAR_UPGRADER_H_
|
||||
#define LIVOX_LIDAR_UPGRADER_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
|
||||
#include "firmware.h"
|
||||
#include "../comm/define.h"
|
||||
#include "livox_lidar_def.h"
|
||||
|
||||
namespace livox {
|
||||
namespace lidar {
|
||||
|
||||
static const uint8_t EraseFirmware = 0x34;
|
||||
|
||||
class LivoxLidarUpgrader {
|
||||
public:
|
||||
using UpgradeProgressCallback = std::function<void(uint32_t handle, LivoxLidarUpgradeState state)>;
|
||||
|
||||
LivoxLidarUpgrader(const Firmware& firmware, const uint32_t handle);
|
||||
~LivoxLidarUpgrader();
|
||||
|
||||
void AddUpgradeProgressObserver(UpgradeProgressCallback observer);
|
||||
bool StartUpgradeLivoxLidar();
|
||||
|
||||
livox_status StartUpgrade();
|
||||
livox_status XferFirmware();
|
||||
livox_status CompleteXferFirmware();
|
||||
livox_status GetUpgradeProgress();
|
||||
livox_status UpgradeComplete();
|
||||
|
||||
static void StartUpgradeResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarStartUpgradeResponse* response, void* client_data);
|
||||
static void XferFirmwareResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarXferFirmwareResponse* response, void* client_data);
|
||||
static void CompleteXferFirmwareResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarCompleteXferFirmwareResponse* response, void* client_data);
|
||||
static void GetProgressResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarGetUpgradeProgressResponse* response, void* client_data);
|
||||
static void UpgradeCompleteResponseHandler(livox_status status, uint32_t handle,
|
||||
LivoxLidarRebootResponse* response, void* client_data);
|
||||
|
||||
int32_t LivoxLidarFsmStateChange(LivoxLidarFsmEvent event);
|
||||
void FsmEventHandler(LivoxLidarFsmEvent event, uint8_t progress);
|
||||
|
||||
bool IsUpgradeComplete() { return (fsm_state_ == kLivoxLidarUpgradeIdle); }
|
||||
bool IsUpgradeError() { return (fsm_state_ == kLivoxLidarUpgradeTimeout) || (fsm_state_ == kLivoxLidarUpgradeErr); }
|
||||
|
||||
private:
|
||||
const Firmware& firmware_;
|
||||
uint32_t read_offset_;
|
||||
uint32_t read_length_;
|
||||
uint32_t handle_;
|
||||
uint32_t fsm_state_;
|
||||
|
||||
uint32_t upgrade_error_;
|
||||
uint8_t progress_;
|
||||
|
||||
uint32_t try_count_;
|
||||
std::shared_ptr<std::thread> upgrade_thread_;
|
||||
UpgradeProgressCallback observer_;
|
||||
|
||||
};
|
||||
|
||||
} // namespace comm
|
||||
} // namespace LIVOX_LIDAR_UPGRADER_H_
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user