Skip to content

Commit 44e5150

Browse files
committed
Added Lab2a which shows usage of renode for running unit tests on stm32.
1 parent b1848c9 commit 44e5150

14 files changed

Lines changed: 4315 additions & 0 deletions

File tree

Lab2a/Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
TARGET = Lab3
2+
CC = arm-none-eabi-gcc
3+
4+
CFLAGS = -mcpu=cortex-m4 -mthumb \
5+
-O0 -g \
6+
-ffreestanding -fno-builtin\
7+
-Isrc -Iunity -Istm32f4 \
8+
-Wall -Wextra
9+
10+
LDFLAGS = -T stm32f4/linker.ld \
11+
-nostartfiles \
12+
-Wl,--gc-sections
13+
14+
SRC = \
15+
stm32f4/startup.c \
16+
stm32f4/uart.c \
17+
src/checksum.c \
18+
src/test_checksum.c \
19+
src/syscalls.c \
20+
unity/unity.c
21+
22+
.PHONY: all clean run coverage
23+
24+
all:
25+
$(CC) $(CFLAGS) $(SRC) $(LDFLAGS) -o $(TARGET).elf
26+
27+
clean:
28+
rm -f *.elf
29+
30+
run: clean all
31+
renode --disable-xwt renode/stm32.resc

Lab2a/renode/stm32.resc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
mach create
2+
machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl
3+
4+
sysbus LoadELF @Lab3.elf
5+
showAnalyzer sysbus.usart2
6+
7+
start
8+
9+
sleep 10
10+
quit

Lab2a/src/checksum.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "checksum.h"
2+
#include <stddef.h>
3+
4+
uint8_t calculate_checksum(uint8_t *buffer, uint8_t buffer_length)
5+
{
6+
if (buffer == NULL || buffer_length == 0) {
7+
return 0; // Return 0 for null buffer or zero length
8+
}
9+
10+
uint16_t result_checksum = 0;
11+
uint8_t loop_index = 0;
12+
13+
for (loop_index = 0; loop_index < buffer_length; loop_index ++)
14+
{
15+
result_checksum += buffer[loop_index ];
16+
}
17+
return (uint8_t)(result_checksum % 256);
18+
}

Lab2a/src/checksum.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @file checksum.h
3+
* @brief Header file contains the declarations for checksum module
4+
*
5+
*/
6+
7+
#ifndef CHECKSUM_H
8+
#define CHECKSUM_H
9+
10+
#include <stdint.h>
11+
12+
/**
13+
* @brief Function to calculate the checksum of a given buffer of data.
14+
* The checksum is computed by summing all the bytes in the buffer and taking the result modulo 256.
15+
*
16+
* @param buffer Buffer of data for which the checksum is to be calculated.
17+
* @param length Length of the buffer.
18+
* @return uint8_t The calculated checksum result.
19+
*/
20+
uint8_t calculate_checksum(uint8_t *buffer, uint8_t length);
21+
22+
#endif

Lab2a/src/syscalls.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <sys/stat.h>
2+
3+
/* Stub implementations of system calls for a bare-metal environment.
4+
These functions are required by the C library but are not used in this context.
5+
*/
6+
int _close(int file)
7+
{
8+
(void)file;
9+
return -1;
10+
}
11+
12+
int _fstat(int file, struct stat *st)
13+
{
14+
(void)file;
15+
st->st_mode = S_IFCHR;
16+
return 0;
17+
}
18+
19+
int _isatty(int file)
20+
{
21+
(void)file;
22+
return 1;
23+
}
24+
25+
int _lseek(int file, int ptr, int dir)
26+
{
27+
(void)file;
28+
(void)ptr;
29+
(void)dir;
30+
return 0;
31+
}
32+
33+
int _read(int file, char *ptr, int len)
34+
{
35+
(void)file;
36+
(void)ptr;
37+
(void)len;
38+
return 0;
39+
}
40+
41+
int _write(int file, char *ptr, int len)
42+
{
43+
(void)file;
44+
(void)ptr;
45+
return len;
46+
}
47+
48+
int _kill(int pid, int sig)
49+
{
50+
(void)pid;
51+
(void)sig;
52+
return -1;
53+
}
54+
55+
int _getpid(void)
56+
{
57+
return 1;
58+
}

Lab2a/src/test_checksum.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include "checksum.h"
2+
#include "unity.h"
3+
#include "uart.h"
4+
5+
void setUp(void)
6+
{
7+
/* This function is called before each test case.
8+
You can use it to set up any common test data or state. */
9+
}
10+
11+
void tearDown(void)
12+
{
13+
/* This function is called after each test case.
14+
You can use it to clean up any resources allocated in setUp or during the test. */
15+
}
16+
17+
void test_calculate_checksum_with_valid_data(void) {
18+
uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
19+
uint8_t expected_checksum = 10; // (0x01 + 0x02 + 0x03 + 0x04) % 256 = 10
20+
uint8_t actual_checksum = calculate_checksum(data, sizeof(data));
21+
TEST_ASSERT_EQUAL_UINT8(expected_checksum, actual_checksum);
22+
}
23+
24+
void test_calculate_checksum_with_empty_data(void) {
25+
uint8_t data[] = {};
26+
uint8_t expected_checksum = 0;
27+
uint8_t actual_checksum = calculate_checksum(data, sizeof(data));
28+
TEST_ASSERT_EQUAL_UINT8(expected_checksum, actual_checksum);
29+
}
30+
31+
void test_calculate_checksum_with_max_values(void) {
32+
uint8_t data[] = {0xFF, 0xFF, 0xFF, 0xFF};
33+
uint8_t expected_checksum = 252; // (0xFF + 0xFF + 0xFF + 0xFF) % 256 = 252
34+
uint8_t actual_checksum = calculate_checksum(data, sizeof(data));
35+
TEST_ASSERT_EQUAL_UINT8(expected_checksum, actual_checksum);
36+
}
37+
38+
void test_calculate_checksum_with_null_buffer(void) {
39+
uint8_t *data = NULL;
40+
uint8_t expected_checksum = 0; // Null buffer should return 0
41+
uint8_t actual_checksum = calculate_checksum(data, 10); // Length is arbitrary since buffer is NULL
42+
TEST_ASSERT_EQUAL_UINT8(expected_checksum, actual_checksum);
43+
}
44+
45+
void test_calculate_checksum_with_zero_length(void) {
46+
uint8_t data[] = {0x01, 0x02, 0x03};
47+
uint8_t expected_checksum = 0; // Zero length should return 0
48+
uint8_t actual_checksum = calculate_checksum(data, 0);
49+
TEST_ASSERT_EQUAL_UINT8(expected_checksum, actual_checksum);
50+
}
51+
52+
void test_calculate_zero_checksum(void) {
53+
uint8_t data[] = {0x00, 0x00, 0x00, 0x00};
54+
uint8_t expected_checksum = 0; // All zeros should yield a checksum of 0
55+
uint8_t actual_checksum = calculate_checksum(data, sizeof(data));
56+
TEST_ASSERT_EQUAL_UINT8(expected_checksum, actual_checksum);
57+
}
58+
59+
int main(void) {
60+
61+
uart_init();
62+
uart_print("STM32F4 Unity Test Start\n");
63+
64+
UNITY_BEGIN();
65+
RUN_TEST(test_calculate_checksum_with_valid_data);
66+
RUN_TEST(test_calculate_checksum_with_empty_data);
67+
RUN_TEST(test_calculate_checksum_with_max_values);
68+
RUN_TEST(test_calculate_checksum_with_null_buffer);
69+
RUN_TEST(test_calculate_checksum_with_zero_length);
70+
RUN_TEST(test_calculate_zero_checksum);
71+
72+
int failures = UNITY_END();
73+
74+
if (failures == 0)
75+
uart_print("TEST_RESULT:PASS\n");
76+
else
77+
uart_print("TEST_RESULT:FAIL\n");
78+
79+
}
80+

Lab2a/stm32f4/linker.ld

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
ENTRY(Reset_Handler)
2+
3+
/* ===== Memory Regions ===== */
4+
5+
MEMORY
6+
{
7+
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1M
8+
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
9+
}
10+
11+
/* Initial stack pointer (top of RAM) */
12+
_estack = ORIGIN(RAM) + LENGTH(RAM);
13+
14+
/* ===== Sections ===== */
15+
16+
SECTIONS
17+
{
18+
/* ==== Interrupt Vector Table ==== */
19+
20+
.isr_vector :
21+
{
22+
KEEP(*(.isr_vector))
23+
} > FLASH
24+
25+
26+
/* ==== Code + Read-Only Data ==== */
27+
28+
.text :
29+
{
30+
*(.text*)
31+
*(.rodata*)
32+
KEEP(*(.init))
33+
KEEP(*(.fini))
34+
} > FLASH
35+
36+
37+
/* ==== ARM Exception Tables (required by GCC) ==== */
38+
39+
.ARM.extab :
40+
{
41+
*(.ARM.extab*)
42+
} > FLASH
43+
44+
.ARM.exidx :
45+
{
46+
__exidx_start = .;
47+
*(.ARM.exidx*)
48+
__exidx_end = .;
49+
} > FLASH
50+
51+
52+
/* Mark end of FLASH content */
53+
_etext = .;
54+
55+
56+
/* ==== Initialized Data (in RAM, loaded from FLASH) ==== */
57+
58+
.data : AT (_etext)
59+
{
60+
_sdata = .;
61+
*(.data*)
62+
_edata = .;
63+
} > RAM
64+
65+
66+
/* ==== Uninitialized Data ==== */
67+
68+
.bss :
69+
{
70+
_sbss = .;
71+
*(.bss*)
72+
*(COMMON)
73+
_ebss = .;
74+
} > RAM
75+
76+
77+
/* ==== Heap / End of RAM data ==== */
78+
79+
. = ALIGN(8);
80+
end = .;
81+
_end = .;
82+
83+
84+
/* Stack grows downward from _estack */
85+
}

Lab2a/stm32f4/startup.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <stdint.h>
2+
3+
/* ===== Linker Symbols ===== */
4+
extern uint32_t _estack;
5+
extern uint32_t _etext;
6+
extern uint32_t _sdata;
7+
extern uint32_t _edata;
8+
extern uint32_t _sbss;
9+
extern uint32_t _ebss;
10+
11+
int main(void);
12+
13+
/*
14+
* Reset Handler
15+
*/
16+
void Reset_Handler(void)
17+
{
18+
uint32_t *src = &_etext;
19+
uint32_t *dst = &_sdata;
20+
21+
/* Copy .data from FLASH to RAM */
22+
while (dst < &_edata)
23+
*dst++ = *src++;
24+
25+
/* Zero .bss */
26+
for (dst = &_sbss; dst < &_ebss; )
27+
*dst++ = 0;
28+
29+
main();
30+
31+
while (1);
32+
}
33+
34+
/*
35+
* Default Handler
36+
*/
37+
void Default_Handler(void)
38+
{
39+
while (1);
40+
}
41+
42+
/* Weak aliases for interrupts */
43+
void NMI_Handler(void) __attribute__((weak, alias("Default_Handler")));
44+
void HardFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
45+
void MemManage_Handler(void) __attribute__((weak, alias("Default_Handler")));
46+
void BusFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
47+
void UsageFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
48+
49+
/*
50+
* Interrupt Vector Table
51+
*/
52+
__attribute__((section(".isr_vector")))
53+
const void *vector_table[] =
54+
{
55+
&_estack, // Initial stack pointer
56+
Reset_Handler, // Reset
57+
NMI_Handler, // NMI Handler
58+
HardFault_Handler, // Hard Fault Handler
59+
MemManage_Handler, // Memory Management Fault Handler
60+
BusFault_Handler, // Bus Fault Handler
61+
UsageFault_Handler // Usage Fault Handler
62+
};

0 commit comments

Comments
 (0)