Skip to content

Commit

Permalink
Merge pull request #192 from RobertGawron/feature/hw_4_0_firmware_pre…
Browse files Browse the repository at this point in the history
…validation

Feature/hw 4 0 firmware prevalidation
  • Loading branch information
RobertGawron authored Jan 4, 2025
2 parents dd9e8e7 + e6b9de2 commit ee4de5d
Show file tree
Hide file tree
Showing 80 changed files with 2,256 additions and 11,441 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.vscode

.codegpt
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ project(HardwareDataLogger)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)



# Define the flag to choose between X86 and ARM headers
set(USE_X86_HEADERS TRUE) # Set this to TRUE for X86, FALSE for ARM

set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -pg")

add_subdirectory(Software/STM32F103RBTx/Application)
add_subdirectory(Simulation/FirmwarePCSimulator/STM32F103RBTx)
add_subdirectory(Simulation/FirmwarePCSimulator/ESP8266)
add_subdirectory(Test/Unit)

# Include the DevOps scripts (static code analysis, etc.)
include(DevOps/Cmake/CStaticAnalysis.cmake)
include(DevOps/Cmake/PythonStaticAnalysis.cmake)
Expand Down
9 changes: 5 additions & 4 deletions DevOps/Cmake/CStaticAnalysis.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ endif()

# Define the source directories to analyze
set(CODECHECKER_SOURCE_DIRS
${CMAKE_SOURCE_DIR}/Software/STM32F103RBTx/Application/
${CMAKE_SOURCE_DIR}/Software/STM32F103RBTx/Application
${CMAKE_SOURCE_DIR}/Software/ESP8266
${CMAKE_SOURCE_DIR}../Test/Unit/
${CMAKE_SOURCE_DIR}../Simulation/FirmwarePCSimulator/ESP8266/
${CMAKE_SOURCE_DIR}../Simulation/FirmwarePCSimulator/STM32F103RBTx/
${CMAKE_SOURCE_DIR}/Software/Common
${CMAKE_SOURCE_DIR}../Test/Unit
${CMAKE_SOURCE_DIR}../Simulation/FirmwarePCSimulator
${CMAKE_SOURCE_DIR}../Simulation/FirmwarePCSimulator
)

# Define the output directories for CodeChecker analysis and reports
Expand Down
41 changes: 7 additions & 34 deletions Simulation/FirmwarePCSimulator/ESP8266/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,23 @@ project(SimulatorESP8266 LANGUAGES C CXX)
# Enable position-independent code for compatibility with shared libraries
set(CMAKE_POSITION_INDEPENDENT_CODE ON)


#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++")


# Include directories scoped to each target
set(INCLUDE_DIRS
BEFORE # The BEFORE keyword ensures that these directories are prioritized over the system's include paths.


#${CMAKE_SOURCE_DIR}/Software/STM32F103RBTx/Middlewares/Third_Party/u8g2/csrc
#${CMAKE_SOURCE_DIR}/Software/STM32F103RBTx/Core/Inc
#${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/STM32F103RBTx/Application/Driver/Inc
# ${CMAKE_SOURCE_DIR}/Software/ESP8266/.pio/libdeps/huzzah/PubSubClient/src
${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/

${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/Mocks/Inc/
#${CMAKE_SOURCE_DIR}/Software/ESP8266/.pio/libdeps/huzzah/PubSubClient/src

# ${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/framework-arduinoespressif8266/cores/esp8266/
# ${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/framework-arduinoespressif8266/tools/sdk/include/
# ${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/framework-arduinoespressif8266/variants/adafruit
# ${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/framework-arduinoespressif8266/tools/sdk/lwip2/include/
# ${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/
# ${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/toolchain-xtensa/xtensa-lx106-elf/include/








${CMAKE_SOURCE_DIR}/Software/ESP8266/lib/Device/src
${CMAKE_SOURCE_DIR}/Software/Common
${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266
${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/Mocks/Inc
)

file(GLOB SIMULATOR_MAIN_SRC
"${CMAKE_SOURCE_DIR}/Software/ESP8266/src/*.cpp"
"${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/*.cpp"
"${CMAKE_SOURCE_DIR}/Software/ESP8266/lib/Device/src/*.cpp"
"${CMAKE_SOURCE_DIR}/Software/Common/*.cpp"
"${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/*.cpp"
"${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/ESP8266/Mocks/Src/*.cpp"
# "${CMAKE_SOURCE_DIR}/Software/ESP8266/.pio/libdeps/huzzah/PubSubClient/src/*.cpp"

)


# Define DriverForSimulation as a shared library
add_library(MainSource SHARED ${SIMULATOR_MAIN_SRC})
target_include_directories(MainSource PRIVATE ${INCLUDE_DIRS})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ namespace Driver
{
serialTx(data, size, timeout);

for (std::size_t i = 0u; i < size; i++)
{
printf("UartDriverStub::transmit TX %d \n", (char)data[i]);
}
printf("\n");
/* for (std::size_t i = 0u; i < size; i++)
{
printf("UartDriverStub::transmit TX %d \n", (char)data[i]);
}
printf("\n");*/
}

return UartExchangeStatus::Ok;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ set(INCLUDE_DIRS
${CMAKE_SOURCE_DIR}/Software/STM32F103RBTx/Middlewares/Third_Party/u8g2/cppsrc
${CMAKE_SOURCE_DIR}/Software/STM32F103RBTx/Middlewares/Third_Party/u8g2/csrc
${CMAKE_SOURCE_DIR}/Software/STM32F103RBTx/Core/Inc
${CMAKE_SOURCE_DIR}/Software/Common
${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/STM32F103RBTx/Application/Driver/Inc
${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/STM32F103RBTx/System/
${CMAKE_SOURCE_DIR}/Simulation/FirmwarePCSimulator/STM32F103RBTx/
Expand Down
22 changes: 10 additions & 12 deletions Simulation/FirmwarePCSimulator/STM32F103RBTx/device_under_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from typing import List, Callable



class SimulationKey(Enum):

"""Enumeration for simulation key events."""
Expand Down Expand Up @@ -42,7 +41,6 @@ def __init__(self) -> None:
+ os.path.sep + dll_name
)
self.dut: ctypes.CDLL = ctypes.CDLL(dll_abs_path)

self._serial_tx_callback_c = None

def init(self) -> None:
Expand Down Expand Up @@ -141,21 +139,21 @@ def register_serial_tx_callback(self, callback: Callable[[List[int], int, int],
The function should return an integer (`HAL_StatusTypeDef`).
"""
# Define the C-compatible callback type
# C: typedef int (*SerialTxCallback)(const uint8_t*, uint16_t, uint32_t);
SerialTxCallbackType = ctypes.CFUNCTYPE(
ctypes.c_int, # return type
ctypes.POINTER(ctypes.c_uint8), # const uint8_t* pData
ctypes.c_uint16, # uint16_t size
ctypes.c_uint32 # uint32_t timeout
# C: typedef int (*serial_tx_callback_type)(const uint8_t*, uint16_t, uint32_t);
serial_tx_callback_type = ctypes.CFUNCTYPE(
ctypes.c_int, # return type
ctypes.POINTER(ctypes.c_uint8), # const uint8_t* pdata
ctypes.c_uint16, # uint16_t size
ctypes.c_uint32 # uint32_t timeout
)

self.dut.LibWrapper_RegisterSerialTxCallback.argtypes = [SerialTxCallbackType]
self.dut.LibWrapper_RegisterSerialTxCallback.argtypes = [serial_tx_callback_type]
self.dut.LibWrapper_RegisterSerialTxCallback.restype = None

# Wrap the Python callback
def wrapper(pData, size, timeout):
data = [pData[i] for i in range(size)] # Convert to Python list
def wrapper(p_data, size, timeout):
data = [p_data[i] for i in range(size)] # Convert to Python list
return callback(data, size, timeout)

self._serial_tx_callback_c = SerialTxCallbackType(wrapper)
self._serial_tx_callback_c = serial_tx_callback_type(wrapper)
self.dut.LibWrapper_RegisterSerialTxCallback(self._serial_tx_callback_c)
57 changes: 9 additions & 48 deletions Simulation/FirmwarePCSimulator/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

import threading
import time
import datetime
import random
from typing import Tuple
from enum import Enum

Expand All @@ -21,11 +19,7 @@

class SimulationKey(Enum):

"""
Enumeration for simulation key events.
Defines key mappings for UP, DOWN, LEFT, and RIGHT keys.
"""
"""Enumeration for simulation key events."""

UP = 0
DOWN = 1
Expand All @@ -35,11 +29,7 @@ class SimulationKey(Enum):

class GPIOID(Enum):

"""
Enumeration for GPIO identifiers.
Maps GPIO pins to their corresponding identifiers.
"""
"""Enumeration for GPIO identifiers."""

GPIO1 = 13
GPIO2 = 2
Expand All @@ -48,15 +38,7 @@ class GPIOID(Enum):

class Simulation:

"""
Simulation class manages the interaction between STM32 and ESP8266 simulations.
This class provides methods to initialize, control, and interact with
the device-under-test (DUT) simulations. It handles tasks such as
starting and stopping the firmware, managing periodic ticks, updating
pulse counters, and retrieving display information. The class also
facilitates communication via UART and GPIO callbacks.
"""
"""Simulation class manages the interaction between STM32 and ESP8266 simulations."""

def __init__(self):
"""
Expand Down Expand Up @@ -98,7 +80,7 @@ def start_firmware(self) -> None:
self.esp8266.register_uart0_tx_callback(self.esp8266_uart0_tx_callback)
self.esp8266.register_gpio_state_callback(self.my_gpio_state_callback)

self.stm32.register_serial_tx_callback(self.STM32F103RBTx_uart_tx_callback)
self.stm32.register_serial_tx_callback(self.stm32_uart_tx_callback)

self.stm32.init()
self.esp8266.init()
Expand All @@ -121,11 +103,7 @@ def reload_firmware(self) -> None:
self.start_firmware()

def update_pulse_counters(self, values) -> None:
"""
Update the pulse counters in the STM32 simulation.
:param values: List of pulse counter values.
"""
"""Update the pulse counters in the STM32 simulation."""
self.stm32.update_pulse_counters(values)

def get_display_width(self) -> int:
Expand Down Expand Up @@ -154,21 +132,8 @@ def _run_periodic_tick(self) -> None:
This internal method handles periodic updates to simulate device behavior.
"""
while not self._stop_event.is_set():
"""timestamp = datetime.datetime.now().isoformat(timespec='seconds') + 'Z'
value = round(random.uniform(0.0, 10.0), 2)
data_string = f'MEAS:VOLT:DATA "{timestamp},{value}"'
data_bytes = list(data_string.encode('ascii'))
data_to_send = [len(data_bytes)] + data_bytes
size = len(data_to_send)
timeout = 1000
self.esp8266.uart0_tx(data_to_send, size, timeout)
"""

self.stm32.tick()
self.esp8266.tick()

time.sleep(self.tick_interval)

def _convert_rgb565_to_rgb8(self, rgb565: int) -> Tuple[int, int, int]:
Expand All @@ -191,21 +156,17 @@ def key_released(self, key: SimulationKey):
"""Notify the STM32 simulation of a key release event."""
self.stm32.key_released(key)

def STM32F103RBTx_uart_tx_callback(self, data: list, size: int, timeout: int) -> int:
def stm32_uart_tx_callback(self, data: list, size: int, timeout: int) -> int:
"""
Callback function for STM32F103RBTx UART transmission.
Print the data transmitted from STM32F103RBTx UART and send it to ESP8266.
This callback prints the data being transmitted.
:param data: List of integers representing the transmitted bytes.
:param size: Number of bytes transmitted.
:param timeout: Timeout in milliseconds.
:return: Always returns 0 (HAL_OK) for success.
"""
data_string = ''.join(map(chr, data)) # Convert byte list to string
print(f"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@UART TX Callback: Transmitting data: '{data_string}', Size: {size}, Timeout: {timeout}")

print(f"UART TX Callback: Transmitting data: '{data_string}', Size: {size}, Timeout: {timeout}")

self.esp8266.uart0_tx(data, size, timeout)


return 0 # HAL_OK equivalent
return 0 # HAL_OK equivalent
99 changes: 99 additions & 0 deletions Software/Common/CobsEncoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "CobsEncoder.hpp"
#include <cstdint>

namespace Device
{
std::size_t CobsEncoder::encode(const std::uint8_t *input,
std::size_t length,
std::uint8_t *output,
std::size_t maxOutputLength)
{
if (input == nullptr || output == nullptr || length == 0 || maxOutputLength < length + 1)
{
return 0; // Invalid input or insufficient output buffer size
}

std::size_t writeIndex = 0; // Position to write in the output
std::size_t readIndex = 0; // Position to read in the input
std::size_t codeIndex = 0; // Position of the code byte in the output
std::uint8_t code = 1; // Initialize the code byte

output[writeIndex++] = 0; // Placeholder for the code byte

while (readIndex < length)
{
if (input[readIndex] == 0)
{
// Write the code byte to its position
output[codeIndex] = code;

// Update the code byte's position and reset code
codeIndex = writeIndex++;
code = 1;
}
else
{
// Copy non-zero byte to the output
output[writeIndex++] = input[readIndex];
code++;

// If code reaches the max value (255), write it and reset
if (code == 0xFF)
{
output[codeIndex] = code;
codeIndex = writeIndex++;
code = 1;
}
}

readIndex++;
}

// Write the final code byte
output[codeIndex] = code;

// Return the total number of bytes written
return writeIndex;
}

std::size_t CobsEncoder::decode(const uint8_t *input, std::size_t length,
uint8_t *output, std::size_t maxOutputLength)
{
if (input == nullptr || output == nullptr || length == 0 || maxOutputLength < length - 1)
{
return 0; // Invalid input or insufficient output buffer size
}

std::size_t readIndex = 0; // Position to read in the input
std::size_t writeIndex = 0; // Position to write in the output

while (readIndex < length)
{
std::uint8_t code = input[readIndex++];

if (code == 0 || readIndex + code - 1 > length)
{
return 0; // Malformed input
}

for (std::uint8_t i = 1; i < code; ++i)
{
if (writeIndex >= maxOutputLength)
{
return 0; // Output buffer overflow
}

output[writeIndex++] = input[readIndex++];
}

if (code < 0xFF && writeIndex < maxOutputLength)
{
// Insert a zero if the code is less than 0xFF
output[writeIndex++] = 0;
}
}

// Return the total number of bytes written
return writeIndex;
}
}
Loading

0 comments on commit ee4de5d

Please sign in to comment.