Skip to content

Commit 12250a3

Browse files
author
Kinin-Code-Offical
committed
Add binary, hex, and EEPROM files for TestSketch with bootloader
- Added TestSketch.ino.with_bootloader.bin containing the compiled binary with bootloader. - Added TestSketch.ino.with_bootloader.hex containing the hex representation of the compiled sketch. - Added ArduinoUno.bin for EEPROM data storage. backup
1 parent 62529d6 commit 12250a3

File tree

148 files changed

+22601
-2230
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+22601
-2230
lines changed

CoreSim/src/RobotTwin.CoreSim/IPC/FirmwareClient.cs

Lines changed: 359 additions & 15 deletions
Large diffs are not rendered by default.

CoreSim/src/RobotTwin.CoreSim/IPC/FirmwareProtocol.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ internal static class FirmwareProtocol
77
{
88
internal const uint ProtocolMagic = 0x57465452; // "RTFW"
99
internal const ushort ProtocolMajor = 1;
10-
internal const ushort ProtocolMinor = 1;
10+
internal const ushort ProtocolMinor = 3;
1111
internal const int HeaderSize = 20;
1212
internal const uint MaxPayloadBytes = 8 * 1024 * 1024;
1313

Directory.Build.props

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Project>
2+
<PropertyGroup>
3+
<BaseOutputPath>$(MSBuildThisFileDirectory)builds\$(MSBuildProjectName)\</BaseOutputPath>
4+
<BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)builds\$(MSBuildProjectName)\obj\</BaseIntermediateOutputPath>
5+
<DefaultItemExcludes>$(DefaultItemExcludes);**\bin\**;**\obj\**</DefaultItemExcludes>
6+
</PropertyGroup>
7+
</Project>

FirmwareEngine/CMakeLists.txt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ set(SOURCES
1616
"${REPO_ROOT}/FirmwareEngine/Rpi/RpiBackend.cpp"
1717
"${REPO_ROOT}/FirmwareEngine/Rpi/RpiShm.cpp"
1818
"${REPO_ROOT}/FirmwareEngine/Rpi/QemuProcess.cpp"
19-
"${REPO_ROOT}/FirmwareEngine/U1/U1.cpp"
19+
# "${REPO_ROOT}/FirmwareEngine/U1/U1.cpp" # Removed for Real Sim
2020
"${REPO_ROOT}/NativeEngine/src/MCU/ATmega328P_ISA.c"
2121
)
2222

2323
add_executable(RoboTwinFirmwareHost ${SOURCES})
2424
target_include_directories(RoboTwinFirmwareHost PRIVATE
2525
"${REPO_ROOT}/FirmwareEngine"
2626
"${REPO_ROOT}/FirmwareEngine/include"
27-
"${REPO_ROOT}/FirmwareEngine/U1"
27+
# "${REPO_ROOT}/FirmwareEngine/U1" # Removed for Real Sim
2828
"${REPO_ROOT}/FirmwareEngine/Rpi"
2929
"${REPO_ROOT}/NativeEngine/include"
3030
)
@@ -48,3 +48,13 @@ target_include_directories(RoboTwinFirmwareHostLockstepSanity PRIVATE
4848
set_target_properties(RoboTwinFirmwareHostLockstepSanity PROPERTIES
4949
RUNTIME_OUTPUT_DIRECTORY "${OUT_DIR}"
5050
)
51+
52+
add_executable(SketchRunner
53+
"${REPO_ROOT}/FirmwareEngine/tests/SketchRunner.cpp"
54+
)
55+
target_include_directories(SketchRunner PRIVATE
56+
"${REPO_ROOT}/FirmwareEngine"
57+
)
58+
set_target_properties(SketchRunner PROPERTIES
59+
RUNTIME_OUTPUT_DIRECTORY "${OUT_DIR}"
60+
)

FirmwareEngine/PipeManager.cpp

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,67 @@
44
#include <cstring>
55
#include <cstdlib>
66
#include <thread>
7+
#include <sddl.h>
8+
9+
#pragma comment(lib, "Advapi32.lib")
710

811
namespace firmware
912
{
1013
namespace
1114
{
15+
void WriteBits(std::uint8_t *dst, std::size_t dstBits, std::size_t offset, std::size_t width, std::uint64_t value)
16+
{
17+
if (!dst || width == 0)
18+
return;
19+
if (offset + width > dstBits)
20+
return;
21+
for (std::size_t bit = 0; bit < width; ++bit)
22+
{
23+
std::size_t target = offset + bit;
24+
std::size_t byteIndex = target / 8;
25+
std::size_t bitIndex = target % 8;
26+
if ((value >> bit) & 0x1u)
27+
{
28+
dst[byteIndex] = static_cast<std::uint8_t>(dst[byteIndex] | (1u << bitIndex));
29+
}
30+
}
31+
}
32+
33+
void WriteDebugBits(std::uint8_t *dst, std::size_t dstBytes, const OutputDebugState &debug)
34+
{
35+
if (!dst || dstBytes < kDebugBitBytes)
36+
return;
37+
std::memset(dst, 0, dstBytes);
38+
const std::size_t dstBits = dstBytes * 8;
39+
WriteBits(dst, dstBits, kDbgBitPc, 16, debug.pc);
40+
WriteBits(dst, dstBits, kDbgBitSp, 16, debug.sp);
41+
WriteBits(dst, dstBits, kDbgBitSreg, 8, debug.sreg);
42+
WriteBits(dst, dstBits, kDbgBitFlashBytes, 32, debug.flashBytes);
43+
WriteBits(dst, dstBits, kDbgBitSramBytes, 32, debug.sramBytes);
44+
WriteBits(dst, dstBits, kDbgBitEepromBytes, 32, debug.eepromBytes);
45+
WriteBits(dst, dstBits, kDbgBitIoBytes, 32, debug.ioBytes);
46+
WriteBits(dst, dstBits, kDbgBitCpuHz, 32, debug.cpuHz);
47+
WriteBits(dst, dstBits, kDbgBitStackHighWater, 16, debug.stackHighWater);
48+
WriteBits(dst, dstBits, kDbgBitHeapTop, 16, debug.heapTopAddress);
49+
WriteBits(dst, dstBits, kDbgBitStackMin, 16, debug.stackMinAddress);
50+
WriteBits(dst, dstBits, kDbgBitDataSegmentEnd, 16, debug.dataSegmentEnd);
51+
WriteBits(dst, dstBits, kDbgBitStackOverflows, 32, static_cast<std::uint32_t>(debug.stackOverflows));
52+
WriteBits(dst, dstBits, kDbgBitInvalidMem, 32, static_cast<std::uint32_t>(debug.invalidMemoryAccesses));
53+
WriteBits(dst, dstBits, kDbgBitInterruptCount, 32, static_cast<std::uint32_t>(debug.interruptCount));
54+
WriteBits(dst, dstBits, kDbgBitInterruptLatencyMax, 32, static_cast<std::uint32_t>(debug.interruptLatencyMax));
55+
WriteBits(dst, dstBits, kDbgBitTimingViolations, 32, static_cast<std::uint32_t>(debug.timingViolations));
56+
WriteBits(dst, dstBits, kDbgBitCriticalSectionCycles, 32, static_cast<std::uint32_t>(debug.criticalSectionCycles));
57+
WriteBits(dst, dstBits, kDbgBitSleepCycles, 32, static_cast<std::uint32_t>(debug.sleepCycles));
58+
WriteBits(dst, dstBits, kDbgBitFlashAccessCycles, 32, static_cast<std::uint32_t>(debug.flashAccessCycles));
59+
WriteBits(dst, dstBits, kDbgBitUartOverflows, 32, static_cast<std::uint32_t>(debug.uartOverflows));
60+
WriteBits(dst, dstBits, kDbgBitTimerOverflows, 32, static_cast<std::uint32_t>(debug.timerOverflows));
61+
WriteBits(dst, dstBits, kDbgBitBrownOutResets, 32, static_cast<std::uint32_t>(debug.brownOutResets));
62+
WriteBits(dst, dstBits, kDbgBitGpioStateChanges, 32, static_cast<std::uint32_t>(debug.gpioStateChanges));
63+
WriteBits(dst, dstBits, kDbgBitPwmCycles, 32, static_cast<std::uint32_t>(debug.pwmCycles));
64+
WriteBits(dst, dstBits, kDbgBitI2cTransactions, 32, static_cast<std::uint32_t>(debug.i2cTransactions));
65+
WriteBits(dst, dstBits, kDbgBitSpiTransactions, 32, static_cast<std::uint32_t>(debug.spiTransactions));
66+
}
67+
1268
bool LockstepTraceEnabled()
1369
{
1470
static const bool enabled = []()
@@ -138,13 +194,19 @@ namespace firmware
138194
payload.pin_count = static_cast<std::uint32_t>(kPinCount);
139195
payload.board_id_size = static_cast<std::uint32_t>(kBoardIdSize);
140196
payload.analog_count = static_cast<std::uint32_t>(kAnalogCount);
197+
payload.flash_bytes = 0;
198+
payload.sram_bytes = 0;
199+
payload.eeprom_bytes = 0;
200+
payload.io_bytes = 0;
201+
payload.cpu_hz = 0;
141202
WritePacket(MessageType::HelloAck, reinterpret_cast<const std::uint8_t *>(&payload), sizeof(payload));
142203
}
143204

144205
bool PipeManager::SendOutputState(const std::string &boardId, std::uint64_t stepSequence, std::uint64_t tickCount, const std::uint8_t *pins, std::size_t count,
145206
std::uint64_t cycles, std::uint64_t adcSamples,
146207
const std::uint64_t *uartTxBytes, const std::uint64_t *uartRxBytes,
147-
std::uint64_t spiTransfers, std::uint64_t twiTransfers, std::uint64_t wdtResets)
208+
std::uint64_t spiTransfers, std::uint64_t twiTransfers, std::uint64_t wdtResets,
209+
const OutputDebugState &debug)
148210
{
149211
if (!pins || count < kPinCount)
150212
return false;
@@ -167,6 +229,36 @@ namespace firmware
167229
payload.twi_transfers = twiTransfers;
168230
payload.wdt_resets = wdtResets;
169231
payload.timestamp_micros = NowMicros();
232+
payload.flash_bytes = debug.flashBytes;
233+
payload.sram_bytes = debug.sramBytes;
234+
payload.eeprom_bytes = debug.eepromBytes;
235+
payload.io_bytes = debug.ioBytes;
236+
payload.cpu_hz = debug.cpuHz;
237+
payload.pc = debug.pc;
238+
payload.sp = debug.sp;
239+
payload.sreg = debug.sreg;
240+
payload.stack_high_water = debug.stackHighWater;
241+
payload.heap_top_address = debug.heapTopAddress;
242+
payload.stack_min_address = debug.stackMinAddress;
243+
payload.data_segment_end = debug.dataSegmentEnd;
244+
payload.stack_overflows = debug.stackOverflows;
245+
payload.invalid_memory_accesses = debug.invalidMemoryAccesses;
246+
payload.interrupt_count = debug.interruptCount;
247+
payload.interrupt_latency_max = debug.interruptLatencyMax;
248+
payload.timing_violations = debug.timingViolations;
249+
payload.critical_section_cycles = debug.criticalSectionCycles;
250+
payload.sleep_cycles = debug.sleepCycles;
251+
payload.flash_access_cycles = debug.flashAccessCycles;
252+
payload.uart_overflows = debug.uartOverflows;
253+
payload.timer_overflows = debug.timerOverflows;
254+
payload.brown_out_resets = debug.brownOutResets;
255+
payload.gpio_state_changes = debug.gpioStateChanges;
256+
payload.pwm_cycles = debug.pwmCycles;
257+
payload.i2c_transactions = debug.i2cTransactions;
258+
payload.spi_transactions = debug.spiTransactions;
259+
payload.debug_bit_count = kDebugBitCount;
260+
payload.reserved1 = 0;
261+
WriteDebugBits(payload.debug_bits, sizeof(payload.debug_bits), debug);
170262

171263
if (LockstepTraceEnabled())
172264
{
@@ -304,6 +396,30 @@ namespace firmware
304396
Enqueue(cmd);
305397
continue;
306398
}
399+
400+
if (type == MessageType::MemoryPatch)
401+
{
402+
if (payload.size() < sizeof(MemoryPatchHeader))
403+
{
404+
SendError("system", 2, "Invalid patch payload");
405+
continue;
406+
}
407+
const auto *header = reinterpret_cast<const MemoryPatchHeader *>(payload.data());
408+
std::size_t expected = sizeof(MemoryPatchHeader) + header->length;
409+
if (payload.size() < expected)
410+
{
411+
SendError("system", 2, "Patch payload truncated");
412+
continue;
413+
}
414+
PipeCommand cmd;
415+
cmd.type = PipeCommand::Type::Patch;
416+
cmd.boardId = ReadFixedString(header->board_id, kBoardIdSize);
417+
cmd.memoryType = static_cast<MemoryType>(header->memory_type);
418+
cmd.address = header->address;
419+
cmd.data.assign(payload.begin() + sizeof(MemoryPatchHeader), payload.begin() + expected);
420+
Enqueue(cmd);
421+
continue;
422+
}
307423
}
308424
}
309425

@@ -317,6 +433,15 @@ namespace firmware
317433
_pipeHandle = INVALID_HANDLE_VALUE;
318434
}
319435

436+
SECURITY_ATTRIBUTES attrs{};
437+
attrs.nLength = sizeof(attrs);
438+
attrs.bInheritHandle = FALSE;
439+
PSECURITY_DESCRIPTOR security = nullptr;
440+
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(L"D:(A;;GA;;;WD)", SDDL_REVISION_1, &security, nullptr))
441+
{
442+
attrs.lpSecurityDescriptor = security;
443+
}
444+
320445
_pipeHandle = CreateNamedPipeW(
321446
_pipeName.c_str(),
322447
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
@@ -325,7 +450,12 @@ namespace firmware
325450
65536,
326451
65536,
327452
0,
328-
nullptr);
453+
security ? &attrs : nullptr);
454+
455+
if (security)
456+
{
457+
LocalFree(security);
458+
}
329459

330460
if (_pipeHandle == INVALID_HANDLE_VALUE)
331461
{

FirmwareEngine/PipeManager.h

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ namespace firmware
1717
enum class Type
1818
{
1919
Load,
20-
Step
20+
Step,
21+
Patch
2122
};
2223

2324
Type type = Type::Load;
@@ -30,6 +31,39 @@ namespace firmware
3031
std::uint8_t pins[kPinCount]{};
3132
std::uint16_t analog[kAnalogCount]{};
3233
std::size_t analogCount = 0;
34+
MemoryType memoryType = MemoryType::Flash;
35+
std::uint32_t address = 0;
36+
};
37+
38+
struct OutputDebugState
39+
{
40+
std::uint32_t flashBytes = 0;
41+
std::uint32_t sramBytes = 0;
42+
std::uint32_t eepromBytes = 0;
43+
std::uint32_t ioBytes = 0;
44+
std::uint32_t cpuHz = 0;
45+
std::uint16_t pc = 0;
46+
std::uint16_t sp = 0;
47+
std::uint8_t sreg = 0;
48+
std::uint16_t stackHighWater = 0;
49+
std::uint16_t heapTopAddress = 0;
50+
std::uint16_t stackMinAddress = 0;
51+
std::uint16_t dataSegmentEnd = 0;
52+
std::uint64_t stackOverflows = 0;
53+
std::uint64_t invalidMemoryAccesses = 0;
54+
std::uint64_t interruptCount = 0;
55+
std::uint64_t interruptLatencyMax = 0;
56+
std::uint64_t timingViolations = 0;
57+
std::uint64_t criticalSectionCycles = 0;
58+
std::uint64_t sleepCycles = 0;
59+
std::uint64_t flashAccessCycles = 0;
60+
std::uint64_t uartOverflows = 0;
61+
std::uint64_t timerOverflows = 0;
62+
std::uint64_t brownOutResets = 0;
63+
std::uint64_t gpioStateChanges = 0;
64+
std::uint64_t pwmCycles = 0;
65+
std::uint64_t i2cTransactions = 0;
66+
std::uint64_t spiTransactions = 0;
3367
};
3468

3569
class PipeManager
@@ -49,7 +83,8 @@ namespace firmware
4983
bool SendOutputState(const std::string &boardId, std::uint64_t stepSequence, std::uint64_t tickCount, const std::uint8_t *pins, std::size_t count,
5084
std::uint64_t cycles, std::uint64_t adcSamples,
5185
const std::uint64_t *uartTxBytes, const std::uint64_t *uartRxBytes,
52-
std::uint64_t spiTransfers, std::uint64_t twiTransfers, std::uint64_t wdtResets);
86+
std::uint64_t spiTransfers, std::uint64_t twiTransfers, std::uint64_t wdtResets,
87+
const OutputDebugState &debug);
5388
void SendSerial(const std::string &boardId, const std::uint8_t *data, std::size_t size);
5489
void SendStatus(const std::string &boardId, std::uint64_t tickCount);
5590
void SendLog(const std::string &boardId, LogLevel level, const std::string &text);

0 commit comments

Comments
 (0)