CMSIS VIO: registered API and added virtual implementation (using memory only)
diff --git a/ARM.CMSIS.pdsc b/ARM.CMSIS.pdsc
index b12a767..8b43458 100644
--- a/ARM.CMSIS.pdsc
+++ b/ARM.CMSIS.pdsc
@@ -13,6 +13,8 @@
       CMSIS-NN: 1.3.0 (see revision history for details)
         - Added MVE support
         - Further optimizations for kernels using DSP extension
+      CMSIS-Driver: 2.8.0
+        - Added VIO API 0.1.0 (Preview)
     </release>
     <release version="5.7.0-dev4">
       CMSIS-DSP: 1.8.0 (see revision history for details)
@@ -36,7 +38,7 @@
     <release version="5.7.0-dev1">
       Active development...
       CMSIS-Core(M): 5.4.0 (see revision history for details)
-         - Enhanced MVE support for Armv8.1-MML
+        - Enhanced MVE support for Armv8.1-MML
       CMSIS-RTOS2:
         - RTX 5.5.2 (see revision history for details)
       CMSIS-Driver: 2.8.0
@@ -975,6 +977,13 @@
         <file category="header" name="CMSIS/Driver/Include/Driver_WiFi.h" />
       </files>
     </api>
+    <api Cclass="CMSIS Driver" Cgroup="VIO" Capiversion="0.1.0" exclusive="1">
+      <description>Virtual I/O</description>
+      <files>
+  <!--  <file category="doc" name="CMSIS/Documentation/Driver/html/vio_pg.html"/> -->
+        <file category="header" name="CMSIS/Driver/VIO/Include/cmsis_vio.h" />
+      </files>
+    </api>
   </apis>
 
   <!-- conditions are dependency rules that can apply to a component or an individual file -->
@@ -3880,6 +3889,23 @@
         <!-- <file category="sourceC" attr="template" name="CMSIS/Driver/DriverTemplates/Driver_WiFi.c" select="WiFi Driver"/> -->
       </files>
     </component>
+
+    <!-- VIO components -->
+    <component Cclass="CMSIS Driver" Cgroup="VIO" Csub="Custom" Cversion="1.0.0" Capiversion="0.1.0" custom="1">
+      <description>Virtual I/O custom implementation template</description>
+      <files>
+        <file category="sourceC" name="CMSIS/Driver/VIO/Source/vio.c" attr="template" select="Virtual I/O"/>
+        <file category="other"   name="CMSIS/Driver/VIO/cmsis_vio.scvd"/>
+      </files>
+    </component>
+    <component Cclass="CMSIS Driver" Cgroup="VIO" Csub="Virtual" Cversion="1.0.0" Capiversion="0.1.0">
+      <description>Virtual I/O implementation using memory only</description>
+      <files>
+        <file category="sourceC" name="CMSIS/Driver/VIO/Source/vio_memory.c"/>
+        <file category="other"   name="CMSIS/Driver/VIO/cmsis_vio.scvd"/>
+      </files>
+    </component>
+
   </components>
 
   <boards>
diff --git a/CMSIS/DoxyGen/Build/Build.dxy b/CMSIS/DoxyGen/Build/Build.dxy
index abb708a..6b59cd5 100644
--- a/CMSIS/DoxyGen/Build/Build.dxy
+++ b/CMSIS/DoxyGen/Build/Build.dxy
@@ -759,7 +759,7 @@
                          src/CmdLineBuild.txt \
                          src/cprj_schema.txt \
                          src/vio.txt \
-                         ../../Build/VIO/Include/cmsis_vio.h \
+                         ../../Driver/VIO/Include/cmsis_vio.h \
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/CMSIS/Driver/VIO/Include/cmsis_vio.h b/CMSIS/Driver/VIO/Include/cmsis_vio.h
index 639597d..a85d74e 100644
--- a/CMSIS/Driver/VIO/Include/cmsis_vio.h
+++ b/CMSIS/Driver/VIO/Include/cmsis_vio.h
@@ -1,8 +1,8 @@
-/**************************************************************************//**
+/******************************************************************************
  * @file     cmsis_vio.h
  * @brief    CMSIS Virtual I/O header file
- * @version  V1.4.0
- * @date     11. March 2020
+ * @version  V0.1.0
+ * @date     18. March 2020
  ******************************************************************************/
 /*
  * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
@@ -31,74 +31,72 @@
  * Generic I/O mapping recommended for CMSIS-VIO
  * Note: not every I/O must be physically available
  */
- 
-// cvSetSignal: mask values 
-#define cvLED0             (1U << 0)   /// cvSetSignal mask LED 0 (for 3-color: red)
-#define cvLED1             (1U << 1)   /// cvSetSignal mask LED 1 (for 3-color: green)
-#define cvLED2             (1U << 2)   /// cvSetSignal mask LED 2 (for 3-color: blue)
-#define cvLED3             (1U << 3)   /// cvSetSignal mask LED 3
-#define cvLED4             (1U << 4)   /// cvSetSignal mask LED 4
-#define cvLED5             (1U << 5)   /// cvSetSignal mask LED 5
-#define cvLED6             (1U << 6)   /// cvSetSignal mask LED 6
-#define cvLED7             (1U << 7)   /// cvSetSignal mask LED 7
+
+/// cvSetSignal: mask values 
+#define cvLED0             (1U << 0)    /// cvSetSignal mask LED 0 (for 3-color: red)
+#define cvLED1             (1U << 1)    /// cvSetSignal mask LED 1 (for 3-color: green)
+#define cvLED2             (1U << 2)    /// cvSetSignal mask LED 2 (for 3-color: blue)
+#define cvLED3             (1U << 3)    /// cvSetSignal mask LED 3
+#define cvLED4             (1U << 4)    /// cvSetSignal mask LED 4
+#define cvLED5             (1U << 5)    /// cvSetSignal mask LED 5
+#define cvLED6             (1U << 6)    /// cvSetSignal mask LED 6
+#define cvLED7             (1U << 7)    /// cvSetSignal mask LED 7
 
 /// cvSetSignal: signal values
-#define cvLEDon            (0xFF)      // pattern to turn any LED on
-#define cvLEDoff           (0x00)      // pattern to turn any LED off
+#define cvLEDon            (0xFFU)      /// pattern to turn any LED on
+#define cvLEDoff           (0x00U)      /// pattern to turn any LED off
 
 
 /// cvGetSignal: mask values and return values
-#define cvBUTTON0          (1U << 0)   ///< cvGetSignal mask Push button 0
-#define cvBUTTON1          (1U << 1)   ///< cvGetSignal mask Push button 1
-#define cvBUTTON2          (1U << 2)   ///< cvGetSignal mask Push button 2
-#define cvBUTTON3          (1U << 3)   ///< cvGetSignal mask Push button 3
-#define cvJOYup            (1U << 4)   ///< cvGetSignal mask Joystick button: up
-#define cvJOYdown          (1U << 5)   ///< cvGetSignal mask Joystick button: down
-#define cvJOYleft          (1U << 6)   ///< cvGetSignal mask Joystick button: left
-#define cvJOYright         (1U << 7)   ///< cvGetSignal mask Joystick button: right
-#define cvJOYselect        (1U << 8)   ///< cvGetSignal mask Joystick button: select
+#define cvBUTTON0          (1U << 0)    ///< cvGetSignal mask Push button 0
+#define cvBUTTON1          (1U << 1)    ///< cvGetSignal mask Push button 1
+#define cvBUTTON2          (1U << 2)    ///< cvGetSignal mask Push button 2
+#define cvBUTTON3          (1U << 3)    ///< cvGetSignal mask Push button 3
+#define cvJOYup            (1U << 4)    ///< cvGetSignal mask Joystick button: up
+#define cvJOYdown          (1U << 5)    ///< cvGetSignal mask Joystick button: down
+#define cvJOYleft          (1U << 6)    ///< cvGetSignal mask Joystick button: left
+#define cvJOYright         (1U << 7)    ///< cvGetSignal mask Joystick button: right
+#define cvJOYselect        (1U << 8)    ///< cvGetSignal mask Joystick button: select
 #define cvJOYall           (cvJOYup     | \
                             cvJOYdown   | \
                             cvJOYleft   | \
                             cvJOYright  | \
-                            cvJOYselect | ) 
-
+                            cvJOYselect | )
 
 /// cvSetValue / cvGetValue: id values
-#define cvAIN0             (0U)        ///< cvSetvalue / cvgetValue Analog input value 0
-#define cvAIN1             (1U)        ///< cvSetvalue / cvgetValue Analog input value 1
-#define cvAIN2             (2U)        ///< cvSetvalue / cvgetValue Analog input value 2
-#define cvAIN3             (3U)        ///< cvSetvalue / cvgetValue Analog input value 3
-#define cvAOUT0            (3U)        ///< cvSetvalue / cvgetValue Analog output value 0
+#define cvAIN0             (0U)         ///< cvSetvalue / cvGetValue Analog input value 0
+#define cvAIN1             (1U)         ///< cvSetvalue / cvGetValue Analog input value 1
+#define cvAIN2             (2U)         ///< cvSetvalue / cvGetValue Analog input value 2
+#define cvAIN3             (3U)         ///< cvSetvalue / cvGetValue Analog input value 3
+#define cvAOUT0            (3U)         ///< cvSetvalue / cvGetValue Analog output value 0
 
 
 /// cvSetXYZ / cvGetXZY: id values
-#define cvMotionGyro       (0U)        ///< cvSetXYZ / cvGetXYZ Gyroscope
-#define cvMotionAccelero   (1U)        ///< cvSetXYZ / cvGetXYZ Accelerometer
-#define cvMotionMagneto    (2U)        ///< cvSetXYZ / cvGetXYZ Magnetometer
-
+#define cvMotionGyro       (0U)         ///< cvSetXYZ / cvGetXYZ Gyroscope
+#define cvMotionAccelero   (1U)         ///< cvSetXYZ / cvGetXYZ Accelerometer
+#define cvMotionMagneto    (2U)         ///< cvSetXYZ / cvGetXYZ Magnetometer
 
 /// cvPrint: levels
-#define cvLevelNone        (0U)        ///< cvPrint Level None
-#define cvLevelHeading     (1U)        ///< cvPrint Level Heading
-#define cvLevelMessage     (2U)        ///< cvPrint Level Message
-#define cvLevelError       (3U)        ///< cvPrint Level Error
+#define cvLevelNone        (0U)         ///< cvPrint Level None
+#define cvLevelHeading     (1U)         ///< cvPrint Level Heading
+#define cvLevelMessage     (2U)         ///< cvPrint Level Message
+#define cvLevelError       (3U)         ///< cvPrint Level Error
 
 /// 3-D vector value
 typedef struct cvValueXYZ {
-  int32_t   X;                         ///< X coordinate
-  int32_t   Y;                         ///< Y coordinate
-  int32_t   Z;                         ///< Z coordinate
+  int32_t   X;                          ///< X coordinate
+  int32_t   Y;                          ///< Y coordinate
+  int32_t   Z;                          ///< Z coordinate
 } cvValueXYZ_t;
 
 /// IPv4 Internet Address
-typedef struct cvAddrIPv4 {
-  uint8_t   addr[4];                   ///< IPv4 address value
+typedef struct {
+  uint8_t   addr[4];                    ///< IPv4 address value
 } cvAddrIPv4_t;
 
 /// IPv6 Internet Address
-typedef struct cvAddrIPv6 {
-  uint8_t   addr[16];                  ///< IPv6 address value
+typedef struct {
+  uint8_t   addr[16];                   ///< IPv6 address value
 } cvAddrIPv6_t;
 
 #ifdef  __cplusplus
@@ -107,7 +105,7 @@
 #endif
 
 /// Initialize test input, output.
-/// \return none
+/// \return none.
 void cvInit (void);
 
 /// Print formated string to test terminal.
@@ -123,19 +121,19 @@
 
 /// Set signal output.
 /// \param[in]     mask         bit mask of signals to set.
-/// \param[in]     signal       signal value to set (LEDs bit 0..15,  Switches bit 16..31).
-/// \return none
+/// \param[in]     signal       signal value to set.
+/// \return none.
 void cvSetSignal (uint32_t mask, uint32_t signal);
 
 /// Get signal input.
 /// \param[in]     mask         bit mask of signals to read.
-/// \return signal value or highest bit set in case of error.
+/// \return signal value.
 uint32_t cvGetSignal (uint32_t mask);
 
 /// Set value output.
 /// \param[in]     id           output identifier.
 /// \param[in]     value        value to set.
-/// \return none
+/// \return none.
 void cvSetValue (uint32_t id, int32_t value);
 
 /// Get value input.
@@ -146,7 +144,7 @@
 /// Set XYZ value output.
 /// \param[in]     id           output identifier.
 /// \param[in]     valueXYZ     XYZ data to set.
-/// \return none
+/// \return none.
 void cvSetXYZ (uint32_t id, cvValueXYZ_t valueXYZ);
 
 /// Get XYZ value input.
@@ -157,23 +155,23 @@
 /// Set IPv4 address output.
 /// \param[in]     id           output identifier.
 /// \param[in]     addrIPv4     pointer to IPv4 address.
-/// \return none
+/// \return none.
 void cvSetIPv4 (uint32_t id, cvAddrIPv4_t addrIPv4);
 
 /// Get IPv4 address input.
 /// \param[in]     id           input identifier.
-/// \return IPv4 address retrieved from peripheral
+/// \return IPv4 address retrieved from peripheral.
 cvAddrIPv4_t cvGetIPv4 (uint32_t id);
 
 /// Set IPv6 address output.
 /// \param[in]     id           output identifier.
 /// \param[in]     addrIPv6     pointer to IPv6 address.
-/// \return none
+/// \return none.
 void cvSetIPv6 (uint32_t id, cvAddrIPv6_t addrIPv6);
 
 /// Get IPv6 address from peripheral.
 /// \param[in]     id           input identifier.
-/// \return IPv6 address retrieved from peripheral
+/// \return IPv6 address retrieved from peripheral.
 cvAddrIPv6_t cvGetIPv6 (uint32_t id);
 
 #ifdef  __cplusplus
diff --git a/CMSIS/Driver/VIO/Source/vio.c b/CMSIS/Driver/VIO/Source/vio.c
new file mode 100644
index 0000000..01f5e65
--- /dev/null
+++ b/CMSIS/Driver/VIO/Source/vio.c
@@ -0,0 +1,278 @@
+/******************************************************************************
+ * @file     vio.c
+ * @brief    Virtual I/O implementation template
+ * @version  V1.0.0
+ * @date     18. March 2020
+ ******************************************************************************/
+/*
+ * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "cmsis_vio.h"
+
+#include "RTE_Components.h"             // Component selection
+#include CMSIS_device_header
+
+// CV input, output definitions
+#define CV_PRINT_MAX_SIZE       64U     // maximum size of print memory
+#define CV_PRINTMEM_NUM          4U     // number of print memories
+#define CV_VALUE_NUM             3U     // number of values
+#define CV_VALUEXYZ_NUM          3U     // number of XYZ values
+#define CV_IPV4_ADDRESS_NUM      2U     // number of IPv4 addresses
+#define CV_IPV6_ADDRESS_NUM      2U     // number of IPv6 addresses
+
+// CV input, output variables
+__USED uint32_t     cvSignalIn;
+__USED uint32_t     cvSignalOut;
+__USED char         cvPrintMem[CV_PRINTMEM_NUM][CV_PRINT_MAX_SIZE];
+__USED int32_t      cvValue   [CV_VALUE_NUM];
+__USED cvValueXYZ_t cvValueXYZ[CV_VALUEXYZ_NUM];
+__USED cvAddrIPv4_t cvAddrIPv4[CV_IPV4_ADDRESS_NUM];
+__USED cvAddrIPv6_t cvAddrIPv6[CV_IPV6_ADDRESS_NUM];
+
+// Initialize test input, output.
+void cvInit (void) {
+
+  cvSignalIn  = 0U;
+  cvSignalOut = 0U;
+
+  memset (cvPrintMem, 0, sizeof(cvPrintMem));
+  memset (cvValue,    0, sizeof(cvValue));
+  memset (cvValueXYZ, 0, sizeof(cvValueXYZ));
+  memset (cvAddrIPv4, 0, sizeof(cvAddrIPv4));
+  memset (cvAddrIPv6, 0, sizeof(cvAddrIPv6));
+
+// Add user code here:
+// <code cvInit>
+
+// </code>
+}
+
+// Print formated string to test terminal.
+int32_t cvPrint (uint32_t level, const char *format, ...) {
+  va_list args;
+  int32_t ret;
+
+  if (level > cvLevelError) {
+    return (-1);
+  }
+
+  if (level > CV_PRINTMEM_NUM) {
+    return (-1);
+  }
+
+  va_start(args, format);
+
+  ret = vsnprintf((char *)cvPrintMem[level], sizeof(cvPrintMem[level]), format, args);
+
+  va_end(args);
+
+// Add user code here:
+// <code cvPrint>
+
+// </code>
+
+  return (ret);
+}
+
+// Get character from test terminal.
+int32_t cvGetChar (void) {
+  int32_t ch = -1;
+
+// Add user code here:
+// <code cvGetChar>
+
+//   ch = ...;
+// </code>
+
+  return ch;
+}
+
+// Set signal output.
+void cvSetSignal (uint32_t mask, uint32_t signal) {
+
+  cvSignalOut &= ~mask;
+  cvSignalOut |=  mask & signal;
+
+// Add user code here:
+// <code cvSetSignal>
+
+// </code>
+}
+
+// Get signal input.
+uint32_t cvGetSignal (uint32_t mask) {
+  uint32_t signal;
+
+// Add user code here:
+// <code cvGetSignal>
+
+//   cvSignalIn = ...;
+// </code>
+
+  signal = cvSignalIn;
+
+  return (signal & mask);
+}
+
+// Set value output.
+void cvSetValue (uint32_t id, int32_t value) {
+  uint32_t index = id;
+
+  if (index >= CV_VALUE_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvValue[index] = value;
+
+// Add user code here:
+// <code cvSetValue>
+
+// </code>
+}
+
+// Get value input.
+int32_t cvGetValue (uint32_t id) {
+  uint32_t index = id;
+  int32_t  value = 0;
+
+  if (index >= CV_VALUE_NUM) {
+    return value;                       /* return default in case of out-of-range index */
+  }
+
+// Add user code here:
+// <code cvGetValue>
+
+//   cvValue[index] = ...;
+// </code>
+
+  value = cvValue[index];
+
+  return value;
+}
+
+// Set XYZ value output.
+void cvSetXYZ (uint32_t id, cvValueXYZ_t valueXYZ) {
+  uint32_t index = id;
+
+  if (index >= CV_VALUEXYZ_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvValueXYZ[index] = valueXYZ;
+
+// Add user code here:
+// <code cvSetXYZ>
+
+// </code>
+}
+
+// Get XYZ value input.
+cvValueXYZ_t cvGetXYZ (uint32_t id) {
+  uint32_t index = id;
+  cvValueXYZ_t valueXYZ = {0, 0, 0};
+
+  if (index >= CV_VALUEXYZ_NUM) {
+    return valueXYZ;                    /* return default in case of out-of-range index */
+  }
+
+// Add user code here:
+// <code cvGetXYZ>
+
+//   cvValueXYZ[index] = ...;
+// </code>
+
+  valueXYZ = cvValueXYZ[index];
+
+  return valueXYZ;
+}
+
+// Set IPv4 address output.
+void cvSetIPv4 (uint32_t id, cvAddrIPv4_t addrIPv4) {
+  uint32_t index = id;
+
+  if (index >= CV_IPV4_ADDRESS_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvAddrIPv4[index] = addrIPv4;
+
+// Add user code here:
+// <code cvSetIPv4>
+
+// </code>
+}
+
+// Get IPv4 address input.
+cvAddrIPv4_t cvGetIPv4 (uint32_t id) {
+  uint32_t index = id;
+  cvAddrIPv4_t addrIPv4 = {0U, 0U, 0U, 0U};
+
+  if (index >= CV_IPV4_ADDRESS_NUM) {
+    return addrIPv4;                    /* return default in case of out-of-range index */
+  }
+
+// Add user code here:
+// <code cvGetIPv4>
+
+//   cvAddrIPv4[index] = ...;
+// </code>
+
+  addrIPv4 = cvAddrIPv4[index];
+
+  return addrIPv4;
+}
+
+// Set IPv6 address output.
+void cvSetIPv6 (uint32_t id, cvAddrIPv6_t addrIPv6) {
+  uint32_t index = id;
+
+  if (index >= CV_IPV6_ADDRESS_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvAddrIPv6[index] = addrIPv6;
+
+// Add user code here:
+// <code cvSetIPv6>
+
+// </code>
+}
+
+// Get IPv6 address input.
+cvAddrIPv6_t cvGetIPv6 (uint32_t id) {
+  uint32_t index = id;
+  cvAddrIPv6_t addrIPv6 = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
+                           0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
+
+  if (index >= CV_IPV6_ADDRESS_NUM) {
+    return addrIPv6;                    /* return default in case of out-of-range index */
+  }
+
+// Add user code here:
+// <code cvGetIPv6>
+
+//   cvAddrIPv6[index] = ...;
+// </code>
+
+  addrIPv6 = cvAddrIPv6[index];
+
+  return addrIPv6;
+}
diff --git a/CMSIS/Driver/VIO/Source/vio_memory.c b/CMSIS/Driver/VIO/Source/vio_memory.c
new file mode 100644
index 0000000..dbabfce
--- /dev/null
+++ b/CMSIS/Driver/VIO/Source/vio_memory.c
@@ -0,0 +1,215 @@
+/******************************************************************************
+ * @file     vio_memory.c
+ * @brief    Virtual I/O implementation using memory only
+ * @version  V1.0.0
+ * @date     18. March 2020
+ ******************************************************************************/
+/*
+ * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "cmsis_vio.h"
+
+#include "RTE_Components.h"             // Component selection
+#include CMSIS_device_header
+
+// CV input, output definitions
+#define CV_PRINT_MAX_SIZE       64U     // maximum size of print memory
+#define CV_PRINTMEM_NUM          4U     // number of print memories
+#ifndef CV_VALUE_NUM
+#define CV_VALUE_NUM             3U     // number of values
+#endif
+#ifndef CV_VALUEXYZ_NUM
+#define CV_VALUEXYZ_NUM          3U     // number of XYZ values
+#endif
+#ifndef CV_IPV4_ADDRESS_NUM
+#define CV_IPV4_ADDRESS_NUM      2U     // number of IPv4 addresses
+#endif
+#ifndef CV_IPV6_ADDRESS_NUM
+#define CV_IPV6_ADDRESS_NUM      2U     // number of IPv6 addresses
+#endif
+
+// CV input, output variables
+__USED uint32_t     cvSignalIn;
+__USED uint32_t     cvSignalOut;
+__USED char         cvPrintMem[CV_PRINTMEM_NUM][CV_PRINT_MAX_SIZE];
+__USED int32_t      cvValue   [CV_VALUE_NUM];
+__USED cvValueXYZ_t cvValueXYZ[CV_VALUEXYZ_NUM];
+__USED cvAddrIPv4_t cvAddrIPv4[CV_IPV4_ADDRESS_NUM];
+__USED cvAddrIPv6_t cvAddrIPv6[CV_IPV6_ADDRESS_NUM];
+
+// Initialize test input, output.
+void cvInit (void) {
+
+  cvSignalIn  = 0U;
+  cvSignalOut = 0U;
+
+  memset (cvPrintMem, 0, sizeof(cvPrintMem));
+  memset (cvValue,    0, sizeof(cvValue));
+  memset (cvValueXYZ, 0, sizeof(cvValueXYZ));
+  memset (cvAddrIPv4, 0, sizeof(cvAddrIPv4));
+  memset (cvAddrIPv6, 0, sizeof(cvAddrIPv6));
+}
+
+// Print formated string to test terminal.
+int32_t cvPrint (uint32_t level, const char *format, ...) {
+  va_list args;
+  int32_t ret;
+
+  if (level > cvLevelError) {
+    return (-1);
+  }
+
+  if (level > CV_PRINTMEM_NUM) {
+    return (-1);
+  }
+
+  va_start(args, format);
+
+  ret = vsnprintf((char *)cvPrintMem[level], sizeof(cvPrintMem[level]), format, args);
+
+  va_end(args);
+
+  return (ret);
+}
+
+// Get character from test terminal.
+int32_t cvGetChar (void) {
+  int32_t ch = -1;
+
+  return ch;
+}
+
+// Set signal output.
+void cvSetSignal (uint32_t mask, uint32_t signal) {
+
+  cvSignalOut &= ~mask;
+  cvSignalOut |=  mask & signal;
+}
+
+// Get signal input.
+uint32_t cvGetSignal (uint32_t mask) {
+  uint32_t signal;
+
+  signal = cvSignalIn;
+
+  return (signal & mask);
+}
+
+// Set value output.
+void cvSetValue (uint32_t id, int32_t value) {
+  uint32_t index = id;
+
+  if (index >= CV_VALUE_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvValue[index] = value;
+}
+
+// Get value input.
+int32_t cvGetValue (uint32_t id) {
+  uint32_t index = id;
+  int32_t  value = 0;
+
+  if (index >= CV_VALUE_NUM) {
+    return value;                       /* return default in case of out-of-range index */
+  }
+
+  value = cvValue[index];
+
+  return value;
+}
+
+// Set XYZ value output.
+void cvSetXYZ (uint32_t id, cvValueXYZ_t valueXYZ) {
+  uint32_t index = id;
+
+  if (index >= CV_VALUEXYZ_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvValueXYZ[index] = valueXYZ;
+}
+
+// Get XYZ value input.
+cvValueXYZ_t cvGetXYZ (uint32_t id) {
+  uint32_t index = id;
+  cvValueXYZ_t valueXYZ = {0, 0, 0};
+
+  if (index >= CV_VALUEXYZ_NUM) {
+    return valueXYZ;                    /* return default in case of out-of-range index */
+  }
+
+  valueXYZ = cvValueXYZ[index];
+
+  return valueXYZ;
+}
+
+// Set IPv4 address output.
+void cvSetIPv4 (uint32_t id, cvAddrIPv4_t addrIPv4) {
+  uint32_t index = id;
+
+  if (index >= CV_IPV4_ADDRESS_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvAddrIPv4[index] = addrIPv4;
+}
+
+// Get IPv4 address input.
+cvAddrIPv4_t cvGetIPv4 (uint32_t id) {
+  uint32_t index = id;
+  cvAddrIPv4_t addrIPv4 = {0U, 0U, 0U, 0U};
+
+  if (index >= CV_IPV4_ADDRESS_NUM) {
+    return addrIPv4;                    /* return default in case of out-of-range index */
+  }
+
+  addrIPv4 = cvAddrIPv4[index];
+
+  return addrIPv4;
+}
+
+// Set IPv6 address output.
+void cvSetIPv6 (uint32_t id, cvAddrIPv6_t addrIPv6) {
+  uint32_t index = id;
+
+  if (index >= CV_IPV6_ADDRESS_NUM) {
+    return;                             /* return in case of out-of-range index */
+  }
+
+  cvAddrIPv6[index] = addrIPv6;
+}
+
+// Get IPv6 address input.
+cvAddrIPv6_t cvGetIPv6 (uint32_t id) {
+  uint32_t index = id;
+  cvAddrIPv6_t addrIPv6 = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
+                           0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
+
+  if (index >= CV_IPV6_ADDRESS_NUM) {
+    return addrIPv6;                    /* return default in case of out-of-range index */
+  }
+
+  addrIPv6 = cvAddrIPv6[index];
+
+  return addrIPv6;
+}
diff --git a/CMSIS/Driver/VIO/cmsis_vio.scvd b/CMSIS/Driver/VIO/cmsis_vio.scvd
index 5196626..f963959 100644
--- a/CMSIS/Driver/VIO/cmsis_vio.scvd
+++ b/CMSIS/Driver/VIO/cmsis_vio.scvd
@@ -1,8 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
+<component_viewer schemaVersion="1.2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
 <component name="CMSIS Virtual I/O" version="1.0.0"/>
 
   <typedefs>
+    <typedef name="cvPrintMem_t" size="64">
+      <member name="mem" type="uint8_t" size="64" offset="0"/>
+    </typedef>
+
     <typedef name="cvValueXYZ_t" size="12">
       <member name="X" type="int32_t" offset="0"/>
       <member name="Y" type="int32_t" offset="4"/>
@@ -17,26 +21,21 @@
       <member name="addr" type="uint8_t" size="16" offset="0"/>
     </typedef>
 
-    <typedef name="cvPrintMem_t" size="64">
-      <member name="mem" type="uint8_t" size="64" offset="0"/>
-    </typedef>
-
   </typedefs>
 
   <objects>
-    <object name="Virtual I/O">
-      <var name="i" type="int32_t" value="0" />
+    <object name="Virtual I/O Object">
+      <var name="i" type="int32_t" value="0"/>
 
       <read     name="SignalIn"    type="uint32_t"     symbol="cvSignalIn"/>
       <read     name="SignalOut"   type="uint32_t"     symbol="cvSignalOut"/>
-      <readlist name="PrintMem"     type="cvPrintMem_t" symbol="cvPrintMem" count="4" />
-      <read     name="Value"        type="int32_t"      symbol="cvValue"    size="3" />
-      <readlist name="ValueXYZ"     type="cvValueXYZ_t" symbol="cvValueXYZ" count="3" />
+      <readlist name="PrintMem"    type="cvPrintMem_t" symbol="cvPrintMem" count="4"/>
+      <read     name="Value"       type="int32_t"      symbol="cvValue"    size="__size_of(&quot;cvValue&quot;)"/>
+      <readlist name="ValueXYZ"    type="cvValueXYZ_t" symbol="cvValueXYZ" count="__size_of(&quot;cvValueXYZ&quot;)"/>
+      <readlist name="IPv4Address" type="cvAddrIPv4_t" symbol="cvAddrIPv4" count="__size_of(&quot;cvAddrIPv4&quot;)"/>
+      <readlist name="IPv6Address" type="cvAddrIPv6_t" symbol="cvAddrIPv6" count="__size_of(&quot;cvAddrIPv6&quot;)"/>
 
-      <readlist name="IPv4Address"  type="cvAddrIPv4_t" symbol="cvAddrIPv4" count="2" />
-      <readlist name="IPv6Address"  type="cvAddrIPv6_t" symbol="cvAddrIPv6" count="2" />
-
-      <out name="Test I/O">
+      <out name="Virtual I/O">
         <item property="Signal Bits (Input)"  value="%x[SignalIn]"/>
         <item property="Signal Bits (Output)" value="%x[SignalOut]"/>
 
@@ -77,5 +76,7 @@
       </out>
 
     </object>
+
   </objects>
+
 </component_viewer>