* [IE Myriad] Added XLinkBootFirmware method in XLink API for booting firmware buffer
* [IE Myriad] Patch firmware in mvnc. Added test to check device reset without connecting.
* [IE Myriad] Added option MOVIDIUS_DDR_TYPE for Myriad plugin
* [IE Myriad] Added tests for new option MOVIDIUS_DDR_TYPE
* [IE Myriad] Update firmware 1201 -> 1212
* [IE Myriad] Convolution3x3 tests are disabled due to firmware issue. #-32921
# Default packages
#
-set(FIRMWARE_PACKAGE_VERSION 1201)
+set(FIRMWARE_PACKAGE_VERSION 1212)
set(VPU_CLC_MA2X8X_VERSION "movi-cltools-20.02.0")
#
DECLARE_VPU_MYRIAD_CONFIG_VALUE(2450);
DECLARE_VPU_MYRIAD_CONFIG_VALUE(2480);
+/**
+ * @brief This option allows to specify device memory type.
+ */
+DECLARE_VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE);
+
+/**
+ * @brief Supported keys definition for VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE) option.
+ */
+DECLARE_VPU_MYRIAD_CONFIG_VALUE(DDR_AUTO);
+DECLARE_VPU_MYRIAD_CONFIG_VALUE(MICRON_2GB);
+DECLARE_VPU_MYRIAD_CONFIG_VALUE(SAMSUNG_2GB);
+DECLARE_VPU_MYRIAD_CONFIG_VALUE(HYNIX_2GB);
+DECLARE_VPU_MYRIAD_CONFIG_VALUE(MICRON_1GB);
+
} // namespace VPUConfigParams
} // namespace InferenceEngine
VPU_MYRIAD_CONFIG_KEY(PLUGIN_LOG_FILE_PATH),
VPU_MYRIAD_CONFIG_KEY(DEVICE_CONNECT_TIMEOUT),
+
+ VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE),
});
IE_SUPPRESS_DEPRECATED_END
{ VPU_MYRIAD_CONFIG_VALUE(POWER_STAGE_NCES), PowerConfig::STAGE_NCES },
};
+ static const std::unordered_map<std::string, MovidiusDdrType> memoryTypes = {
+ { VPU_MYRIAD_CONFIG_VALUE(DDR_AUTO), MovidiusDdrType::AUTO },
+ { VPU_MYRIAD_CONFIG_VALUE(MICRON_2GB), MovidiusDdrType::MICRON_2GB },
+ { VPU_MYRIAD_CONFIG_VALUE(SAMSUNG_2GB), MovidiusDdrType::SAMSUNG_2GB },
+ { VPU_MYRIAD_CONFIG_VALUE(HYNIX_2GB), MovidiusDdrType::HYNIX_2GB },
+ { VPU_MYRIAD_CONFIG_VALUE(MICRON_1GB), MovidiusDdrType::MICRON_1GB }
+ };
+
ParsedConfig::parse(config);
setOption(_pluginLogFilePath, config, VPU_MYRIAD_CONFIG_KEY(PLUGIN_LOG_FILE_PATH));
setOption(_watchdogInterval, watchdogIntervals, config, VPU_MYRIAD_CONFIG_KEY(WATCHDOG));
setOption(_deviceConnectTimeout, config, VPU_MYRIAD_CONFIG_KEY(DEVICE_CONNECT_TIMEOUT), parseSeconds);
setOption(_powerConfig, powerConfigs, config, VPU_MYRIAD_CONFIG_KEY(POWER_MANAGEMENT));
+ setOption(_memoryType, memoryTypes, config, VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE));
IE_SUPPRESS_DEPRECATED_START
setOption(_forceReset, switches, config, VPU_CONFIG_KEY(FORCE_RESET));
STAGE_NCES = 4,
)
+// Must be synchronized with firmware side.
+VPU_DECLARE_ENUM(MovidiusDdrType,
+ AUTO = 0,
+ MICRON_2GB = 1,
+ SAMSUNG_2GB = 2,
+ HYNIX_2GB = 3,
+ MICRON_1GB = 4,
+)
+
class MyriadConfig final : public ParsedConfig {
public:
const std::string& pluginLogFilePath() const {
return _deviceName;
}
+ MovidiusDdrType memoryType() const {
+ return _memoryType;
+ }
+
protected:
const std::unordered_set<std::string>& getCompileOptions() const override;
const std::unordered_set<std::string>& getRunTimeOptions() const override;
std::chrono::milliseconds _watchdogInterval = std::chrono::milliseconds(1000);
std::chrono::seconds _deviceConnectTimeout = std::chrono::seconds(15);
std::string _deviceName;
+ MovidiusDdrType _memoryType = MovidiusDdrType::AUTO;
};
} // namespace MyriadPlugin
ncDeviceOpenParams_t deviceOpenParams = {};
deviceOpenParams.watchdogHndl = _mvnc->watchdogHndl();
deviceOpenParams.watchdogInterval = config.watchdogInterval().count();
+ deviceOpenParams.memoryType = checked_cast<char>(config.memoryType());
deviceOpenParams.customFirmwareDirectory = dirName.c_str();
// Open new device with specific path to FW folder
{MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, "MYRIAD"},
{VPU_CONFIG_KEY(HW_STAGES_OPTIMIZATION), CONFIG_VALUE(YES)}
}),
+
+ // Please do not use other types of DDR in tests with a real device, because it may hang.
+ BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), VPU_MYRIAD_CONFIG_VALUE(DDR_AUTO)}}),
};
const std::vector<BehTestParams> withCorrectConfValuesPluginOnly = {
{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "0"}}),
BEH_MULTI_CONFIG.withConfig({{MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, "MYRIAD"},
{VPU_MYRIAD_CONFIG_KEY(PLATFORM), "1"}}),
+
+ BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "-1"}}),
+ BEH_MYRIAD.withConfig({{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "MICRON"}}),
};
const BehTestParams withIncorrectConfKeys[] = {
}
}
-TEST_P(myriadConvolution3x3LayerTests_smoke, Convolution3x3) {
+TEST_P(myriadConvolution3x3LayerTests_smoke, DISABLED_Convolution3x3) {
std::string model = R"V0G0N(
<net name="Convolution3x3" version="2" batch="1">
<layers>
TEST_P(myriadIncorrectModelsConfigsTests_nightly, LoadNetworkWithIncorrectConfig) {
InferenceEngine::ResponseDesc response;
const auto &config = GetParam();
- DISABLE_IF(hasAppropriateStick(config));
InferenceEngine::CNNNetwork net(ngraph::builder::subgraph::makeSplitConvConcat());
InferenceEngine::IExecutableNetwork::Ptr executable;
// Current key & deprecated value
{{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_CONFIG_VALUE(2450)}},
{{VPU_MYRIAD_CONFIG_KEY(PLATFORM), VPU_CONFIG_VALUE(2480)}},
+};
+static const std::vector<config_t> myriadCorrectPackageTypeConfigValues = {
+ // Please do not use other types of DDR in tests with a real device, because it may hang.
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), VPU_MYRIAD_CONFIG_VALUE(DDR_AUTO)}}
};
-INSTANTIATE_TEST_CASE_P(MyriadConfigs, myriadCorrectModelsConfigsTests_nightly, ::testing::ValuesIn(myriadCorrectPlatformConfigValues));
+static const std::vector<config_t> myriadIncorrectPackageTypeConfigValues = {
+
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "-1"}},
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "-MICRON_1GB"}},
+};
+
+INSTANTIATE_TEST_CASE_P(MyriadConfigs, myriadCorrectModelsConfigsTests_nightly,
+ ::testing::ValuesIn(myriadCorrectPlatformConfigValues));
+
+INSTANTIATE_TEST_CASE_P(MyriadConfigs, myriadIncorrectModelsConfigsTests_nightly,
+ ::testing::ValuesIn(myriadIncorrectPlatformConfigValues));
+
+INSTANTIATE_TEST_CASE_P(MyriadPackageConfigs, myriadCorrectModelsConfigsTests_nightly,
+ ::testing::ValuesIn(myriadCorrectPackageTypeConfigValues));
-INSTANTIATE_TEST_CASE_P(MyriadConfigs, myriadIncorrectModelsConfigsTests_nightly, ::testing::ValuesIn(myriadIncorrectPlatformConfigValues));
+INSTANTIATE_TEST_CASE_P(MyriadPackageConfigs, myriadIncorrectModelsConfigsTests_nightly,
+ ::testing::ValuesIn(myriadIncorrectPackageTypeConfigValues));
{{VPU_MYRIAD_CONFIG_KEY(POWER_MANAGEMENT), VPU_MYRIAD_CONFIG_VALUE(POWER_STAGE_NCES)}},
};
+static const std::vector<config_t> myriadCorrectPackageTypeConfigValues = {
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), VPU_MYRIAD_CONFIG_VALUE(DDR_AUTO)}},
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), VPU_MYRIAD_CONFIG_VALUE(MICRON_2GB)}},
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), VPU_MYRIAD_CONFIG_VALUE(SAMSUNG_2GB)}},
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), VPU_MYRIAD_CONFIG_VALUE(HYNIX_2GB)}},
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), VPU_MYRIAD_CONFIG_VALUE(MICRON_1GB)}}
+};
+
+static const std::vector<config_t> myriadIncorrectPackageTypeConfigValues = {
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "-1"}},
+ {{VPU_MYRIAD_CONFIG_KEY(MOVIDIUS_DDR_TYPE), "-MICRON_1GB"}},
+};
+
IE_SUPPRESS_DEPRECATED_END
/// Platform
::testing::ValuesIn(myriadCorrectPowerConfigValues));
INSTANTIATE_TEST_CASE_P(MyriadPowerConfigs, MyriadEngineSetIncorrectConfigTest,
- ::testing::ValuesIn(myriadIncorrectPowerConfigValues));
\ No newline at end of file
+ ::testing::ValuesIn(myriadIncorrectPowerConfigValues));
+/// Package Config
+INSTANTIATE_TEST_CASE_P(MyriadPackageConfigs, MyriadEngineSetCorrectConfigTest,
+ ::testing::ValuesIn(myriadCorrectPackageTypeConfigValues));
+
+INSTANTIATE_TEST_CASE_P(MyriadPackageConfigs, MyriadEngineSetIncorrectConfigTest,
+ ::testing::ValuesIn(myriadIncorrectPackageTypeConfigValues));
int XLinkPlatformBootRemote(deviceDesc_t* deviceDesc, const char* binaryPath)
{
- int rc = 0;
FILE *file;
long file_size;
- void *image_buffer;
+ char *image_buffer;
/* Open the mvcmd file */
file = fopen(binaryPath, "rb");
}
fclose(file);
+ if(XLinkPlatformBootFirmware(deviceDesc, image_buffer, file_size)) {
+ free(image_buffer);
+ return -1;
+ }
+
+ free(image_buffer);
+ return 0;
+}
+
+int XLinkPlatformBootFirmware(deviceDesc_t* deviceDesc, const char* firmware, size_t length) {
if (deviceDesc->protocol == X_LINK_PCIE) {
// Temporary open fd to boot device and then close it
int* pcieFd = NULL;
- rc = pcie_init(deviceDesc->name, (void**)&pcieFd);
+ int rc = pcie_init(deviceDesc->name, (void**)&pcieFd);
if (rc) {
- free(image_buffer);
return rc;
}
#if (!defined(_WIN32) && !defined(_WIN64))
- rc = pcie_boot_device(*(int*)pcieFd, image_buffer, file_size);
+ rc = pcie_boot_device(*(int*)pcieFd, firmware, length);
#else
- rc = pcie_boot_device(pcieFd, image_buffer, file_size);
+ rc = pcie_boot_device(pcieFd, firmware, length);
#endif
- free(image_buffer);
-
pcie_close(pcieFd); // Will not check result for now
return rc;
} else if (deviceDesc->protocol == X_LINK_USB_VSC) {
printf("Path to your boot util is too long for the char array here!\n");
}
// Boot it
- rc = usb_boot(deviceDesc->name, image_buffer, file_size);
- free(image_buffer);
+ int rc = usb_boot(deviceDesc->name, firmware, length);
if(!rc) {
mvLog(MVLOG_DEBUG, "Boot successful, device address %s", deviceDesc->name);
}
return rc;
} else {
- printf("Selected protocol not supported\n");
- free(image_buffer);
return -1;
}
}
if (libusb_rc < 0)
{
if(last_open_dev_err[0])
- mvLog(MVLOG_ERROR, "Last opened device name: %s", last_open_dev_err);
+ mvLog(MVLOG_DEBUG, "Last opened device name: %s", last_open_dev_err);
usb_close_device(h);
usb_free_device(dev);
#endif
#if !defined(_WIN32)
-pcieHostError_t pcie_boot_device(int fd, void *buffer, size_t length)
+pcieHostError_t pcie_boot_device(int fd, const char *buffer, size_t length)
#else
-pcieHostError_t pcie_boot_device(HANDLE fd, void *buffer, size_t length)
+pcieHostError_t pcie_boot_device(HANDLE fd, const char *buffer, size_t length)
#endif
{
ASSERT_XLINK_PLATFORM_R(fd, PCIE_INVALID_PARAMETERS);
bResult = DeviceIoControl(fd, // device to be queried
MXLK_BOOT_DEV, // operation to perform
- buffer, length,
+ (void*)buffer, length,
&output_buffer, sizeof(output_buffer), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
pcieHostError_t pcie_close(void *fd);
#if (!defined(_WIN32))
-pcieHostError_t pcie_boot_device(int fd, void *buffer, size_t length);
+pcieHostError_t pcie_boot_device(int fd, const char *buffer, size_t length);
pcieHostError_t pcie_reset_device(int fd);
#else // Windows
-pcieHostError_t pcie_boot_device(HANDLE fd, void *buffer, size_t length);
+pcieHostError_t pcie_boot_device(HANDLE fd, const char *buffer, size_t length);
pcieHostError_t pcie_reset_device(HANDLE fd);
#endif
if (device) {
const char *dev_addr = gen_addr(dev, get_pid_by_name(input_addr));
if (!strcmp(dev_addr, input_addr)) {
+#if 0 // To avoid spam in Debug mode
mvLog(MVLOG_DEBUG, "Found Address: %s - VID/PID %04x:%04x",
input_addr, desc.idVendor, desc.idProduct);
+#endif
libusb_ref_device(dev);
libusb_free_device_list(devs, 1);
const char *dev_addr = gen_addr(dev, desc.idProduct);
// If the same add as input
if (!strcmp(dev_addr, input_addr)) {
+#if 0 // To avoid spam in Debug mode
mvLog(MVLOG_DEBUG, "Found Address: %s - VID/PID %04x:%04x",
input_addr, desc.idVendor, desc.idProduct);
+#endif
if (pthread_mutex_unlock(&globalMutex)) {
mvLog(MVLOG_ERROR, "globalMutex unlock failed");
}
} else if (idx == count) {
const char *caddr = gen_addr(dev, desc.idProduct);
+#if 0 // To avoid spam in Debug mode
mvLog(MVLOG_DEBUG, "Device %d Address: %s - VID/PID %04x:%04x",
idx, caddr, desc.idVendor, desc.idProduct);
+#endif
mv_strncpy(input_addr, addrsize, caddr, addrsize - 1);
if (pthread_mutex_unlock(&globalMutex)) {
mvLog(MVLOG_ERROR, "globalMutex unlock failed");
if(timeout != -1)
{
if(last_open_dev_err[0])
- mvLog(MVLOG_ERROR, "Last opened device name: %s", last_open_dev_err);
-
- mvLog(MVLOG_ERROR, "error: device not found!");
+ mvLog(MVLOG_DEBUG, "Last opened device name: %s", last_open_dev_err);
return rc ? USB_BOOT_DEVICE_NOT_FOUND : USB_BOOT_TIMEOUT;
} else if (elapsedTime > (double)timeout) {
*/
XLinkError_t XLinkBoot(deviceDesc_t* deviceDesc, const char* binaryPath);
+/**
+ * @brief Boots specified firmware binary to the remote device
+ * @param deviceDesc - device description structure, obtained from XLinkFind* functions call
+ * @param firmware - firmware buffer
+ * @param length - firmware buffer length
+ * @return Status code of the operation: X_LINK_SUCCESS (0) for success
+ */
+XLinkError_t XLinkBootFirmware(deviceDesc_t* deviceDesc, const char* firmware, unsigned long length);
+
/**
* @brief Resets the remote device and close all open local handles for this device
* @warning This function should be used in a host application
unsigned int *out_amountOfFoundDevices);
int XLinkPlatformBootRemote(deviceDesc_t* deviceDesc, const char* binaryPath);
+int XLinkPlatformBootFirmware(deviceDesc_t* deviceDesc, const char* firmware, size_t length);
int XLinkPlatformConnect(const char* devPathRead, const char* devPathWrite,
XLinkProtocol_t protocol, void** fd);
#endif // __PC__
linkId_t id = EXTRACT_LINK_ID(streamId);
*out_link = getLinkById(id);
- ASSERT_XLINK(*out_link != NULL);
+ XLINK_RET_ERR_IF(*out_link == NULL, X_LINK_ERROR);
XLINK_RET_ERR_IF(getXLinkState(*out_link) != XLINK_UP,
X_LINK_COMMUNICATION_NOT_OPEN);
return X_LINK_COMMUNICATION_FAIL;
}
+XLinkError_t XLinkBootFirmware(deviceDesc_t* deviceDesc, const char* firmware, unsigned long length) {
+ if (!XLinkPlatformBootFirmware(deviceDesc, firmware, length)) {
+ return X_LINK_SUCCESS;
+ }
+
+ return X_LINK_COMMUNICATION_FAIL;
+}
+
XLinkError_t XLinkResetRemote(linkId_t id)
{
xLinkDesc_t* link = getLinkById(id);
typedef struct ncDeviceOpenParams {
WatchdogHndl_t* watchdogHndl;
int watchdogInterval;
+ char memoryType;
const char* customFirmwareDirectory;
} ncDeviceOpenParams_t;
#include "mvnc.h"
#include "XLinkPlatform.h"
+#include "ncPrivateTypes.h"
#ifdef __cplusplus
extern "C"
{
int copyXLinkDeviceDescrToNc(
const deviceDesc_t *in_DeviceDesc, struct ncDeviceDescr_t *out_ncDeviceDesc);
+ncStatus_t bootDevice(deviceDesc_t* deviceDescToBoot,
+ const char* mv_cmd_file_path, const bootOptions_t bootOptions);
+
#ifdef __cplusplus
}
#endif
void* output_data;
};
+typedef struct {
+ char memType;
+ char wdEnable;
+} bootOptions_t;
#if (!defined(_WIN32) && !defined(_WIN64))
#define PACKED(name) struct __attribute__((packed)) name
return NC_INVALID_PARAMETERS;
}
+ bootOptions_t bootOptions = {0};
+ bootOptions.memType = deviceOpenParams.memoryType;
+ bootOptions.wdEnable = watchdogInterval > 0;
+
#ifdef NO_BOOT
XLinkDeviceState_t state = X_LINK_BOOTED;
if (watchdogInterval > 0) {
return NC_MVCMD_NOT_FOUND;
}
- rc = XLinkBoot(&deviceDescToBoot, mv_cmd_file_path);
- if (rc) {
+ sc = bootDevice(&deviceDescToBoot, mv_cmd_file_path, bootOptions);
+ if (sc) {
mvLog(MVLOG_WARN, "%s() XLinkBootRemote returned error %s for %s",
__func__, XLinkErrorToStr(rc), d->dev_addr);
free(handler);
XLinkFindAllSuitableDevices(X_LINK_ANY_STATE, deviceDesc, beforeBootDevices,
NC_MAX_DEVICES, &numberOfDevicesBeforeBoot);
- // Boot device
- rc = XLinkBoot(&deviceDescToBoot, mv_cmd_file_path);
- if (rc) {
+ sc = bootDevice(&deviceDescToBoot, mv_cmd_file_path, bootOptions);
+ if (sc) {
mvLog(MVLOG_WARN, "%s() XLinkBootRemote returned error %s for %s",
__func__, XLinkErrorToStr(rc), d->dev_addr);
} else {
d->device_mon_stream_id = deviceMonitorStreamId;
#if !(defined(NO_BOOT))
- wd_error_t wd_rc = xlink_device_create(&d->watchdog_device, d);
- if (wd_rc) {
- mvLog(MVLOG_WARN, "watchdog is not started for device %p", d->xlink);
+ if(bootOptions.wdEnable) {
+ wd_error_t wd_rc = xlink_device_create(&d->watchdog_device, d);
+ if (wd_rc) {
+ mvLog(MVLOG_ERROR, "failed to start watchdog for device %p", d->xlink);
+ } else {
+ watchdog_register_device(deviceOpenParams.watchdogHndl, d->watchdog_device);
+ }
} else {
- watchdog_register_device(deviceOpenParams.watchdogHndl, d->watchdog_device);
+ mvLog(MVLOG_WARN, "watchdog is not started for device %p", d->xlink);
}
#endif
return NC_OK;
}
-
ncStatus_t ncDeviceClose(struct ncDeviceHandle_t **deviceHandlePtr, WatchdogHndl_t* watchdogHndl) {
int found = 0;
XLinkError_t rc = X_LINK_SUCCESS;
* approved by Intel in writing.
*/
-#include <string.h>
#include "mvnc_data.h"
+#include "mvnc_tool.h"
+
#define MVLOG_UNIT_NAME ncTool
#include "XLinkLog.h"
#include "XLinkStringUtils.h"
-#include "mvnc_tool.h"
+#include "XLink.h"
+
+#include <string.h>
+#include <stdio.h>
XLinkProtocol_t convertProtocolToXlink(
const ncDeviceProtocol_t ncProtocol) {
mv_strncpy(out_ncDeviceDesc->name, XLINK_MAX_NAME_SIZE, in_DeviceDesc->name, XLINK_MAX_NAME_SIZE - 1);
return NC_OK;
-}
\ No newline at end of file
+}
+
+static ncStatus_t readFirmware(const char* binaryPath, char** out_firmware, size_t* out_length) {
+ CHECK_HANDLE_CORRECT(binaryPath);
+ CHECK_HANDLE_CORRECT(out_firmware);
+ CHECK_HANDLE_CORRECT(out_length);
+
+ *out_firmware = NULL;
+ *out_length = 0;
+ FILE* firmwareFile = fopen(binaryPath, "rb");
+
+ if(firmwareFile == NULL) {
+ mvLog(MVLOG_ERROR, "Fail to open file by path %s", binaryPath);
+ return NC_ERROR;
+ }
+
+ fseek(firmwareFile, 0, SEEK_END);
+ long fileSize = ftell(firmwareFile);
+ if(fileSize <= 0) {
+ mvLog(MVLOG_ERROR, "Fail to get file size or firmware is empty. fileSize = %ld", fileSize);
+ fclose(firmwareFile);
+ return NC_ERROR;
+ }
+ rewind(firmwareFile);
+
+ char* firmware = malloc(fileSize * sizeof(char));
+ if(firmware == NULL) {
+ mvLog(MVLOG_ERROR, "Fail to allocate memory for firmware");
+ fclose(firmwareFile);
+ return NC_ERROR;
+ }
+
+ size_t readCount = fread(firmware, sizeof(char), fileSize, firmwareFile);
+ if(readCount != fileSize)
+ {
+ mvLog(MVLOG_ERROR, "Fail to read firmware by path %s. readCount = %zu", binaryPath, readCount);
+ fclose(firmwareFile);
+ free(firmware);
+ return NC_ERROR;
+ }
+
+ fclose(firmwareFile);
+
+ *out_firmware = firmware;
+ *out_length = (size_t )fileSize;
+
+ return NC_OK;
+}
+
+static ncStatus_t patchFirmware(char **firmware, size_t *length, size_t commandLocationId,
+ const char command[], const size_t commandSize, const char value) {
+ CHECK_HANDLE_CORRECT(firmware);
+ CHECK_HANDLE_CORRECT(length);
+ CHECK_HANDLE_CORRECT(command);
+
+ char* currFirmware = *firmware;
+ size_t currLength = *length;
+
+ size_t patchedFirmwareLen = currLength + commandSize + 1;
+ char* patchedFirmware = malloc(patchedFirmwareLen);
+ if(patchedFirmware == NULL) {
+ mvLog(MVLOG_ERROR, "Fail to allocate memory for patched firmware");
+ return NC_ERROR;
+ }
+
+ memcpy(patchedFirmware, currFirmware, commandLocationId);
+
+ memcpy(patchedFirmware + commandLocationId,
+ command, commandSize);
+ memcpy(patchedFirmware + commandLocationId + commandSize,
+ &value, 1);
+
+ size_t currentPos = commandLocationId + commandSize + 1;
+ size_t tailSize = currLength - commandLocationId;
+ memcpy(patchedFirmware + currentPos,
+ currFirmware + commandLocationId, tailSize);
+
+ free(currFirmware);
+ *firmware = patchedFirmware;
+ *length = patchedFirmwareLen;
+
+ return NC_OK;
+}
+
+// 0x98 the write command for 8bit
+// {0x00, 0x00, 0x20, 0x80} == 0x80200000 the address of watchdog flag
+// 0x01 flag value
+const char g_setWdSwitchCommandMX[] = {0x98, 0x00, 0x00, 0x20, 0x80};
+const char g_executeCommand = 0xa4;
+
+static ncStatus_t patchSetWdSwitchCommand(char **firmware, size_t *length, const char wdEnable) {
+ CHECK_HANDLE_CORRECT(firmware);
+ CHECK_HANDLE_CORRECT(length);
+
+ char* currFirmware = *firmware;
+ size_t currLength = *length;
+ size_t executeCommandIdx = 0;
+ char executeCommandFound = 0;
+ size_t i = 0;
+
+ for (i = currLength - 1; i >= 0; i--) {
+ if(currFirmware[i] == g_executeCommand) {
+ executeCommandIdx = i;
+ executeCommandFound = 1;
+ break;
+ }
+ }
+
+ if(!executeCommandFound) {
+ mvLog(MVLOG_ERROR, "Fail to find execute command");
+ return NC_ERROR;
+ }
+
+ return patchFirmware(firmware, length, executeCommandIdx,
+ g_setWdSwitchCommandMX, sizeof(g_setWdSwitchCommandMX), wdEnable);
+}
+
+// 0x98 the write command for 8bit
+// {0x00, 0x0c, 0x20, 0x70} == 0x70200c00 the address of memory type for ddrInit application
+const char g_setMemTypeCommandMX[] = {0x98, 0x00, 0x0c, 0x20, 0x70};
+const char g_callCommand[] = {0xba, 0xf4, 0xe6, 0x21, 0x70};
+
+static ncStatus_t patchSetMemTypeCommand(char **firmware, size_t *length, const char memType) {
+ CHECK_HANDLE_CORRECT(firmware);
+ CHECK_HANDLE_CORRECT(length);
+
+ char* currFirmware = *firmware;
+ size_t currLength = *length;
+ size_t callCommandIdx = 0;
+ char callCommandFound = 0;
+ size_t i = 0;
+ size_t callCommandLen = sizeof(g_callCommand);
+
+ for (i = 0; i < currLength; i++) {
+ size_t j = 0;
+ for (j = 0; j < callCommandLen; j++) {
+ if(currFirmware[i + j] != g_callCommand[j]) {
+ break;
+ }
+ }
+
+ if(j == callCommandLen) {
+ callCommandIdx = i;
+ callCommandFound = 1;
+ }
+ }
+
+ if(!callCommandFound) {
+ mvLog(MVLOG_ERROR, "Fail to find call command");
+ return NC_ERROR;
+ }
+
+ return patchFirmware(firmware, length, callCommandIdx,
+ g_setMemTypeCommandMX, sizeof(g_setMemTypeCommandMX), memType);
+}
+
+ncStatus_t bootDevice(deviceDesc_t* deviceDescToBoot,
+ const char* mv_cmd_file_path, const bootOptions_t bootOptions) {
+
+ CHECK_HANDLE_CORRECT(deviceDescToBoot);
+
+ char* firmware = NULL;
+ size_t length = 0;
+ ncStatus_t sc = readFirmware(mv_cmd_file_path, &firmware, &length);
+ if(sc) {
+ mvLog(MVLOG_ERROR, "Fail to read firmware by path %s. sc = %d", mv_cmd_file_path, sc);
+ return sc;
+ }
+
+ if(deviceDescToBoot->platform == X_LINK_MYRIAD_X) {
+ if(deviceDescToBoot->protocol != X_LINK_PCIE) {
+ sc = patchSetWdSwitchCommand(&firmware, &length, bootOptions.wdEnable);
+ if(sc) {
+ mvLog(MVLOG_ERROR, "Fail to patch \"Set wd switch value\" command for firmware sc = %d", sc);
+ free(firmware);
+ return sc;
+ }
+ }
+
+ sc = patchSetMemTypeCommand(&firmware, &length, bootOptions.memType);
+ if(sc) {
+ mvLog(MVLOG_ERROR, "Fail to patch \"Set memory type\" command for firmware sc = %d", sc);
+ free(firmware);
+ return sc;
+ }
+ }
+
+ XLinkError_t rc = XLinkBootFirmware(deviceDescToBoot, firmware, length);
+ free(firmware);
+
+ if(rc) {
+ return NC_ERROR;
+ }
+
+ return NC_OK;
+}
if (sleepInterval.count() <= 0) {
continue;
}
-
+#if 0 // To avoid spam in Debug mode
mvLog(MVLOG_DEBUG, "sleep interval = %ld ms\n", sleepInterval.count());
+#endif
waitFor(sleepInterval);
-
+#if 0 // To avoid spam in Debug mode
mvLog(MVLOG_DEBUG, "waiting completed in %ld ms\n",
duration_cast<std::chrono::milliseconds>(steady_clock::now() - currentTime).count());
+#endif
} while (threadRunning);
} catch (const std::exception &ex) {
MvncTestsCommon::MvncTestsCommon() {
#if !(defined(_WIN32) || defined(_WIN64))
// On linux we should use custom path to firmware due to another searching mechanism for library
- strcpy(firmwarePath, "./lib");
+ strcpy(firmwareDir, "./lib/");
#else
- firmwarePath[0] = 0;
+ firmwareDir[0] = "./";
#endif
}
ASSERT_EQ(WD_ERRNO, watchdog_create(&m_watchdogHndl));
m_ncDeviceOpenParams.watchdogInterval = watchdogInterval;
- m_ncDeviceOpenParams.customFirmwareDirectory = firmwarePath;
+ m_ncDeviceOpenParams.customFirmwareDirectory = firmwareDir;
m_ncDeviceOpenParams.watchdogHndl = m_watchdogHndl;
}
if (deviceProtocol == NC_PCIE) {
GTEST_FATAL_FAILURE_("Boot doesn't supported for PCIe protocol\n");
}
- ASSERT_NO_ERROR(ncDeviceLoadFirmware(NC_ANY_PLATFORM, firmwarePath));
+ ASSERT_NO_ERROR(ncDeviceLoadFirmware(NC_ANY_PLATFORM, firmwareDir));
+}
+
+
+std::string MvncTestsCommon::getMyriadUSBFirmwarePath(const std::string& deviceName) {
+ if (deviceName.find('-') == std::string::npos) {
+ throw std::invalid_argument("Invalid device address");
+ }
+
+ std::string firmwareName = "usb-ma2450.mvcmd";
+ if (deviceName.find("ma2480") != std::string::npos) {
+ firmwareName = "usb-ma2x8x.mvcmd";
+ }
+
+ return firmwareDir + firmwareName;
+}
+
+std::string MvncTestsCommon::getMyriadFirmwarePath(const deviceDesc_t& in_deviceDesc) {
+ if(in_deviceDesc.protocol != X_LINK_USB_VSC &&
+ in_deviceDesc.protocol != X_LINK_PCIE) {
+ throw std::invalid_argument("Device protocol must be specified");
+ }
+
+ if(in_deviceDesc.protocol == X_LINK_PCIE) {
+#if defined(_WIN32)
+ const std::string extension = "elf";
+#else
+ const std::string extension = "mvcmd";
+#endif
+ return firmwareDir + std::string("pcie-ma248x.") + extension;
+ }
+
+ return getMyriadUSBFirmwarePath(in_deviceDesc.name);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
class MvncTestsCommon : public ::testing::Test {
public:
- char firmwarePath[MAX_PATH] = {};
+ char firmwareDir[MAX_PATH] = {};
mvLog_t ncLogLevel = MVLOG_INFO;
int watchdogInterval = 1000;
int availableDevices_ = 0;
WatchdogHndl_t* m_watchdogHndl = nullptr;
ncDeviceOpenParams_t m_ncDeviceOpenParams = {};
- ~MvncTestsCommon() override = default;
MvncTestsCommon();
+ ~MvncTestsCommon() override = default;
protected:
void SetUp() override;
* @warning Only USB devices is supported
*/
virtual void bootOneDevice(ncDeviceProtocol_t deviceProtocol= NC_USB);
+
+ // Firmware
+ std::string getMyriadUSBFirmwarePath(const std::string& deviceName);
+ std::string getMyriadFirmwarePath(const deviceDesc_t& in_deviceDesc);
};
//------------------------------------------------------------------------------
#include <thread>
#include "mvnc.h"
+#include "mvnc_data.h"
#include "ncPrivateTypes.h"
#include "mvnc_common_test_cases.h"
ASSERT_NO_ERROR(ncDeviceClose(&deviceHandle, m_watchdogHndl));
}
+TEST_P(MvncOpenDevice, WatchdogShouldResetDeviceWithoutConnection) {
+ if (availableDevices_ == 0)
+ GTEST_SKIP() << ncProtocolToStr(_deviceProtocol) << " devices not found";
+
+ ncDeviceHandle_t* deviceHandle = nullptr;
+ std::string deviceName;
+ deviceDesc_t deviceDescToBoot = {};
+ deviceDesc_t in_deviceDesc = {};
+ in_deviceDesc.protocol = convertProtocolToXlink(_deviceProtocol);
+ in_deviceDesc.platform = convertPlatformToXlink(NC_ANY_PLATFORM);
+ int expectAvailableDevices = getAmountOfDevices(_deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED);
+
+ XLinkError_t rc = X_LINK_ERROR;
+ auto waittm = std::chrono::system_clock::now() + std::chrono::seconds(5);
+ while ((rc != X_LINK_SUCCESS) && (std::chrono::system_clock::now() < waittm)) {
+ rc = XLinkFindFirstSuitableDevice(X_LINK_UNBOOTED, in_deviceDesc, &deviceDescToBoot);
+ }
+
+ bootOptions_t bootOptions = {0};
+ bootOptions.wdEnable = 1;
+
+ auto pathToFirmware = getMyriadFirmwarePath(deviceDescToBoot);
+ ASSERT_EQ(bootDevice(&deviceDescToBoot, pathToFirmware.c_str(), bootOptions), NC_OK);
+
+ std::this_thread::sleep_for(5_sec);
+ ASSERT_EQ(expectAvailableDevices - 1,
+ getAmountOfDevices(_deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED));
+
+ std::this_thread::sleep_for(15_sec);
+ ASSERT_EQ(expectAvailableDevices,
+ getAmountOfDevices(_deviceProtocol, NC_ANY_PLATFORM, X_LINK_UNBOOTED));
+}
+
//------------------------------------------------------------------------------
// MvncLoggingTests Tests
//------------------------------------------------------------------------------
}
TEST_F(XLinkNullPtrTests, XLinkOpenAndCloseStream) {
- ASSERT_EQ(XLinkOpenStream(0, nullptr, 0), X_LINK_ERROR);
+ ASSERT_EQ(XLinkOpenStream(0, nullptr, 0), INVALID_STREAM_ID);
ASSERT_EQ(XLinkCloseStream(0), X_LINK_ERROR);
}
throw std::invalid_argument("Invalid device address");
}
+ std::string firmwareName = "usb-ma2450.mvcmd";
if (deviceName.find("ma2480") != std::string::npos) {
- return FIRMWARE_SUBFOLDER + std::string("usb-ma2x8x.mvcmd");
+ firmwareName = "usb-ma2x8x.mvcmd";
}
- return FIRMWARE_SUBFOLDER + std::string("usb-ma2450.mvcmd");
+ return FIRMWARE_SUBFOLDER + firmwareName;
}
std::string XLinkTestsHelper::getMyriadFirmwarePath(const deviceDesc_t& in_deviceDesc) {
if(in_deviceDesc.protocol == X_LINK_PCIE) {
#if defined(_WIN32)
- return FIRMWARE_SUBFOLDER + std::string("pcie-ma248x.elf");
+ const std::string extension = "elf";
#else
- return FIRMWARE_SUBFOLDER + std::string("pcie-ma248x.mvcmd");
+ const std::string extension = "mvcmd";
#endif
+ return FIRMWARE_SUBFOLDER + std::string("pcie-ma248x.") + extension;
}
return getMyriadUSBFirmwarePath(in_deviceDesc.name);