[ICV] Watchdog switch + ddr initialization (#554)
authorNikita Kudriavtsev <nikita.kudriavtsev@intel.com>
Mon, 8 Jun 2020 17:51:45 +0000 (20:51 +0300)
committerGitHub <noreply@github.com>
Mon, 8 Jun 2020 17:51:45 +0000 (20:51 +0300)
* [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

28 files changed:
inference-engine/cmake/vpu_dependencies.cmake
inference-engine/include/vpu/myriad_plugin_config.hpp
inference-engine/src/vpu/myriad_plugin/myriad_config.cpp
inference-engine/src/vpu/myriad_plugin/myriad_config.h
inference-engine/src/vpu/myriad_plugin/myriad_executor.cpp
inference-engine/tests_deprecated/behavior/vpu/shared_tests_instances/plugin_tests/vpu_test_data.hpp
inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_convolution3x3.hpp
inference-engine/tests_deprecated/functional/vpu/myriad_tests/myriad_configs_tests.cpp
inference-engine/tests_deprecated/unit/engines/vpu/myriad_tests/myriad_engine_tests.cpp
inference-engine/thirdparty/movidius/XLink/pc/PlatformDeviceControl.c
inference-engine/thirdparty/movidius/XLink/pc/protocols/pcie_host.c
inference-engine/thirdparty/movidius/XLink/pc/protocols/pcie_host.h
inference-engine/thirdparty/movidius/XLink/pc/protocols/usb_boot.c
inference-engine/thirdparty/movidius/XLink/shared/include/XLink.h
inference-engine/thirdparty/movidius/XLink/shared/include/XLinkPlatform.h
inference-engine/thirdparty/movidius/XLink/shared/src/XLinkData.c
inference-engine/thirdparty/movidius/XLink/shared/src/XLinkDevice.c
inference-engine/thirdparty/movidius/mvnc/include/mvnc.h
inference-engine/thirdparty/movidius/mvnc/include/mvnc_data.h
inference-engine/thirdparty/movidius/mvnc/include/ncPrivateTypes.h
inference-engine/thirdparty/movidius/mvnc/src/mvnc_api.c
inference-engine/thirdparty/movidius/mvnc/src/mvnc_data.c
inference-engine/thirdparty/movidius/mvnc/src/watchdog/watchdog.cpp
inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.cpp
inference-engine/thirdparty/movidius/mvnc/tests/cases/mvnc_common_test_cases.h
inference-engine/thirdparty/movidius/mvnc/tests/mvnc_tests_common.cpp
inference-engine/thirdparty/movidius/tests/XLink/XLink_common_tests.cpp
inference-engine/thirdparty/movidius/tests/XLink/helpers/XLink_tests_helpers.cpp

index df5a88d..388ce52 100644 (file)
@@ -19,7 +19,7 @@ set(VPU_SUPPORTED_FIRMWARES usb-ma2450 usb-ma2x8x pcie-ma248x)
 # Default packages
 #
 
-set(FIRMWARE_PACKAGE_VERSION 1201)
+set(FIRMWARE_PACKAGE_VERSION 1212)
 set(VPU_CLC_MA2X8X_VERSION "movi-cltools-20.02.0")
 
 #
index f530692..1d94d37 100644 (file)
@@ -52,6 +52,20 @@ DECLARE_VPU_MYRIAD_CONFIG_KEY(PLATFORM);
 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
index d6eb818..b3c7c33 100644 (file)
@@ -44,6 +44,8 @@ IE_SUPPRESS_DEPRECATED_START
 
         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
 
@@ -95,6 +97,14 @@ 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));
@@ -105,6 +115,7 @@ IE_SUPPRESS_DEPRECATED_END
     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));
index d9ba6b6..3dc7050 100644 (file)
@@ -25,6 +25,15 @@ VPU_DECLARE_ENUM(PowerConfig,
     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 {
@@ -59,6 +68,10 @@ public:
         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;
@@ -74,6 +87,7 @@ private:
     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
index 9b7b96c..9e408dc 100644 (file)
@@ -140,6 +140,7 @@ ncStatus_t MyriadExecutor::bootNextDevice(std::vector<DevicePtr> &devicePool,
     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
index 9858ad0..9d5e464 100644 (file)
@@ -112,6 +112,9 @@ const std::vector<BehTestParams> deviceAgnosticConfigurations = {
         {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 = {
@@ -154,6 +157,9 @@ const BehTestParams withIncorrectConfValues[] = {
                                  {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[] = {
index bf06022..cdf98c7 100644 (file)
@@ -102,7 +102,7 @@ void refConvolution3x3(const Blob::Ptr src, InferenceEngine::TBlob<uint8_t>::Ptr
     }
 }
 
-TEST_P(myriadConvolution3x3LayerTests_smoke, Convolution3x3) {
+TEST_P(myriadConvolution3x3LayerTests_smoke, DISABLED_Convolution3x3) {
     std::string model = R"V0G0N(
        <net name="Convolution3x3" version="2" batch="1">
            <layers>
index 2a8ad3e..67b783d 100644 (file)
@@ -69,7 +69,6 @@ TEST_P(myriadCorrectModelsConfigsTests_nightly, CreateInferRequestWithUnavailabl
 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;
@@ -106,9 +105,27 @@ static const std::vector<config_t> myriadIncorrectPlatformConfigValues = {
         // 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));
index 3684985..8c7adbc 100644 (file)
@@ -79,6 +79,19 @@ static const std::vector<config_t> myriadCorrectPowerConfigValues = {
     {{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
@@ -104,4 +117,10 @@ INSTANTIATE_TEST_CASE_P(MyriadPowerConfigs, MyriadEngineSetCorrectConfigTest,
                         ::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));
index 4ebc9f5..9d282bb 100644 (file)
@@ -94,11 +94,10 @@ void XLinkPlatformInit()
 
 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");
@@ -126,21 +125,28 @@ int XLinkPlatformBootRemote(deviceDesc_t* deviceDesc, const char* binaryPath)
     }
     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) {
@@ -152,16 +158,13 @@ int XLinkPlatformBootRemote(deviceDesc_t* deviceDesc, const char* binaryPath)
             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;
     }
 }
@@ -246,7 +249,7 @@ libusb_device_handle *usbLinkOpen(const char *path)
     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);
index e7c5f65..68eeecd 100644 (file)
@@ -533,9 +533,9 @@ pcieHostError_t pcie_reset_device(HANDLE fd)
 #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);
@@ -583,7 +583,7 @@ pcieHostError_t pcie_boot_device(HANDLE fd, void *buffer, size_t length)
 
     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
index 9cb91ca..172bf26 100644 (file)
@@ -41,11 +41,11 @@ pcieHostError_t pcie_init(const char *slot, void **fd);
 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
 
index ba63fcb..723ee83 100644 (file)
@@ -313,8 +313,10 @@ usbBootError_t usb_find_device_with_bcd(unsigned idx, char *input_addr,
             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);
@@ -332,8 +334,10 @@ usbBootError_t usb_find_device_with_bcd(unsigned idx, char *input_addr,
                 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");
@@ -342,8 +346,10 @@ usbBootError_t usb_find_device_with_bcd(unsigned idx, char *input_addr,
                 }
             } 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");
@@ -569,9 +575,7 @@ static int wait_findopen(const char *device_address, int timeout, libusb_device
         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) {
index 89bb643..ac2762d 100644 (file)
@@ -83,6 +83,15 @@ XLinkError_t XLinkConnect(XLinkHandler_t* handler);
 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
  * @param[in] id â€“ link Id obtained from XLinkConnect in the handler parameter
index 74e3fc4..d8bb336 100644 (file)
@@ -51,6 +51,7 @@ xLinkPlatformErrorCode_t XLinkPlatformFindArrayOfDevicesNames(
     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__
index 67762d3..442ed4e 100644 (file)
@@ -287,7 +287,7 @@ static XLinkError_t getLinkByStreamId(streamId_t streamId, xLinkDesc_t** out_lin
     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);
 
index d8cde9e..019a2d6 100644 (file)
@@ -225,6 +225,14 @@ XLinkError_t XLinkBoot(deviceDesc_t* deviceDesc, const char* binaryPath)
     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);
index a3f6d2d..02bef56 100644 (file)
@@ -164,6 +164,7 @@ struct ncDeviceDescr_t {
 typedef struct ncDeviceOpenParams {
     WatchdogHndl_t* watchdogHndl;
     int watchdogInterval;
+    char memoryType;
     const char* customFirmwareDirectory;
 } ncDeviceOpenParams_t;
 
index 2c44747..9e73b0b 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "mvnc.h"
 #include "XLinkPlatform.h"
+#include "ncPrivateTypes.h"
 #ifdef __cplusplus
 extern "C"
 {
@@ -23,6 +24,9 @@ int copyNcDeviceDescrToXLink(
 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
index e539788..2e846b9 100644 (file)
@@ -111,6 +111,10 @@ struct _fifoPrivate_t {
     void* output_data;
 };
 
+typedef struct {
+    char memType;
+    char wdEnable;
+} bootOptions_t;
 
 #if (!defined(_WIN32) && !defined(_WIN64))
 #define PACKED(name) struct __attribute__((packed)) name
index 3900783..b44ea52 100644 (file)
@@ -680,6 +680,10 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
         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) {
@@ -846,8 +850,8 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
             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);
@@ -929,9 +933,8 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
         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 {
@@ -1099,11 +1102,15 @@ ncStatus_t ncDeviceOpen(struct ncDeviceHandle_t **deviceHandlePtr,
     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
 
@@ -1668,7 +1675,6 @@ static ncStatus_t destroyDeviceHandle(struct ncDeviceHandle_t **deviceHandlePtr)
     return NC_OK;
 }
 
-
 ncStatus_t ncDeviceClose(struct ncDeviceHandle_t **deviceHandlePtr, WatchdogHndl_t* watchdogHndl) {
     int found = 0;
     XLinkError_t rc = X_LINK_SUCCESS;
index 3ce7bfd..4b194db 100644 (file)
 * 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) {
@@ -89,4 +93,199 @@ int copyXLinkDeviceDescrToNc(const deviceDesc_t *in_DeviceDesc,
     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;
+}
index dda87de..fb5afeb 100644 (file)
@@ -297,13 +297,15 @@ void WatchdogImpl::watchdogRoutine() noexcept {
             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) {
index 196d2ac..aa50b66 100644 (file)
@@ -10,9 +10,9 @@
 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
 }
 
@@ -24,7 +24,7 @@ void MvncTestsCommon::SetUp() {
     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;
 }
 
@@ -71,7 +71,39 @@ void MvncTestsCommon::bootOneDevice(ncDeviceProtocol_t deviceProtocol) {
     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);
 }
 
 //------------------------------------------------------------------------------
index 76960be..9ba0c40 100644 (file)
@@ -29,15 +29,15 @@ constexpr std::chrono::seconds operator "" _sec(unsigned long long s)
 //------------------------------------------------------------------------------
 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;
@@ -59,6 +59,10 @@ public:
      * @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);
 };
 
 //------------------------------------------------------------------------------
index b41e13d..7e87e0f 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <thread>
 #include "mvnc.h"
+#include "mvnc_data.h"
 #include "ncPrivateTypes.h"
 #include "mvnc_common_test_cases.h"
 
@@ -295,6 +296,39 @@ TEST_P(MvncOpenDevice, OpenTwiceWithOneXLinkInitializion) {
     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
 //------------------------------------------------------------------------------
index b76c340..98045b7 100644 (file)
@@ -19,7 +19,7 @@ TEST_F(XLinkNullPtrTests, XLinkConnect) {
 }
 
 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);
 }
 
index 2ab2d01..c51b466 100644 (file)
@@ -68,11 +68,12 @@ std::string XLinkTestsHelper::getMyriadUSBFirmwarePath(const std::string& device
         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) {
@@ -83,10 +84,11 @@ std::string XLinkTestsHelper::getMyriadFirmwarePath(const deviceDesc_t& in_devic
 
     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);