Hi,
I’ve been trying to use the BEEBS benchmarking programs to run on a CW308 with a STM32F3 target board mounted on it, and capture the power trace using a CW Husky. I’ve modified the programs CW, and was able to load the firmware, but I’m unable to capture the power using the capture script. I’m including the files I’ve used for reference. Any help, suggestion, advice would be greatly appreciated.
#Power Capture
#!/usr/bin/env python3
Script to load firmware, run benchmark, and capture traces
import chipwhisperer as cw
import time
import numpy as np
import matplotlib.pyplot as plt
def main():
try:
# Step 1: Connect to the ChipWhisperer Husky
scope = cw.scope()
print("Connected to ChipWhisperer Husky")
# Step 2: Setup scope parameters for capturing power traces
scope.gain.gain = 45
scope.adc.samples = 5000
scope.adc.offset = 0
scope.adc.basic_mode = "rising_edge"
scope.clock.clkgen_freq = 7370000 # 7.37 MHz
scope.clock.adc_src = "clkgen_x1"
scope.trigger.triggers = "tio4"
scope.io.tio1 = "serial_rx"
scope.io.tio2 = "serial_tx"
scope.io.tio4 = "gpio_high"
scope.io.hs2 = "clkgen"
# # Reset the target
# scope.io.nrst = 0
# time.sleep(0.1)
# scope.io.nrst = 1
# time.sleep(0.1)
# Arm the scope
scope.arm()
target = cw.target(scope)
# print(target)
print("Scope is armed")
print(f"Current trigger source: {scope.trigger.triggers}")
print(f"Current IO settings: TIO1={scope.io.tio1}, TIO2={scope.io.tio2}, TIO3={scope.io.tio3}, TIO4={scope.io.tio4}")
# Step 4: Capture the trace while running the benchmark
target.simpleserial_write('b', bytearray([0])) # Send 'b' command to run benchmark
print(target)
time.sleep(2)
trace = scope.get_last_trace()
if trace is None:
print("Failed to capture trace")
else:
# Display info about the trace
print(f"Captured trace of length: {len(trace)}")
# Plot the trace
plt.figure()
plt.plot(trace)
plt.title('Power Trace of Bubble Sort Algorithm')
plt.xlabel('Sample Number')
plt.ylabel('Power Consumption')
plt.grid()
plt.savefig('bubble_sort_trace.png')
plt.show()
# Save the trace data to a file
np.save('bubble_sort_trace.npy', trace)
# Disconnect
scope.dis()
print("Disconnected from ChipWhisperer")
except Exception as e:
print(f"Error: {e}")
if 'scope' in locals():
try:
scope.dis()
print("Disconnected from ChipWhisperer due to error")
except:
pass
if name == “main”:
main()
support.h
/* Modified support.h for STM32F3 with ChipWhisperer */
#ifndef SUPPORT_H
#define SUPPORT_H
#include <stdint.h>
// Define board repeat factor for benchmark
#define BOARD_REPEAT_FACTOR 4096
#define CALIB_SCALE 0
#define REPEAT_FACTOR ((BOARD_REPEAT_FACTOR) >> (CALIB_SCALE))
// Function declarations for board control
void initialise_board(void);
void start_trigger(void);
void stop_trigger(void);
// The benchmark function declaration
int benchmark(void) attribute ((noinline));
#endif /* SUPPORT_H */
board support.c
/* boardsupport.c for STM32F3 with ChipWhisperer */
#include “support.h”
#include <stdint.h>
// Include HAL for STM32F3
#include “…/…/firmware/mcu/hal/hal.h”
void initialise_board(void)
{
// Initialize any board-specific hardware
// This is handled by ChipWhisperer’s HAL initialization
}
void start_trigger(void)
{
// Set trigger high for power trace capture
trigger_high();
}
void stop_trigger(void)
{
// Set trigger low when operation completes
trigger_low();
}
bubble sort_mod.c
/* Modified bubbleSort_og.c for ChipWhisperer */
#include “support.h”
#include <stdint.h>
#include “…/…/firmware/mcu/hal/hal.h”
#include “…/…/firmware/mcu/simpleserial/simpleserial.h”
/* This scale factor will be changed to equalise the runtime of the
benchmarks. */
#define SCALE_FACTOR (REPEAT_FACTOR >> 4)
#define WORSTCASE 1
#define FALSE 0
#define TRUE 1
#define NUMELEMS 100
#define MAXDIM (NUMELEMS+1)
void Initialize(int Array);
void BubbleSort(int Array);
/* BUBBLESORT BENCHMARK PROGRAM */
int Array[MAXDIM], Seed;
int factor;
void BubbleSort(int Array);
void Initialize(int Array);
int benchmark(void)
{
Initialize(Array);
BubbleSort(Array);
return 0;
}
void Initialize(int Array)
{
int Index, fact;
#ifdef WORSTCASE
factor = -1;
#else
factor = 1;
#endif
fact = factor;
for (Index = 1; Index <= NUMELEMS; Index++)
Array[Index] = Index*fact;
}
void BubbleSort(int Array)
{
int Sorted = FALSE;
int Temp, Index, i;
for (i = 1; i <= NUMELEMS-1; i++)
{
Sorted = TRUE;
for (Index = 1; Index <= NUMELEMS-1; Index++) {
if (Index > NUMELEMS-i)
break;
if (Array[Index] > Array[Index + 1])
{
Temp = Array[Index];
Array[Index] = Array[Index+1];
Array[Index+1] = Temp;
Sorted = FALSE;
}
}
if (Sorted)
break;
}
}
// SimpleSerial command to run the benchmark
uint8_t run_benchmark(uint8_t* data, uint8_t len)
{
start_trigger();
// Run the benchmark multiple times for clearer power trace
for (int i = 0; i < SCALE_FACTOR; i++)
benchmark();
stop_trigger();
// Return success
return 0x00;
}
int main(void)
{
// Initialize ChipWhisperer platform
platform_init();
init_uart();
trigger_setup();
// Setup SimpleSerial communication
simpleserial_init();
// Register the benchmark command ('b')
simpleserial_addcmd('b', 0, run_benchmark);
// Main loop for SimpleSerial
while(1)
simpleserial_get();
return 0;
}
Makefile
Makefile for Bubble Sort Benchmark
For ChipWhisperer STM32F3 target
Target build name
TARGET = bubbleSort
Target platform
PLATFORM = CW308_STM32F3
Find ChipWhisperer firmware directory
FIRMWAREPATH = …/…/firmware/mcu
Name for simpleserial project
SS_VER = SS_VER_2_1
Source files
SRC += bubbleSort.c
SRC += boardsupport.c
Cryptographic options
CRYPTO_TARGET = NONE
CRYPTO_OPTIONS =
Include SimpleSerial Makefile
include $(FIRMWAREPATH)/simpleserial/Makefile.simpleserial
Include common firmware Makefile
include $(FIRMWAREPATH)/Makefile.inc