Implementing the firmware update interrupt tests (#164)

Refactors the firmware update tests to make it easier to implement the interrupt tests.
Implementing the interrupt tests.
This commit is contained in:
Derek M 2019-03-22 16:13:10 -07:00 коммит произвёл GitHub
Родитель 7f943693f5
Коммит e8cec587bd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 1324 добавлений и 525 удалений

Просмотреть файл

@ -50,7 +50,8 @@ can be run using "ctest -L perf" in the build directory.
Firmware tests are used to validate new firmware drops. They are run manually
when a new firmware candidate is given and will require hardware. Firmware
tests are built using the GoogleTest framework. After compiling, firmware tests
can be run using "ctest -L firmware" in the build directory.
can be run using "bin\firmware_fw.exe --firmware \<firmware path\>" in the build
directory.
## Running tests

Просмотреть файл

@ -6,7 +6,7 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_executable(firmware_fw firmware_fw.cpp)
add_executable(firmware_fw firmware_helper.cpp firmware_fw.cpp firmware_interrupt_fw.cpp)
target_link_libraries(firmware_fw PRIVATE
k4ainternal::utcommon

Просмотреть файл

@ -1,134 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#define _CRT_NONSTDC_NO_DEPRECATE
#include "firmware_helper.h"
#include <utcommon.h>
#include <ConnEx.h>
#include <k4ainternal/firmware.h>
#include <k4ainternal/logging.h>
#include <azure_c_shared_utility/tickcounter.h>
#include <azure_c_shared_utility/threadapi.h>
#define UPDATE_TIMEOUT_MS 10 * 60 * 1000 // 10 Minutes should be way more than enough.
#define K4A_DEPTH_MODE_NFOV_UNBINNED_EXPECTED_SIZE 737280
// This will define the path to the new firmware drop to test and the last known good firmware drop. The firmware update
// process runs from the current firmware. In order to test the firmware update process, the device must be on the
// firmware you want to test and then updated to a different firmware.
#define K4A_TEST_FIRMWARE_PATH "..\\..\\tools\\updater\\firmware\\AzureKinectDK_Fw_1.5.886314.bin"
#define K4A_LKG_FIRMWARE_PATH "..\\..\\tools\\updater\\firmware\\AzureKinectDK_Fw_1.5.786013.bin"
static k4a_result_t load_firmware_files(char *firmware_path, uint8_t **firmware_buffer, size_t *firmware_size);
typedef enum
{
FIRMWARE_OPERATION_AUDIO,
FIRMWARE_OPERATION_DEPTH_CONFIG,
FIRMWARE_OPERATION_DEPTH,
FIRMWARE_OPERATION_RGB,
FIRMWARE_OPERATION_FULL_DEVICE,
} firmware_operation_component_t;
typedef enum
{
FIRMWARE_OPERATION_RESET,
FIRMWARE_OPERATION_DISCONNECT,
} firmware_operation_interruption_t;
class firmware_fw : public ::testing::Test
{
public:
static void SetUpTestCase()
{
int port;
float voltage;
float current;
k4a_port_number = -1;
connEx = new (std::nothrow) connection_exerciser();
LOG_INFO("Searching for Connection Exerciser...", 0);
ASSERT_TRUE(K4A_SUCCEEDED(connEx->find_connection_exerciser()));
LOG_INFO("Clearing port...");
ASSERT_TRUE(K4A_SUCCEEDED(connEx->set_usb_port(0)));
LOG_INFO("Searching for device...");
for (int i = 0; i < CONN_EX_MAX_NUM_PORTS; ++i)
{
ASSERT_TRUE(K4A_SUCCEEDED(connEx->set_usb_port(i)));
port = connEx->get_usb_port();
ASSERT_TRUE(port == i);
voltage = connEx->get_voltage_reading();
ASSERT_FALSE(voltage == -1);
current = connEx->get_current_reading();
ASSERT_FALSE(current == -1);
if (current < 0)
{
current = current * -1;
}
if (voltage > 4.5 && voltage < 5.5 && current > 0.1)
{
ASSERT_TRUE(k4a_port_number == -1) << "More than one device was detected on the connection exerciser.";
k4a_port_number = port;
}
printf("On port #%d: %4.2fV %4.2fA\n", port, voltage, current);
}
ASSERT_FALSE(k4a_port_number == -1)
<< "The Kinect for Azure was not detected on a port of the connection exerciser.";
connEx->set_usb_port(port);
std::cout << "Loading test firmware package: " << K4A_TEST_FIRMWARE_PATH << std::endl;
load_firmware_files(K4A_TEST_FIRMWARE_PATH, &test_firmware_buffer, &test_firmware_size);
parse_firmware_package(test_firmware_buffer, test_firmware_size, &test_firmware_package_info);
std::cout << "Loading LKG firmware package: " << K4A_LKG_FIRMWARE_PATH << std::endl;
load_firmware_files(K4A_LKG_FIRMWARE_PATH, &lkg_firmware_buffer, &lkg_firmware_size);
parse_firmware_package(lkg_firmware_buffer, lkg_firmware_size, &lkg_firmware_package_info);
}
static void TearDownTestCase()
{
if (connEx != nullptr)
{
delete connEx;
connEx = nullptr;
}
if (test_firmware_buffer != nullptr)
{
free(test_firmware_buffer);
test_firmware_buffer = nullptr;
}
if (lkg_firmware_buffer != nullptr)
{
free(lkg_firmware_buffer);
lkg_firmware_buffer = nullptr;
}
}
protected:
void SetUp() override
{
ASSERT_EQ(K4A_RESULT_SUCCEEDED, TRACE_CALL(setup_common_test()));
const ::testing::TestInfo *const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
LOG_INFO("Test %s requires a connection exerciser.", test_info->name());
LOG_INFO("Disconnecting the device", 0);
connEx->set_usb_port(0);
g_connection_exerciser->set_usb_port(0);
ThreadAPI_Sleep(500);
// Make sure that all of the firmwares have loaded correctly.
ASSERT_TRUE(g_test_firmware_buffer != nullptr);
ASSERT_TRUE(g_test_firmware_size > 0);
ASSERT_TRUE(g_candidate_firmware_buffer != nullptr);
ASSERT_TRUE(g_candidate_firmware_size > 0);
ASSERT_TRUE(g_lkg_firmware_buffer != nullptr);
ASSERT_TRUE(g_lkg_firmware_size > 0);
ASSERT_TRUE(g_factory_firmware_buffer != nullptr);
ASSERT_TRUE(g_factory_firmware_size > 0);
// Make sure that the Test firmware has all components with a different version when compared to the Release
// Candidate firmware.
// Depth Sensor isn't expect to change.
ASSERT_FALSE(compare_version(g_test_firmware_package_info.audio, g_candidate_firmware_package_info.audio));
ASSERT_FALSE(compare_version(g_test_firmware_package_info.depth, g_candidate_firmware_package_info.depth));
ASSERT_FALSE(compare_version(g_test_firmware_package_info.rgb, g_candidate_firmware_package_info.rgb));
// There should be no other devices.
uint32_t device_count = 0;
usb_cmd_get_device_count(&device_count);
@ -142,438 +51,144 @@ protected:
firmware_destroy(firmware_handle);
firmware_handle = nullptr;
}
if (serial_number != nullptr)
{
free(serial_number);
serial_number = nullptr;
serial_number_length = 0;
}
}
void open_k4a_device();
void open_firmware_device();
void interrupt_operation(firmware_operation_interruption_t interruption);
void reset_device();
void interrupt_device_at_update_stage(firmware_operation_component_t component,
firmware_operation_interruption_t interruption,
firmware_status_summary_t *finalStatus);
static int k4a_port_number;
static connection_exerciser *connEx;
static uint8_t *test_firmware_buffer;
static size_t test_firmware_size;
static firmware_package_info_t test_firmware_package_info;
static uint8_t *lkg_firmware_buffer;
static size_t lkg_firmware_size;
static firmware_package_info_t lkg_firmware_package_info;
firmware_t firmware_handle = nullptr;
k4a_hardware_version_t current_version = { 0 };
char *serial_number = nullptr;
size_t serial_number_length = 0;
};
int firmware_fw::k4a_port_number = -1;
connection_exerciser *firmware_fw::connEx = nullptr;
uint8_t *firmware_fw::test_firmware_buffer = nullptr;
size_t firmware_fw::test_firmware_size = 0;
firmware_package_info_t firmware_fw::test_firmware_package_info = { 0 };
uint8_t *firmware_fw::lkg_firmware_buffer = nullptr;
size_t firmware_fw::lkg_firmware_size = 0;
firmware_package_info_t firmware_fw::lkg_firmware_package_info = { 0 };
static k4a_result_t load_firmware_files(char *firmware_path, uint8_t **firmware_buffer, size_t *firmware_size)
TEST_F(firmware_fw, DISABLED_update_timing)
{
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, firmware_path == NULL);
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, firmware_buffer == NULL);
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, firmware_size == NULL);
LOG_INFO("Beginning the manual test to get update timings.", 0);
ASSERT_EQ(K4A_RESULT_SUCCEEDED, g_connection_exerciser->set_usb_port(g_k4a_port_number));
k4a_result_t result = K4A_RESULT_FAILED;
FILE *pFirmwareFile = NULL;
size_t numRead = 0;
uint8_t *tempFirmwareBuffer = NULL;
ASSERT_EQ(K4A_RESULT_SUCCEEDED, open_firmware_device(&firmware_handle));
if ((pFirmwareFile = fopen(firmware_path, "rb")) != NULL)
{
fseek(pFirmwareFile, 0, SEEK_END);
size_t tempFirmwareSize = (size_t)ftell(pFirmwareFile);
if (tempFirmwareSize == (size_t)-1L)
{
std::cout << "ERROR: Failed to get size of the firmware package." << std::endl;
return K4A_RESULT_FAILED;
}
ASSERT_EQ(K4A_BUFFER_RESULT_TOO_SMALL, firmware_get_device_serialnum(firmware_handle, NULL, &serial_number_length));
fseek(pFirmwareFile, 0, SEEK_SET);
serial_number = (char *)malloc(serial_number_length);
ASSERT_NE(nullptr, serial_number);
tempFirmwareBuffer = (uint8_t *)malloc(tempFirmwareSize);
if (tempFirmwareBuffer == NULL)
{
std::cout << "ERROR: Failed to allocate memory." << std::endl;
return K4A_RESULT_FAILED;
}
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
firmware_get_device_serialnum(firmware_handle, serial_number, &serial_number_length));
std::cout << "File size: " << tempFirmwareSize << " bytes" << std::endl;
numRead = fread(tempFirmwareBuffer, tempFirmwareSize, 1, pFirmwareFile);
fclose(pFirmwareFile);
LOG_INFO("Updating the device to the Candidate firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_candidate_firmware_buffer,
g_candidate_firmware_size,
g_candidate_firmware_package_info,
true));
if (numRead != 1)
{
std::cout << "ERROR: Could not read all data from the file" << std::endl;
}
else
{
*firmware_buffer = tempFirmwareBuffer;
*firmware_size = tempFirmwareSize;
tempFirmwareBuffer = NULL;
result = K4A_RESULT_SUCCEEDED;
}
}
else
{
std::cout << "ERROR: Cannot Open (" << firmware_path << ") errno=" << errno << std::endl;
}
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
if (tempFirmwareBuffer)
{
free(tempFirmwareBuffer);
}
LOG_INFO("Updating the device to the Test firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_test_firmware_buffer,
g_test_firmware_size,
g_test_firmware_package_info,
true));
return result;
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
}
static firmware_operation_status_t calculate_overall_component_status(const firmware_component_status_t status)
TEST_F(firmware_fw, simple_update_from_lkg)
{
if (status.overall == FIRMWARE_OPERATION_SUCCEEDED)
{
return FIRMWARE_OPERATION_SUCCEEDED;
}
LOG_INFO("Beginning the basic update test from the LKG firmware.", 0);
ASSERT_EQ(K4A_RESULT_SUCCEEDED, g_connection_exerciser->set_usb_port(g_k4a_port_number));
if (status.overall == FIRMWARE_OPERATION_INPROGRESS)
{
return FIRMWARE_OPERATION_INPROGRESS;
}
ASSERT_EQ(K4A_RESULT_SUCCEEDED, open_firmware_device(&firmware_handle));
// If the version check failed, this component's update was skipped. This could because the new version is
// an unsafe downgrade or the versions are the same and no update is required.
if (status.version_check == FIRMWARE_OPERATION_FAILED)
{
return FIRMWARE_OPERATION_SUCCEEDED;
}
ASSERT_EQ(K4A_BUFFER_RESULT_TOO_SMALL, firmware_get_device_serialnum(firmware_handle, NULL, &serial_number_length));
return FIRMWARE_OPERATION_FAILED;
serial_number = (char *)malloc(serial_number_length);
ASSERT_NE(nullptr, serial_number);
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
firmware_get_device_serialnum(firmware_handle, serial_number, &serial_number_length));
LOG_INFO("Updating the device to the LKG firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_lkg_firmware_buffer,
g_lkg_firmware_size,
g_lkg_firmware_package_info,
false));
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
LOG_INFO("Updating the device to the Candidate firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_candidate_firmware_buffer,
g_candidate_firmware_size,
g_candidate_firmware_package_info,
false));
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
LOG_INFO("Updating the device to the Test firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_test_firmware_buffer,
g_test_firmware_size,
g_test_firmware_package_info,
false));
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
}
static bool compare_version(k4a_version_t left_version, k4a_version_t right_version)
TEST_F(firmware_fw, simple_update_from_factory)
{
return left_version.major == right_version.major && left_version.minor == right_version.minor &&
left_version.iteration == right_version.iteration;
LOG_INFO("Beginning the basic update test from the Factory firmware.", 0);
ASSERT_EQ(K4A_RESULT_SUCCEEDED, g_connection_exerciser->set_usb_port(g_k4a_port_number));
ASSERT_EQ(K4A_RESULT_SUCCEEDED, open_firmware_device(&firmware_handle));
ASSERT_EQ(K4A_BUFFER_RESULT_TOO_SMALL, firmware_get_device_serialnum(firmware_handle, NULL, &serial_number_length));
serial_number = (char *)malloc(serial_number_length);
ASSERT_NE(nullptr, serial_number);
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
firmware_get_device_serialnum(firmware_handle, serial_number, &serial_number_length));
LOG_INFO("Updating the device to the Factory firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_factory_firmware_buffer,
g_factory_firmware_size,
g_factory_firmware_package_info,
false));
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
LOG_INFO("Updating the device to the Candidate firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_candidate_firmware_buffer,
g_candidate_firmware_size,
g_candidate_firmware_package_info,
false));
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
LOG_INFO("Updating the device to the Test firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_test_firmware_buffer,
g_test_firmware_size,
g_test_firmware_package_info,
false));
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
}
static bool compare_version_list(k4a_version_t device_version, uint8_t count, k4a_version_t versions[5])
{
for (int i = 0; i < count; ++i)
{
if (device_version.major == versions[i].major && device_version.minor == versions[i].minor)
{
return true;
}
}
return false;
}
static void log_firmware_build_config(k4a_firmware_build_t build_config)
{
std::cout << " Build Config: ";
switch (build_config)
{
case K4A_FIRMWARE_BUILD_RELEASE:
std::cout << "Production" << std::endl;
break;
case K4A_FIRMWARE_BUILD_DEBUG:
std::cout << "Debug" << std::endl;
break;
default:
std::cout << "Unknown" << std::endl;
}
}
static void log_firmware_signature_type(k4a_firmware_signature_t signature_type, bool certificate)
{
if (certificate)
{
std::cout << " Certificate Type: ";
}
else
{
std::cout << " Signature Type: ";
}
switch (signature_type)
{
case K4A_FIRMWARE_SIGNATURE_MSFT:
std::cout << "Microsoft" << std::endl;
break;
case K4A_FIRMWARE_SIGNATURE_TEST:
std::cout << "Test" << std::endl;
break;
case K4A_FIRMWARE_SIGNATURE_UNSIGNED:
std::cout << "Unsigned" << std::endl;
break;
default:
std::cout << "Unknown (" << signature_type << ")" << std::endl;
}
}
static void log_firmware_version(firmware_package_info_t firmware_version)
{
std::cout << "Firmware Package Versions:" << std::endl;
std::cout << " RGB camera firmware: " << firmware_version.rgb.major << "." << firmware_version.rgb.minor
<< "." << firmware_version.rgb.iteration << std::endl;
std::cout << " Depth camera firmware: " << firmware_version.depth.major << "." << firmware_version.depth.minor
<< "." << firmware_version.depth.iteration << std::endl;
std::cout << " Depth config file: ";
for (size_t i = 0; i < firmware_version.depth_config_number_versions; i++)
{
std::cout << firmware_version.depth_config_versions[i].major << "."
<< firmware_version.depth_config_versions[i].minor << " ";
}
std::cout << std::endl;
std::cout << " Audio firmware: " << firmware_version.audio.major << "." << firmware_version.audio.minor
<< "." << firmware_version.audio.iteration << std::endl;
log_firmware_build_config(firmware_version.build_config);
log_firmware_signature_type(firmware_version.certificate_type, true);
log_firmware_signature_type(firmware_version.signature_type, false);
}
static void log_device_version(k4a_hardware_version_t firmware_version)
{
std::cout << "Current Firmware Versions:" << std::endl;
std::cout << " RGB camera firmware: " << (uint16_t)firmware_version.rgb.major << "."
<< (uint16_t)firmware_version.rgb.minor << "." << firmware_version.rgb.iteration << std::endl;
std::cout << " Depth camera firmware: " << (uint16_t)firmware_version.depth.major << "."
<< (uint16_t)firmware_version.depth.minor << "." << firmware_version.depth.iteration << std::endl;
std::cout << " Depth config file: " << firmware_version.depth_sensor.major << "."
<< firmware_version.depth_sensor.minor << std::endl;
std::cout << " Audio firmware: " << (uint16_t)firmware_version.audio.major << "."
<< (uint16_t)firmware_version.audio.minor << "." << firmware_version.audio.iteration << std::endl;
log_firmware_build_config((k4a_firmware_build_t)firmware_version.firmware_build);
log_firmware_signature_type((k4a_firmware_signature_t)firmware_version.firmware_signature, true);
}
void firmware_fw::open_firmware_device()
{
int retry = 0;
uint32_t device_count = 0;
while (device_count == 0 && retry++ < 20)
{
ThreadAPI_Sleep(500);
usb_cmd_get_device_count(&device_count);
}
ASSERT_LE(retry, 20) << "Device never returned.";
LOG_INFO("Opening firmware device...", 0);
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_create(K4A_DEVICE_DEFAULT, &firmware_handle))
<< "Couldn't open firmware\n";
ASSERT_NE(firmware_handle, nullptr);
}
void firmware_fw::reset_device()
{
LOG_INFO("Resetting device...", 0);
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_reset_device(firmware_handle));
firmware_destroy(firmware_handle);
firmware_handle = nullptr;
// Re-open the device to ensure it is ready.
open_firmware_device();
}
void firmware_fw::interrupt_operation(firmware_operation_interruption_t interruption)
{
switch (interruption)
{
case FIRMWARE_OPERATION_RESET:
reset_device();
break;
default:
ASSERT_TRUE(false) << "Unknown interruption type";
}
}
void firmware_fw::interrupt_device_at_update_stage(firmware_operation_component_t component,
firmware_operation_interruption_t interruption,
firmware_status_summary_t *finalStatus)
{
ASSERT_NE(nullptr, finalStatus);
bool all_complete = false;
k4a_result_t result = K4A_RESULT_FAILED;
tickcounter_ms_t start_time_ms, now;
TICK_COUNTER_HANDLE tick = tickcounter_create();
ASSERT_NE(nullptr, tick) << "Failed to create tick counter.";
ASSERT_EQ(0, tickcounter_get_current_ms(tick, &start_time_ms));
do
{
// This is not the necessarily the final status we will get, but at any point could return and the caller needs
// to know the state of the update when we return.
result = firmware_get_download_status(firmware_handle, finalStatus);
if (result == K4A_RESULT_SUCCEEDED)
{
all_complete = ((finalStatus->audio.overall > FIRMWARE_OPERATION_INPROGRESS) &&
(finalStatus->depth_config.overall > FIRMWARE_OPERATION_INPROGRESS) &&
(finalStatus->depth.overall > FIRMWARE_OPERATION_INPROGRESS) &&
(finalStatus->rgb.overall > FIRMWARE_OPERATION_INPROGRESS));
// Check to see if now is the correct time to interrupt the device.
switch (component)
{
case FIRMWARE_OPERATION_AUDIO:
if (finalStatus->audio.version_check != FIRMWARE_OPERATION_INPROGRESS)
{
interrupt_operation(interruption);
return;
}
break;
case FIRMWARE_OPERATION_DEPTH_CONFIG:
if (finalStatus->depth_config.version_check != FIRMWARE_OPERATION_INPROGRESS)
{
interrupt_operation(interruption);
return;
}
break;
case FIRMWARE_OPERATION_DEPTH:
if (finalStatus->depth.version_check != FIRMWARE_OPERATION_INPROGRESS)
{
interrupt_operation(interruption);
return;
}
break;
case FIRMWARE_OPERATION_RGB:
if (finalStatus->rgb.version_check != FIRMWARE_OPERATION_INPROGRESS)
{
interrupt_operation(interruption);
return;
}
break;
default:
break;
}
}
else
{
// Failed to get the status of the update operation. Break out of the loop to attempt to reset the device
// and return.
EXPECT_TRUE(false) << "ERROR: Failed to get the firmware update status.";
break;
}
ASSERT_EQ(0, tickcounter_get_current_ms(tick, &now));
if (!all_complete && (now - start_time_ms > UPDATE_TIMEOUT_MS))
{
// The update hasn't completed and too much time as passed. Break out of the loop to attempt to reset the
// device and return.
EXPECT_TRUE(false) << "ERROR: Timeout waiting for the update to complete.";
break;
}
if (!all_complete)
{
ThreadAPI_Sleep(500);
}
} while (!all_complete);
// At this point the update has either completed or timed out. Either way the device needs to be reset after the
// update has progressed.
interrupt_operation(FIRMWARE_OPERATION_RESET);
}
TEST_F(firmware_fw, simple_update)
{
firmware_status_summary_t finalStatus;
LOG_INFO("Beginning the basic update test", 0);
connEx->set_usb_port(k4a_port_number);
open_firmware_device();
// Update to the test firmware
LOG_INFO("Updating the device to the test firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_get_device_version(firmware_handle, &current_version));
log_device_version(current_version);
log_firmware_version(test_firmware_package_info);
// Perform upgrade...
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_download(firmware_handle, test_firmware_buffer, test_firmware_size));
interrupt_device_at_update_stage(FIRMWARE_OPERATION_FULL_DEVICE, FIRMWARE_OPERATION_RESET, &finalStatus);
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.audio));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth_config));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.rgb));
// Check upgrade...
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_get_device_version(firmware_handle, &current_version));
log_device_version(current_version);
ASSERT_TRUE(compare_version(current_version.audio, test_firmware_package_info.audio)) << "Audio version mismatch";
ASSERT_TRUE(compare_version_list(current_version.depth_sensor,
test_firmware_package_info.depth_config_number_versions,
test_firmware_package_info.depth_config_versions))
<< "Depth Config mismatch";
ASSERT_TRUE(compare_version(current_version.depth, test_firmware_package_info.depth)) << "Depth mismatch";
ASSERT_TRUE(compare_version(current_version.rgb, test_firmware_package_info.rgb)) << "RGB mismatch";
// Update back to the LKG firmware
LOG_INFO("Updating the device back to the LKG firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_get_device_version(firmware_handle, &current_version));
log_device_version(current_version);
log_firmware_version(lkg_firmware_package_info);
// Perform upgrade...
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_download(firmware_handle, lkg_firmware_buffer, lkg_firmware_size));
interrupt_device_at_update_stage(FIRMWARE_OPERATION_FULL_DEVICE, FIRMWARE_OPERATION_RESET, &finalStatus);
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.audio));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth_config));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.rgb));
// Check upgrade...
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_get_device_version(firmware_handle, &current_version));
log_device_version(current_version);
ASSERT_TRUE(compare_version(current_version.audio, lkg_firmware_package_info.audio)) << "Audio version mismatch";
ASSERT_TRUE(compare_version_list(current_version.depth_sensor,
lkg_firmware_package_info.depth_config_number_versions,
lkg_firmware_package_info.depth_config_versions))
<< "Depth Config mismatch";
ASSERT_TRUE(compare_version(current_version.depth, lkg_firmware_package_info.depth)) << "Depth mismatch";
ASSERT_TRUE(compare_version(current_version.rgb, lkg_firmware_package_info.rgb)) << "RGB mismatch";
}
int main(int argc, char **argv)
{
k4a_unittest_init();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Просмотреть файл

@ -0,0 +1,822 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "firmware_helper.h"
#include <utcommon.h>
#include <azure_c_shared_utility/tickcounter.h>
#include <azure_c_shared_utility/threadapi.h>
#define K4A_TEST_VERIFY_SUCCEEDED(_result_) \
if (K4A_FAILED(TRACE_CALL(_result_))) \
{ \
return K4A_RESULT_FAILED; \
}
#define K4A_TEST_VERIFY_TRUE(_condition_) \
if (!(_condition_)) \
{ \
LOG_ERROR("\"" #_condition_ "\" was false but was expected to be true."); \
return K4A_RESULT_FAILED; \
}
#define K4A_TEST_VERIFY_LE(_val1_, _val2_) \
if ((_val1_) > (_val2_)) \
{ \
LOG_ERROR("\"" #_val1_ "\" > \"" #_val2_ "\" but was expected to be less than or equal."); \
std::cout << "\"" #_val1_ "\" = " << (_val1_) << " \"" #_val2_ "\" = " << (_val2_) << std::endl; \
return K4A_RESULT_FAILED; \
}
#define K4A_TEST_VERIFY_EQUAL(_val1_, _val2_) \
if ((_val1_) != (_val2_)) \
{ \
LOG_ERROR("\"" #_val1_ "\" != \"" #_val2_ "\" but was expected to be equal."); \
std::cout << "\"" #_val1_ "\" = " << (_val1_) << " \"" #_val2_ "\" = " << (_val2_) << std::endl; \
return K4A_RESULT_FAILED; \
}
#define K4A_TEST_VERIFY_NOT_EQUAL(_val1_, _val2_) \
if ((_val1_) == (_val2_)) \
{ \
LOG_ERROR("\"" #_val1_ "\" == \"" #_val2_ "\" but was expected to not be equal."); \
std::cout << "\"" #_val1_ "\" = " << (_val1_) << " \"" #_val2_ "\" = " << (_val2_) << std::endl; \
return K4A_RESULT_FAILED; \
}
char *g_candidate_firmware_path = nullptr;
int g_k4a_port_number = -1;
connection_exerciser *g_connection_exerciser = nullptr;
uint8_t *g_test_firmware_buffer = nullptr;
size_t g_test_firmware_size = 0;
firmware_package_info_t g_test_firmware_package_info = { 0 };
uint8_t *g_candidate_firmware_buffer = nullptr;
size_t g_candidate_firmware_size = 0;
firmware_package_info_t g_candidate_firmware_package_info = { 0 };
uint8_t *g_lkg_firmware_buffer = nullptr;
size_t g_lkg_firmware_size = 0;
firmware_package_info_t g_lkg_firmware_package_info = { 0 };
uint8_t *g_factory_firmware_buffer = nullptr;
size_t g_factory_firmware_size = 0;
firmware_package_info_t g_factory_firmware_package_info = { 0 };
static bool common_initialized = false;
k4a_result_t setup_common_test()
{
int port;
float voltage;
float current;
if (common_initialized)
{
return K4A_RESULT_SUCCEEDED;
}
if (g_candidate_firmware_path == nullptr)
{
std::cout << "The firmware path setting is required and wasn't supplied.\n\n";
return K4A_RESULT_FAILED;
}
g_k4a_port_number = -1;
g_connection_exerciser = new (std::nothrow) connection_exerciser();
LOG_INFO("Searching for Connection Exerciser...", 0);
K4A_TEST_VERIFY_SUCCEEDED(g_connection_exerciser->find_connection_exerciser());
LOG_INFO("Clearing port...");
K4A_TEST_VERIFY_SUCCEEDED(g_connection_exerciser->set_usb_port(0));
LOG_INFO("Searching for device...");
for (int i = 0; i < CONN_EX_MAX_NUM_PORTS; ++i)
{
K4A_TEST_VERIFY_SUCCEEDED(g_connection_exerciser->set_usb_port(i));
port = g_connection_exerciser->get_usb_port();
K4A_TEST_VERIFY_EQUAL(port, i);
voltage = g_connection_exerciser->get_voltage_reading();
K4A_TEST_VERIFY_NOT_EQUAL(voltage, -1);
current = g_connection_exerciser->get_current_reading();
K4A_TEST_VERIFY_NOT_EQUAL(current, -1);
if (current < 0)
{
current = current * -1;
}
if (voltage > 4.5 && voltage < 5.5 && current > 0.1)
{
if (g_k4a_port_number != -1)
{
std::cout << "More than one device was detected on the connection exerciser." << std::endl;
return K4A_RESULT_FAILED;
}
g_k4a_port_number = port;
}
printf("On port #%d: %4.2fV %4.2fA\n", port, voltage, current);
}
if (g_k4a_port_number == -1)
{
std::cout << "The Kinect for Azure was not detected on a port of the connection exerciser." << std::endl;
return K4A_RESULT_FAILED;
}
K4A_TEST_VERIFY_SUCCEEDED(g_connection_exerciser->set_usb_port(0));
std::cout << "Loading Test firmware package: " << K4A_TEST_FIRMWARE_PATH << std::endl;
load_firmware_files(K4A_TEST_FIRMWARE_PATH, &g_test_firmware_buffer, &g_test_firmware_size);
parse_firmware_package(g_test_firmware_buffer, g_test_firmware_size, &g_test_firmware_package_info);
std::cout << "Loading Release Candidate firmware package: " << g_candidate_firmware_path << std::endl;
load_firmware_files(g_candidate_firmware_path, &g_candidate_firmware_buffer, &g_candidate_firmware_size);
parse_firmware_package(g_candidate_firmware_buffer, g_candidate_firmware_size, &g_candidate_firmware_package_info);
std::cout << "Loading LKG firmware package: " << K4A_LKG_FIRMWARE_PATH << std::endl;
load_firmware_files(K4A_LKG_FIRMWARE_PATH, &g_lkg_firmware_buffer, &g_lkg_firmware_size);
parse_firmware_package(g_lkg_firmware_buffer, g_lkg_firmware_size, &g_lkg_firmware_package_info);
std::cout << "Loading Factory firmware package: " << K4A_FACTORY_FIRMWARE_PATH << std::endl;
load_firmware_files(K4A_FACTORY_FIRMWARE_PATH, &g_factory_firmware_buffer, &g_factory_firmware_size);
parse_firmware_package(g_factory_firmware_buffer, g_factory_firmware_size, &g_factory_firmware_package_info);
common_initialized = true;
return K4A_RESULT_SUCCEEDED;
}
void tear_down_common_test()
{
if (g_connection_exerciser != nullptr)
{
g_k4a_port_number = -1;
delete g_connection_exerciser;
g_connection_exerciser = nullptr;
}
if (g_test_firmware_buffer != nullptr)
{
free(g_test_firmware_buffer);
g_test_firmware_buffer = nullptr;
}
if (g_candidate_firmware_buffer != nullptr)
{
free(g_candidate_firmware_buffer);
g_candidate_firmware_buffer = nullptr;
}
if (g_lkg_firmware_buffer != nullptr)
{
free(g_lkg_firmware_buffer);
g_lkg_firmware_buffer = nullptr;
}
if (g_factory_firmware_buffer != nullptr)
{
free(g_factory_firmware_buffer);
g_factory_firmware_buffer = nullptr;
}
common_initialized = false;
}
k4a_result_t load_firmware_files(char *firmware_path, uint8_t **firmware_buffer, size_t *firmware_size)
{
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, firmware_path == NULL);
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, firmware_buffer == NULL);
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, firmware_size == NULL);
k4a_result_t result = K4A_RESULT_FAILED;
FILE *pFirmwareFile = NULL;
size_t numRead = 0;
uint8_t *tempFirmwareBuffer = NULL;
if ((pFirmwareFile = fopen(firmware_path, "rb")) != NULL)
{
fseek(pFirmwareFile, 0, SEEK_END);
size_t tempFirmwareSize = (size_t)ftell(pFirmwareFile);
if (tempFirmwareSize == (size_t)-1L)
{
std::cout << "ERROR: Failed to get size of the firmware package." << std::endl;
return K4A_RESULT_FAILED;
}
fseek(pFirmwareFile, 0, SEEK_SET);
tempFirmwareBuffer = (uint8_t *)malloc(tempFirmwareSize);
if (tempFirmwareBuffer == NULL)
{
std::cout << "ERROR: Failed to allocate memory." << std::endl;
return K4A_RESULT_FAILED;
}
std::cout << "File size: " << tempFirmwareSize << " bytes" << std::endl;
numRead = fread(tempFirmwareBuffer, tempFirmwareSize, 1, pFirmwareFile);
fclose(pFirmwareFile);
if (numRead != 1)
{
std::cout << "ERROR: Could not read all data from the file" << std::endl;
}
else
{
*firmware_buffer = tempFirmwareBuffer;
*firmware_size = tempFirmwareSize;
tempFirmwareBuffer = NULL;
result = K4A_RESULT_SUCCEEDED;
}
}
else
{
std::cout << "ERROR: Cannot Open (" << firmware_path << ") errno=" << errno << std::endl;
}
if (tempFirmwareBuffer)
{
free(tempFirmwareBuffer);
}
return result;
}
firmware_operation_status_t calculate_overall_component_status(const firmware_component_status_t status)
{
if (status.overall == FIRMWARE_OPERATION_SUCCEEDED)
{
return FIRMWARE_OPERATION_SUCCEEDED;
}
if (status.overall == FIRMWARE_OPERATION_INPROGRESS)
{
return FIRMWARE_OPERATION_INPROGRESS;
}
// If the version check failed, this component's update was skipped. This could because the new version is
// an unsafe downgrade or the versions are the same and no update is required.
if (status.version_check == FIRMWARE_OPERATION_FAILED)
{
return FIRMWARE_OPERATION_SUCCEEDED;
}
printf("Overall Component Status failed: A:%d V:%d T:%d E:%d W:%d O:%d\n",
status.authentication_check,
status.version_check,
status.image_transfer,
status.flash_erase,
status.flash_write,
status.overall);
return FIRMWARE_OPERATION_FAILED;
}
bool compare_version(k4a_version_t left_version, k4a_version_t right_version)
{
return left_version.major == right_version.major && left_version.minor == right_version.minor &&
left_version.iteration == right_version.iteration;
}
bool compare_version(k4a_hardware_version_t device_version, firmware_package_info_t firmware_version)
{
bool are_equal = true;
if (!compare_version(device_version.audio, firmware_version.audio))
{
printf("Audio version mismatch.\n");
are_equal = false;
}
if (!compare_version_list(device_version.depth_sensor,
firmware_version.depth_config_number_versions,
firmware_version.depth_config_versions))
{
printf("Depth sensor does not exist in package.\n");
are_equal = false;
}
if (!compare_version(device_version.depth, firmware_version.depth))
{
printf("Depth version mismatch.\n");
are_equal = false;
}
if (!compare_version(device_version.rgb, firmware_version.rgb))
{
printf("RGB version mismatch.\n");
are_equal = false;
}
return are_equal;
}
bool compare_version_list(k4a_version_t device_version, uint8_t count, k4a_version_t versions[5])
{
for (int i = 0; i < count; ++i)
{
if (device_version.major == versions[i].major && device_version.minor == versions[i].minor)
{
return true;
}
}
return false;
}
bool compare_device_serial_number(firmware_t firmware_handle, char *device_serial_number)
{
char *serial_number = nullptr;
size_t serial_number_length = 0;
if (K4A_BUFFER_RESULT_TOO_SMALL != firmware_get_device_serialnum(firmware_handle, nullptr, &serial_number_length))
{
printf("ERROR: Failed to get serial number length\n");
return false;
}
serial_number = (char *)malloc(serial_number_length);
if (serial_number == nullptr)
{
printf("ERROR: Failed to allocate memory for serial number (%zu bytes)\n", serial_number_length);
return false;
}
if (K4A_BUFFER_RESULT_SUCCEEDED !=
firmware_get_device_serialnum(firmware_handle, serial_number, &serial_number_length))
{
printf("ERROR: Failed to get serial number\n");
free(serial_number);
return false;
}
if (strcmp(device_serial_number, serial_number) != 0)
{
printf("\'%s\' != \'%s\'", device_serial_number, serial_number);
free(serial_number);
return false;
}
free(serial_number);
return true;
}
void log_firmware_build_config(k4a_firmware_build_t build_config)
{
std::cout << " Build Config: ";
switch (build_config)
{
case K4A_FIRMWARE_BUILD_RELEASE:
std::cout << "Production" << std::endl;
break;
case K4A_FIRMWARE_BUILD_DEBUG:
std::cout << "Debug" << std::endl;
break;
default:
std::cout << "Unknown" << std::endl;
}
}
void log_firmware_signature_type(k4a_firmware_signature_t signature_type, bool certificate)
{
if (certificate)
{
std::cout << " Certificate Type: ";
}
else
{
std::cout << " Signature Type: ";
}
switch (signature_type)
{
case K4A_FIRMWARE_SIGNATURE_MSFT:
std::cout << "Microsoft" << std::endl;
break;
case K4A_FIRMWARE_SIGNATURE_TEST:
std::cout << "Test" << std::endl;
break;
case K4A_FIRMWARE_SIGNATURE_UNSIGNED:
std::cout << "Unsigned" << std::endl;
break;
default:
std::cout << "Unknown (" << signature_type << ")" << std::endl;
}
}
void log_firmware_version(firmware_package_info_t firmware_version)
{
printf("Firmware Package Versions:\n");
printf(" RGB camera firmware: %d.%d.%d\n",
firmware_version.rgb.major,
firmware_version.rgb.minor,
firmware_version.rgb.iteration);
printf(" Depth camera firmware: %d.%d.%d\n",
firmware_version.depth.major,
firmware_version.depth.minor,
firmware_version.depth.iteration);
printf(" Depth config file: ");
for (size_t i = 0; i < firmware_version.depth_config_number_versions; i++)
{
printf("%d.%d ",
firmware_version.depth_config_versions[i].major,
firmware_version.depth_config_versions[i].minor);
}
printf("\n");
printf(" Audio firmware: %d.%d.%d\n",
firmware_version.audio.major,
firmware_version.audio.minor,
firmware_version.audio.iteration);
log_firmware_build_config(firmware_version.build_config);
log_firmware_signature_type(firmware_version.certificate_type, true);
log_firmware_signature_type(firmware_version.signature_type, false);
}
void log_device_version(k4a_hardware_version_t firmware_version)
{
printf("Current Firmware Versions:\n");
printf(" RGB camera firmware: %d.%d.%d\n",
firmware_version.rgb.major,
firmware_version.rgb.minor,
firmware_version.rgb.iteration);
printf(" Depth camera firmware: %d.%d.%d\n",
firmware_version.depth.major,
firmware_version.depth.minor,
firmware_version.depth.iteration);
printf(" Depth config file: %d.%d\n",
firmware_version.depth_sensor.major,
firmware_version.depth_sensor.minor);
printf(" Audio firmware: %d.%d.%d\n",
firmware_version.audio.major,
firmware_version.audio.minor,
firmware_version.audio.iteration);
log_firmware_build_config((k4a_firmware_build_t)firmware_version.firmware_build);
log_firmware_signature_type((k4a_firmware_signature_t)firmware_version.firmware_signature, true);
}
k4a_result_t open_firmware_device(firmware_t *firmware_handle)
{
int retry = 0;
uint32_t device_count = 0;
while (device_count == 0 && retry++ < 20)
{
ThreadAPI_Sleep(500);
K4A_TEST_VERIFY_SUCCEEDED(usb_cmd_get_device_count(&device_count));
}
K4A_TEST_VERIFY_LE(retry, 20);
LOG_INFO("Opening firmware device...", 0);
K4A_TEST_VERIFY_SUCCEEDED(firmware_create(K4A_DEVICE_DEFAULT, firmware_handle));
K4A_TEST_VERIFY_TRUE(*firmware_handle != nullptr);
return K4A_RESULT_SUCCEEDED;
}
k4a_result_t reset_device(firmware_t *firmware_handle)
{
LOG_INFO("Resetting device...", 0);
K4A_TEST_VERIFY_SUCCEEDED(firmware_reset_device(*firmware_handle));
firmware_destroy(*firmware_handle);
*firmware_handle = nullptr;
// Re-open the device to ensure it is ready for use.
return TRACE_CALL(open_firmware_device(firmware_handle));
}
k4a_result_t disconnect_device(firmware_t *firmware_handle)
{
LOG_INFO("Disconnecting device...", 0);
K4A_TEST_VERIFY_SUCCEEDED(g_connection_exerciser->set_usb_port(0));
ThreadAPI_Sleep(500);
K4A_TEST_VERIFY_SUCCEEDED(g_connection_exerciser->set_usb_port(g_k4a_port_number));
firmware_destroy(*firmware_handle);
*firmware_handle = nullptr;
// Re-open the device to ensure it is ready for use.
return TRACE_CALL(open_firmware_device(firmware_handle));
}
k4a_result_t interrupt_operation(firmware_t *firmware_handle, firmware_operation_interruption_t interruption)
{
switch (interruption)
{
case FIRMWARE_INTERRUPTION_RESET:
return TRACE_CALL(reset_device(firmware_handle));
break;
case FIRMWARE_INTERRUPTION_DISCONNECT:
return TRACE_CALL(disconnect_device(firmware_handle));
break;
default:
LOG_ERROR("Unknown interruption type");
return K4A_RESULT_FAILED;
}
}
k4a_result_t interrupt_device_at_update_stage(firmware_t *firmware_handle,
firmware_operation_component_t component,
firmware_operation_interruption_t interruption,
firmware_status_summary_t *final_status,
bool verbose_logging)
{
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, firmware_handle == nullptr);
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, final_status == nullptr);
bool all_complete = false;
k4a_result_t result = K4A_RESULT_FAILED;
firmware_status_summary_t previous_status = {};
tickcounter_ms_t start_time_ms, now;
TICK_COUNTER_HANDLE tick = tickcounter_create();
K4A_TEST_VERIFY_TRUE(tick != nullptr);
K4A_TEST_VERIFY_EQUAL(0, tickcounter_get_current_ms(tick, &start_time_ms));
do
{
// This is not necessarily the final status we will get, but at any point could return and the caller needs to
// know the state of the update when we return.
result = firmware_get_download_status(*firmware_handle, final_status);
if (result == K4A_RESULT_SUCCEEDED)
{
if (verbose_logging)
{
if (memcmp(&previous_status.audio, &final_status->audio, sizeof(firmware_component_status_t)) != 0)
{
LOG_INFO("Audio: A:%d V:%d T:%d E:%d W:%d O:%d",
final_status->audio.authentication_check,
final_status->audio.version_check,
final_status->audio.image_transfer,
final_status->audio.flash_erase,
final_status->audio.flash_write,
final_status->audio.overall);
}
if (memcmp(&previous_status.depth_config,
&final_status->depth_config,
sizeof(firmware_component_status_t)) != 0)
{
LOG_INFO("Depth Config: A:%d V:%d T:%d E:%d W:%d O:%d",
final_status->depth_config.authentication_check,
final_status->depth_config.version_check,
final_status->depth_config.image_transfer,
final_status->depth_config.flash_erase,
final_status->depth_config.flash_write,
final_status->depth_config.overall);
}
if (memcmp(&previous_status.depth, &final_status->depth, sizeof(firmware_component_status_t)) != 0)
{
LOG_INFO("Depth: A:%d V:%d T:%d E:%d W:%d O:%d",
final_status->depth.authentication_check,
final_status->depth.version_check,
final_status->depth.image_transfer,
final_status->depth.flash_erase,
final_status->depth.flash_write,
final_status->depth.overall);
}
if (memcmp(&previous_status.rgb, &final_status->rgb, sizeof(firmware_component_status_t)) != 0)
{
LOG_INFO("RGB: A:%d V:%d T:%d E:%d W:%d O:%d",
final_status->rgb.authentication_check,
final_status->rgb.version_check,
final_status->rgb.image_transfer,
final_status->rgb.flash_erase,
final_status->rgb.flash_write,
final_status->rgb.overall);
}
previous_status = *final_status;
}
all_complete = ((final_status->audio.overall > FIRMWARE_OPERATION_INPROGRESS) &&
(final_status->depth_config.overall > FIRMWARE_OPERATION_INPROGRESS) &&
(final_status->depth.overall > FIRMWARE_OPERATION_INPROGRESS) &&
(final_status->rgb.overall > FIRMWARE_OPERATION_INPROGRESS));
// Check to see if now is the correct time to interrupt the device.
switch (component)
{
case FIRMWARE_OPERATION_START:
// As early as possible reset the device.
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
case FIRMWARE_OPERATION_AUDIO_ERASE:
if (final_status->audio.image_transfer == FIRMWARE_OPERATION_SUCCEEDED)
{
// The erase takes places after the transfer is complete and takes about 7.8 seconds.
int sleepTime = (int)((rand() / (float)RAND_MAX) * 7600);
sleepTime = 3800;
LOG_INFO("Audio Erase started, waiting %dms.", sleepTime);
ThreadAPI_Sleep(sleepTime);
TRACE_CALL(firmware_get_download_status(*firmware_handle, final_status));
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
}
break;
case FIRMWARE_OPERATION_AUDIO_WRITE:
if (final_status->audio.flash_erase == FIRMWARE_OPERATION_SUCCEEDED)
{
// The write takes places after the erase is complete and takes about 20 seconds.
int sleepTime = (int)((rand() / (float)RAND_MAX) * 19700);
sleepTime = 9850;
LOG_INFO("Audio Write started, waiting %dms.", sleepTime);
ThreadAPI_Sleep(sleepTime);
TRACE_CALL(firmware_get_download_status(*firmware_handle, final_status));
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
}
break;
case FIRMWARE_OPERATION_DEPTH_ERASE:
if (final_status->depth.image_transfer == FIRMWARE_OPERATION_SUCCEEDED)
{
// The erase takes places after the transfer is complete and takes about 0.25 seconds.
int sleepTime = (int)((rand() / (float)RAND_MAX) * 100);
sleepTime = 50;
LOG_INFO("Depth Erase started, waiting %dms.", sleepTime);
ThreadAPI_Sleep(sleepTime);
TRACE_CALL(firmware_get_download_status(*firmware_handle, final_status));
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
}
break;
case FIRMWARE_OPERATION_DEPTH_WRITE:
if (final_status->depth.flash_erase == FIRMWARE_OPERATION_SUCCEEDED)
{
// The write takes places after the transfer is complete and takes about 5.8 seconds.
int sleepTime = (int)((rand() / (float)RAND_MAX) * 5700);
sleepTime = 2850;
LOG_INFO("Depth Write started, waiting %dms.", sleepTime);
ThreadAPI_Sleep(sleepTime);
TRACE_CALL(firmware_get_download_status(*firmware_handle, final_status));
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
}
break;
case FIRMWARE_OPERATION_RGB_ERASE:
if (final_status->rgb.image_transfer == FIRMWARE_OPERATION_SUCCEEDED)
{
// The erase takes places after the transfer is complete and takes about 0.05 seconds.
LOG_INFO("RGB erase started...");
TRACE_CALL(firmware_get_download_status(*firmware_handle, final_status));
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
}
break;
case FIRMWARE_OPERATION_RGB_WRITE:
if (final_status->rgb.flash_erase == FIRMWARE_OPERATION_SUCCEEDED)
{
// The write takes places after the transfer is complete and takes about 6.1 seconds.
int sleepTime = (int)((rand() / (float)RAND_MAX) * 6000);
sleepTime = 3000;
LOG_INFO("RGB Write started, waiting %dms.", sleepTime);
ThreadAPI_Sleep(sleepTime);
TRACE_CALL(firmware_get_download_status(*firmware_handle, final_status));
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
}
break;
default:
break;
}
}
else
{
// Failed to get the status of the update operation. Attempt to reset the device and return.
LOG_ERROR("Failed to get the firmware update status.");
TRACE_CALL(interrupt_operation(firmware_handle, interruption));
return K4A_RESULT_FAILED;
}
K4A_TEST_VERIFY_EQUAL(0, tickcounter_get_current_ms(tick, &now));
if (!all_complete && (now - start_time_ms > UPDATE_TIMEOUT_MS))
{
// The update hasn't completed and too much time as passed. Attempt to reset the device and return.
LOG_ERROR("Timeout waiting for the update to complete.");
TRACE_CALL(interrupt_operation(firmware_handle, interruption));
return K4A_RESULT_FAILED;
}
if (!all_complete)
{
ThreadAPI_Sleep(UPDATE_POLL_INTERVAL_MS);
}
} while (!all_complete);
// At this point the update has completed, the device needs to be reset after the
// update has progressed.
return TRACE_CALL(interrupt_operation(firmware_handle, interruption));
}
k4a_result_t perform_device_update(firmware_t *firmware_handle,
uint8_t *firmware_buffer,
size_t firmware_size,
firmware_package_info_t firmware_package_info,
bool verbose_logging)
{
firmware_status_summary_t finalStatus;
k4a_hardware_version_t current_version;
K4A_TEST_VERIFY_SUCCEEDED(firmware_get_device_version(*firmware_handle, &current_version));
log_device_version(current_version);
log_firmware_version(firmware_package_info);
// Perform upgrade...
K4A_TEST_VERIFY_SUCCEEDED(firmware_download(*firmware_handle, firmware_buffer, firmware_size));
interrupt_device_at_update_stage(firmware_handle,
FIRMWARE_OPERATION_FULL_DEVICE,
FIRMWARE_INTERRUPTION_RESET,
&finalStatus,
verbose_logging);
K4A_TEST_VERIFY_EQUAL(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.audio));
K4A_TEST_VERIFY_EQUAL(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth_config));
K4A_TEST_VERIFY_EQUAL(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth));
K4A_TEST_VERIFY_EQUAL(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.rgb));
// Check upgrade...
K4A_TEST_VERIFY_SUCCEEDED(firmware_get_device_version(*firmware_handle, &current_version));
printf("Post full update ");
log_device_version(current_version);
K4A_TEST_VERIFY_TRUE(compare_version(current_version, firmware_package_info));
return K4A_RESULT_SUCCEEDED;
}
int main(int argc, char **argv)
{
bool error = false;
srand((unsigned int)time(0)); // use current time as seed for random generator
k4a_unittest_init();
::testing::InitGoogleTest(&argc, argv);
for (int i = 1; i < argc; ++i)
{
char *argument = argv[i];
for (int j = 0; argument[j]; j++)
{
argument[j] = (char)tolower(argument[j]);
}
if (strcmp(argument, "--firmware") == 0)
{
if (i + 1 <= argc)
{
g_candidate_firmware_path = argv[++i];
printf("Setting g_test_firmware_path = %s\n", g_candidate_firmware_path);
}
else
{
printf("Error: firmware path parameter missing\n");
error = true;
}
}
if ((strcmp(argument, "-h") == 0) || (strcmp(argument, "/h") == 0) || (strcmp(argument, "-?") == 0) ||
(strcmp(argument, "/?") == 0))
{
error = true;
}
}
if (error)
{
printf("\n\nCustom Test Settings:\n");
printf(" --firmware <firmware path>\n");
printf(" This is the path to the candidate firmware that should be tested.\n");
return 1; // Indicates an error or warning
}
int result = RUN_ALL_TESTS();
tear_down_common_test();
return result;
}

Просмотреть файл

@ -0,0 +1,92 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef FIRMWARE_HELPER_H
#define FIRMWARE_HELPER_H
#include <k4a/k4atypes.h>
#include <k4ainternal/firmware.h>
#include <ConnEx.h>
#define UPDATE_TIMEOUT_MS 10 * 60 * 1000 // 10 Minutes should be way more than enough.
#define UPDATE_POLL_INTERVAL_MS 5
// This will define the path to the firmware packages to use in testing the firmware update process. The firmware update
// is executed by the firmware that is currently on the device. In order to test the firmware update process for a
// candidate, the device must be on the candidate firmware and then updated to a different test firmware where all of
// the versions are different.
// Factory firmware - This should be the oldest available firmware that we can roll back to.
// LKG firmware - This should be the last firmware that was released.
// Test firmware - This should be a firmware where all components have different versions than the candidate firmware.
// Candidate firmware - This should be the firmware that is being validated. It will be passed in via command line
// parameter.
#define K4A_FACTORY_FIRMWARE_PATH "D:\\Shares\\Eden\\Public\\AzureKinectDK_Fw_1.5.786013.bin"
#define K4A_LKG_FIRMWARE_PATH "D:\\Shares\\Eden\\Public\\AzureKinectDK_Fw_1.5.886314.bin"
#define K4A_TEST_FIRMWARE_PATH "D:\\Shares\\Eden\\Public\\AzureKinectDK_Fw_1.5.786013.bin"
typedef enum
{
FIRMWARE_OPERATION_START,
FIRMWARE_OPERATION_AUDIO_ERASE,
FIRMWARE_OPERATION_AUDIO_WRITE,
FIRMWARE_OPERATION_DEPTH_ERASE,
FIRMWARE_OPERATION_DEPTH_WRITE,
FIRMWARE_OPERATION_RGB_ERASE,
FIRMWARE_OPERATION_RGB_WRITE,
FIRMWARE_OPERATION_FULL_DEVICE,
} firmware_operation_component_t;
typedef enum
{
FIRMWARE_INTERRUPTION_RESET,
FIRMWARE_INTERRUPTION_DISCONNECT,
} firmware_operation_interruption_t;
extern int g_k4a_port_number;
extern connection_exerciser *g_connection_exerciser;
extern uint8_t *g_test_firmware_buffer;
extern size_t g_test_firmware_size;
extern firmware_package_info_t g_test_firmware_package_info;
extern uint8_t *g_candidate_firmware_buffer;
extern size_t g_candidate_firmware_size;
extern firmware_package_info_t g_candidate_firmware_package_info;
extern uint8_t *g_lkg_firmware_buffer;
extern size_t g_lkg_firmware_size;
extern firmware_package_info_t g_lkg_firmware_package_info;
extern uint8_t *g_factory_firmware_buffer;
extern size_t g_factory_firmware_size;
extern firmware_package_info_t g_factory_firmware_package_info;
k4a_result_t setup_common_test();
k4a_result_t load_firmware_files(char *firmware_path, uint8_t **firmware_buffer, size_t *firmware_size);
firmware_operation_status_t calculate_overall_component_status(const firmware_component_status_t status);
bool compare_version(k4a_version_t left_version, k4a_version_t right_version);
bool compare_version_list(k4a_version_t device_version, uint8_t count, k4a_version_t versions[5]);
bool compare_device_serial_number(firmware_t firmware_handle, char *device_serial_number);
void log_firmware_build_config(k4a_firmware_build_t build_config);
void log_firmware_signature_type(k4a_firmware_signature_t signature_type, bool certificate);
void log_firmware_version(firmware_package_info_t firmware_version);
void log_device_version(k4a_hardware_version_t firmware_version);
k4a_result_t open_firmware_device(firmware_t *firmware_handle);
k4a_result_t reset_device(firmware_t *firmware_handle);
k4a_result_t interrupt_operation(firmware_t *firmware_handle, firmware_operation_interruption_t interruption);
k4a_result_t interrupt_device_at_update_stage(firmware_t *firmware_handle,
firmware_operation_component_t component,
firmware_operation_interruption_t interruption,
firmware_status_summary_t *final_status,
bool verbose_logging);
k4a_result_t perform_device_update(firmware_t *firmware_handle,
uint8_t *firmware_buffer,
size_t firmware_size,
firmware_package_info_t firmware_package_info,
bool verbose_logging);
#endif /* FIRMWARE_HELPER_H */

Просмотреть файл

@ -0,0 +1,264 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#define _CRT_NONSTDC_NO_DEPRECATE
#include "firmware_helper.h"
#include <gtest/gtest.h>
#include <utcommon.h>
#include <k4ainternal/logging.h>
#include <azure_c_shared_utility/tickcounter.h>
#include <azure_c_shared_utility/threadapi.h>
struct firmware_interrupt_parameters
{
int test_number;
const char *test_name;
firmware_operation_component_t component;
firmware_operation_interruption_t interruption;
friend std::ostream &operator<<(std::ostream &os, const firmware_interrupt_parameters &obj)
{
return os << "test " << (int)obj.test_number << ": " << obj.test_name;
}
};
class firmware_interrupt_fw : public ::testing::Test,
public ::testing::WithParamInterface<firmware_interrupt_parameters>
{
protected:
void SetUp() override
{
ASSERT_EQ(K4A_RESULT_SUCCEEDED, TRACE_CALL(setup_common_test()));
const ::testing::TestInfo *const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
LOG_INFO("Test %s requires a connection exerciser.", test_info->name());
LOG_INFO("Disconnecting the device", 0);
g_connection_exerciser->set_usb_port(0);
ThreadAPI_Sleep(500);
// Make sure that all of the firmwares have loaded correctly.
ASSERT_TRUE(g_test_firmware_buffer != nullptr);
ASSERT_TRUE(g_test_firmware_size > 0);
ASSERT_TRUE(g_candidate_firmware_buffer != nullptr);
ASSERT_TRUE(g_candidate_firmware_size > 0);
ASSERT_TRUE(g_lkg_firmware_buffer != nullptr);
ASSERT_TRUE(g_lkg_firmware_size > 0);
// Make sure that the Test firmware has all components with a different version when compared to the Release
// Candidate firmware.
// Depth Sensor isn't expect to change.
ASSERT_FALSE(compare_version(g_test_firmware_package_info.audio, g_candidate_firmware_package_info.audio));
ASSERT_FALSE(compare_version(g_test_firmware_package_info.depth, g_candidate_firmware_package_info.depth));
ASSERT_FALSE(compare_version(g_test_firmware_package_info.rgb, g_candidate_firmware_package_info.rgb));
// There should be no other devices.
uint32_t device_count = 0;
usb_cmd_get_device_count(&device_count);
ASSERT_EQ((uint32_t)0, device_count);
}
void TearDown() override
{
if (firmware_handle != nullptr)
{
firmware_destroy(firmware_handle);
firmware_handle = nullptr;
}
if (serial_number != nullptr)
{
free(serial_number);
serial_number = nullptr;
serial_number_length = 0;
}
}
firmware_t firmware_handle = nullptr;
char *serial_number = nullptr;
size_t serial_number_length = 0;
k4a_hardware_version_t current_version = { 0 };
};
TEST_P(firmware_interrupt_fw, interrupt_update)
{
firmware_interrupt_parameters parameters = GetParam();
firmware_status_summary_t finalStatus;
LOG_INFO("Beginning the \'%s\' test. Stage: %d Interruption: %d",
parameters.test_name,
parameters.component,
parameters.interruption);
LOG_INFO("Powering on the device...", 0);
ASSERT_EQ(K4A_RESULT_SUCCEEDED, g_connection_exerciser->set_usb_port(g_k4a_port_number));
ASSERT_EQ(K4A_RESULT_SUCCEEDED, open_firmware_device(&firmware_handle));
ASSERT_EQ(K4A_BUFFER_RESULT_TOO_SMALL, firmware_get_device_serialnum(firmware_handle, NULL, &serial_number_length));
serial_number = (char *)malloc(serial_number_length);
ASSERT_NE(nullptr, serial_number);
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
firmware_get_device_serialnum(firmware_handle, serial_number, &serial_number_length));
// Update to the Candidate firmware
LOG_INFO("Updating the device to the Candidate firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_candidate_firmware_buffer,
g_candidate_firmware_size,
g_candidate_firmware_package_info,
false));
// Update to the Test firmware, but interrupt...
LOG_INFO("Beginning of the firmware update to the Test Firmware with interruption...");
// Prepend the "Firmware Package Versions:\n" with "Test".
printf("Test ");
log_firmware_version(g_test_firmware_package_info);
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_download(firmware_handle, g_test_firmware_buffer, g_test_firmware_size));
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
interrupt_device_at_update_stage(&firmware_handle,
parameters.component,
parameters.interruption,
&finalStatus,
false));
std::cout << "Updated completed with Audio: " << calculate_overall_component_status(finalStatus.audio)
<< " Depth Config: " << calculate_overall_component_status(finalStatus.depth_config)
<< " Depth: " << calculate_overall_component_status(finalStatus.depth)
<< " RGB: " << calculate_overall_component_status(finalStatus.rgb) << std::endl;
// Check that we are still on the version we expect
ASSERT_EQ(K4A_RESULT_SUCCEEDED, firmware_get_device_version(firmware_handle, &current_version));
log_device_version(current_version);
ASSERT_TRUE(compare_version_list(current_version.depth_sensor,
g_candidate_firmware_package_info.depth_config_number_versions,
g_candidate_firmware_package_info.depth_config_versions))
<< "Depth sensor does not exist in package.";
switch (parameters.component)
{
case FIRMWARE_OPERATION_START:
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.audio));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.depth_config));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.depth));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.rgb));
ASSERT_TRUE(compare_version(current_version.audio, g_candidate_firmware_package_info.audio))
<< "Audio version mismatch";
ASSERT_TRUE(compare_version(current_version.depth, g_candidate_firmware_package_info.depth))
<< "Depth mismatch";
ASSERT_TRUE(compare_version(current_version.rgb, g_candidate_firmware_package_info.rgb)) << "RGB mismatch";
break;
case FIRMWARE_OPERATION_AUDIO_ERASE:
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.audio));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.depth_config));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.depth));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.rgb));
ASSERT_TRUE(compare_version(current_version.audio, { 0 })) << "Audio version mismatch";
ASSERT_TRUE(compare_version(current_version.depth, g_candidate_firmware_package_info.depth))
<< "Depth mismatch";
ASSERT_TRUE(compare_version(current_version.rgb, g_candidate_firmware_package_info.rgb)) << "RGB mismatch";
break;
case FIRMWARE_OPERATION_AUDIO_WRITE:
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.audio));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.depth_config));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.depth));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.rgb));
ASSERT_TRUE(compare_version(current_version.audio, g_test_firmware_package_info.audio))
<< "Audio version mismatch";
ASSERT_TRUE(compare_version(current_version.depth, g_candidate_firmware_package_info.depth))
<< "Depth mismatch";
ASSERT_TRUE(compare_version(current_version.rgb, g_candidate_firmware_package_info.rgb)) << "RGB mismatch";
break;
case FIRMWARE_OPERATION_DEPTH_ERASE:
case FIRMWARE_OPERATION_DEPTH_WRITE:
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.audio));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth_config));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.depth));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.rgb));
ASSERT_TRUE(compare_version(current_version.audio, g_test_firmware_package_info.audio))
<< "Audio version mismatch";
ASSERT_TRUE(compare_version(current_version.rgb, g_candidate_firmware_package_info.rgb)) << "RGB mismatch";
// Don't fail on the Depth version as it appears to be non-deterministic based on when the reset actually
// happened.
if (!compare_version(current_version.depth, { 0 }))
{
printf(" The Depth version was not expected\n");
}
break;
case FIRMWARE_OPERATION_RGB_ERASE:
case FIRMWARE_OPERATION_RGB_WRITE:
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.audio));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth_config));
ASSERT_EQ(FIRMWARE_OPERATION_SUCCEEDED, calculate_overall_component_status(finalStatus.depth));
ASSERT_EQ(FIRMWARE_OPERATION_INPROGRESS, calculate_overall_component_status(finalStatus.rgb));
// Don't fail on the Audio, Depth, and RGB versions as they appear to be non-deterministic based on when the
// reset actually happened.
if (!compare_version(current_version.audio, g_test_firmware_package_info.audio))
{
printf(" The Audio version was not expected\n");
}
if (!compare_version(current_version.depth, g_test_firmware_package_info.depth))
{
printf(" The Depth version was not expected\n");
}
if (!compare_version(current_version.rgb, { 0 }))
{
printf(" The RGB version was not expected\n");
}
break;
default:
ASSERT_TRUE(false) << "Unhandled component type. " << parameters.component;
}
// Update back to the LKG firmware to make sure that works.
LOG_INFO("Updating the device back to the LKG firmware.");
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
perform_device_update(&firmware_handle,
g_lkg_firmware_buffer,
g_lkg_firmware_size,
g_lkg_firmware_package_info,
false));
ASSERT_TRUE(compare_device_serial_number(firmware_handle, serial_number));
}
static struct firmware_interrupt_parameters tests_interrupt_reboot[] = {
{ 0, "Reset device at update start", FIRMWARE_OPERATION_START, FIRMWARE_INTERRUPTION_RESET },
{ 1, "Reset device during Audio erase", FIRMWARE_OPERATION_AUDIO_ERASE, FIRMWARE_INTERRUPTION_RESET },
{ 2, "Reset device during Audio write", FIRMWARE_OPERATION_AUDIO_WRITE, FIRMWARE_INTERRUPTION_RESET },
{ 3, "Reset device during Depth erase", FIRMWARE_OPERATION_DEPTH_ERASE, FIRMWARE_INTERRUPTION_RESET },
{ 4, "Reset device during Depth write", FIRMWARE_OPERATION_DEPTH_WRITE, FIRMWARE_INTERRUPTION_RESET },
{ 5, "Reset device during RGB erase", FIRMWARE_OPERATION_RGB_ERASE, FIRMWARE_INTERRUPTION_RESET },
{ 6, "Reset device during RGB write", FIRMWARE_OPERATION_RGB_WRITE, FIRMWARE_INTERRUPTION_RESET },
};
INSTANTIATE_TEST_CASE_P(interrupt_reboot, firmware_interrupt_fw, ::testing::ValuesIn(tests_interrupt_reboot));
static struct firmware_interrupt_parameters tests_interrupt_disconnect[] = {
{ 0, "Disconnect device at update start", FIRMWARE_OPERATION_START, FIRMWARE_INTERRUPTION_DISCONNECT },
{ 1, "Disconnect device during Audio erase", FIRMWARE_OPERATION_AUDIO_ERASE, FIRMWARE_INTERRUPTION_DISCONNECT },
{ 2, "Disconnect device during Audio write", FIRMWARE_OPERATION_AUDIO_WRITE, FIRMWARE_INTERRUPTION_DISCONNECT },
{ 3, "Disconnect device during Depth erase", FIRMWARE_OPERATION_DEPTH_ERASE, FIRMWARE_INTERRUPTION_DISCONNECT },
{ 4, "Disconnect device during Depth write", FIRMWARE_OPERATION_DEPTH_WRITE, FIRMWARE_INTERRUPTION_DISCONNECT },
{ 5, "Disconnect device during RGB erase", FIRMWARE_OPERATION_RGB_ERASE, FIRMWARE_INTERRUPTION_DISCONNECT },
{ 6, "Disconnect device during RGB write", FIRMWARE_OPERATION_RGB_WRITE, FIRMWARE_INTERRUPTION_DISCONNECT },
};
INSTANTIATE_TEST_CASE_P(interrupt_disconnect, firmware_interrupt_fw, ::testing::ValuesIn(tests_interrupt_disconnect));

Просмотреть файл

@ -254,7 +254,7 @@ k4a_result_t connection_exerciser::find_connection_exerciser()
for (int i = 1; i < 10; ++i)
{
sprintf_s(comPort, "COM%d", i);
LOG_ERROR("Opening %s", comPort);
LOG_INFO("Opening %s", comPort);
state->serialHandle = OpenComPort(comPort);
if (state->serialHandle != INVALID_HANDLE_VALUE)

Просмотреть файл

@ -1,6 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef CONNECTION_EXERCISER_H
#define CONNECTION_EXERCISER_H
#include <k4a/k4atypes.h>
// The connection exerciser has 4 active ports plus a everything disconnected "port".
@ -35,3 +38,5 @@ private:
pconnection_exerciser_internal_t state;
};
#endif /* CONNECTION_EXERCISER_H */