diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2020-11-24 13:46:41 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2020-11-24 13:46:41 -0700 |
commit | 93b063fedfcf7409a67df035170ea5670cad22e1 (patch) | |
tree | a23321a7465d966b1ccf196ca00e65a70c9f9110 /tests | |
parent | b040195d31df6ad759f16ea3456471897f55daa1 (diff) | |
download | stm32l4-93b063fedfcf7409a67df035170ea5670cad22e1.tar.gz stm32l4-93b063fedfcf7409a67df035170ea5670cad22e1.tar.bz2 stm32l4-93b063fedfcf7409a67df035170ea5670cad22e1.zip |
Moved action to top level.
Removed old iterations of the project and moved the files from 02-usart
to the root directory since that's the sole place where the action is
and that subproject has outgrown its initial title.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/metatest.c | 22 | ||||
-rw-r--r-- | tests/test_dma.c | 189 | ||||
-rw-r--r-- | tests/test_gpio.c | 194 | ||||
-rw-r--r-- | tests/test_irq.c | 43 | ||||
-rw-r--r-- | tests/test_lib.c | 21 | ||||
-rw-r--r-- | tests/test_memory.c | 378 | ||||
-rw-r--r-- | tests/test_spi.c | 11 | ||||
-rw-r--r-- | tests/test_usart.c | 22 |
8 files changed, 880 insertions, 0 deletions
diff --git a/tests/metatest.c b/tests/metatest.c new file mode 100644 index 0000000..1024156 --- /dev/null +++ b/tests/metatest.c @@ -0,0 +1,22 @@ +#include "test_harness.h" + +/* Tests the test harness itself. */ + +static int my_variable; +static int my_initialized_variable = 5; + +TEST(meta, clobbers_variables) +{ + my_variable = 6; + my_initialized_variable = 5; + + return 0; +} + +TEST(meta, variables_reset) +{ + ASSERT_EQ(my_variable, 0); + ASSERT_EQ(my_initialized_variable, 5); + + return 0; +} diff --git a/tests/test_dma.c b/tests/test_dma.c new file mode 100644 index 0000000..50cdb5b --- /dev/null +++ b/tests/test_dma.c @@ -0,0 +1,189 @@ +#include "test_harness.h" +#include "arch/stm32l4xxx/peripherals/dma.h" +#include "arch/stm32l4xxx/peripherals/rcc.h" +#include "arch/stm32l4xxx/peripherals/usart.h" +#include "kern/dma/dma_manager.h" + +#include <stdio.h> +#include <stdlib.h> +#include <memory.h> + +TEST(dma, smoke) +{ + dma_t* dma = &DMA1; + memset(dma, 0, sizeof(dma_t)); + + regset(dma->is_r, dma_tcif1, 1); + ASSERT_EQ(dma->is_r, 2); + + regset(dma->is_r, dma_htif7, 1); + ASSERT_EQ(dma->is_r, 67108866); + return 0; +} + +TEST(dma, cc_regset) +{ + dma_t* dma = &DMA1; + memset(dma, 0, sizeof(dma_t)); + + dma_channel_config_t* channel_config = &dma->channel_config[2]; + regset(channel_config->cc_r, dma_cc_msize, DMA_SIZE_32_BITS); + + ASSERT_EQ(channel_config->cc_r, 1 << 11); + return 0; +} + +TEST(dma, correct_align) +{ + dma_t dma; + + // Assert the DMA registers are aligned with what the spec says. + ASSERT_EQ((long)(&dma.csel_r) - (long)(&dma), 0xA8); + + return 0; +} + +TEST(dma, regset_pl) +{ + uint32_t reg = 0; + + regset(reg, dma_cc_pl, DMA_PRIORITY_LEVEL_MEDIUM); + + ASSERT_EQ(reg, (1 << 12)); + + ASSERT_EQ( + regget(reg, dma_cc_pl), + DMA_PRIORITY_LEVEL_MEDIUM); + return 0; +} + +TEST(dma_peri, select_peripheral) +{ + dma_opts_t opts = DEFAULT_DMA_OPTS; + int ec; + + dma_mem2p_channel_t chan = + select_dma_channel_mem2p( + DMA1_PERIPH_USART2_TX, + &opts, + &ec); + + ASSERT_EQ(DMA1.channel_config[6].cpa_r, ptr2reg(&USART2.td_r)); + + ASSERT_EQ( + regget(DMA1.channel_config[6].cc_r, dma_cc_dir), + READ_FROM_MEMORY); + + ASSERT_EQ( + regget(DMA1.channel_config[6].cc_r, dma_cc_minc), + 1); + + ASSERT_EQ( + regget(DMA1.channel_config[6].cc_r, dma_cc_pl), + DMA_PRIORITY_LEVEL_MEDIUM); + + ASSERT_EQ(regget(DMA1.csel_r, dma_c7s), 0x2); + + ASSERT_EQ(regget(RCC.ahb1en_r, rcc_dma1en), 1); + + release_dma_channel(chan.c_); + + ASSERT_EQ(regget(RCC.ahb1en_r, rcc_dma1en), 0); + return 0; +} + +TEST(dma_peri, unable_to_realloc) +{ + dma_opts_t opts = DEFAULT_DMA_OPTS; + + int ec = 0; + + dma_mem2p_channel_t chan = + select_dma_channel_mem2p( + DMA1_PERIPH_USART2_TX, + &opts, + &ec); + + ASSERT_EQ(ec, 0); + + select_dma_channel_p2mem( + DMA1_PERIPH_USART2_TX, + &opts, + &ec); + + ASSERT_EQ(ec, DMA_ERROR_CHANNEL_IN_USE); + + release_dma_channel(chan.c_); + + chan = select_dma_channel_mem2p( + DMA1_PERIPH_USART2_TX, + &opts, + &ec); + + ASSERT_EQ(ec, 0); + + release_dma_channel(chan.c_); + return 0; +} + +TEST(dma_peri, select_mem2mem) +{ + int ec = 0; + dma_opts_t opts = DEFAULT_DMA_OPTS; + dma_mem2mem_channel_t chan = + select_dma_channel_mem2mem(-1, &opts, &ec); + + ASSERT_EQ(ec, 0); + + ASSERT_EQ(chan.c_.dma, 1); + ASSERT_EQ(chan.c_.chan, 6); + + dma_mem2mem_channel_t chan2 = + select_dma_channel_mem2mem(-1, &opts, &ec); + + ASSERT_EQ(ec, 0); + + ASSERT_EQ(chan2.c_.dma, 1); + ASSERT_EQ(chan2.c_.chan, 5); + + release_dma_channel(chan.c_); + + dma_mem2mem_channel_t chan3 = + select_dma_channel_mem2mem(-1, &opts, &ec); + + ASSERT_EQ(chan3.c_.dma, 1); + ASSERT_EQ(chan3.c_.chan, 6); + + release_dma_channel(chan2.c_); + release_dma_channel(chan3.c_); + return 0; +} + +TEST(dma_peri, select_mem2mem_2) +{ + dma_opts_t opts = DEFAULT_DMA_OPTS; + dma_mem2mem_channel_t chans[14]; + int ec; + + for (int i = 0; i < 14; ++ i) { + chans[i] = select_dma_channel_mem2mem( + -1, &opts, &ec); + + ASSERT_EQ(ec, 0); + } + + select_dma_channel_mem2mem(-1, &opts, &ec); + ASSERT_EQ(ec, DMA_ERROR_CHANNEL_IN_USE); + + for (int i = 0; i < 14; ++ i) { + if (i < 7) { + ASSERT_EQ(chans[i].c_.chan, 6 - i); + ASSERT_EQ(chans[i].c_.dma, 1); + } else { + ASSERT_EQ(chans[i].c_.chan, 6 - (i - 7)); + ASSERT_EQ(chans[i].c_.dma, 0); + } + release_dma_channel(chans[i].c_); + } + return 0; +} diff --git a/tests/test_gpio.c b/tests/test_gpio.c new file mode 100644 index 0000000..bcb953c --- /dev/null +++ b/tests/test_gpio.c @@ -0,0 +1,194 @@ +#include "test_harness.h" + +#include "arch/stm32l4xxx/peripherals/rcc.h" +#include "kern/gpio/gpio_manager.h" + +TEST(gpio_manager, smell) +{ + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + int ec = 5; + gpio_reserved_pin_t some_pin = reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_TRUE(gpio_pin_in_use(GPIO_PIN_PA15)); + + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + release_gpio_pin(some_pin); + + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + return 0; +} + +TEST(gpio_manager, multiplereserve) +{ + int ec; + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_TRUE(ec == 0); + + reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_EQ(ec, GPIO_ERROR_IN_USE); + + return 0; +} + +TEST(gpio_manager, alternate) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_TX, GPIO_PIN_PA2, &ec); + + ASSERT_EQ(ec, 0); + + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_RX, GPIO_PIN_PA15, &ec); + + ASSERT_EQ(ec, 0); + + gpio_port_config_t* gpioa = (gpio_port_config_t*) GPIOA_BASE; + + ASSERT_EQ(regget(gpioa->mode_r, gpio_mode_n(15)), GPIO_MODE_ALTERNATE); + ASSERT_EQ(regget(gpioa->mode_r, gpio_mode_n(2)), GPIO_MODE_ALTERNATE); + + ASSERT_EQ(regget(gpioa->af_rl, gpio_afsel_n(2)), 7); + ASSERT_EQ(regget(gpioa->af_rh, gpio_afsel_n(7)), 3); + + return 0; +} + +TEST(gpio_manager, bad_alternate) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_RX, GPIO_PIN_PA2, &ec); + + ASSERT_EQ(ec, GPIO_ERROR_INVALID_PIN_FOR_ALTERNATE_FUNCTION); + + return 0; +} + +TEST(gpio_manager, bad_pin) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_RX, 99, &ec); + + ASSERT_EQ(ec, GPIO_ERROR_INVALID_PIN); + + return 0; +} + +TEST(gpio_manager, alternate_then_reserve_fail) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_TX, GPIO_PIN_PA2, &ec); + + ASSERT_EQ(ec, 0); + + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + reserve_gpio_pin(GPIO_PIN_PA2, &opts, &ec); + + ASSERT_EQ(ec, GPIO_ERROR_IN_USE); + + return 0; +} + +TEST(gpio_manager, get_gpio_pin_port_off) +{ + + gpio_port_config_t* cfg; + int off; + get_gpio_pin_port_off(GPIO_PIN_PA5, &cfg, &off); + + ASSERT_EQ(cfg, (void*)(GPIOA_BASE)); + ASSERT_EQ(off, 5); + + return 0; +} + +TEST(gpio_manager, sets_gpio_settings) +{ + gpio_pin_opts_t opts; + int ec; + + opts.mode = GPIO_MODE_OUTPUT; + opts.pull_dir = GPIO_PULL_DIR_NONE; + opts.output_opts.speed = GPIO_OUTPUT_SPEED_VERY_HIGH; + opts.output_opts.type = GPIO_OUTPUT_TYPE_PUSH_PULL; + + reserve_gpio_pin(GPIO_PIN_PA2, &opts, &ec); + ASSERT_EQ(ec, 0); + + gpio_port_config_t* gpioa = (gpio_port_config_t*) GPIOA_BASE; + + ASSERT_EQ(regget(gpioa->mode_r, gpio_mode_n(2)), GPIO_MODE_OUTPUT); + ASSERT_EQ(regget(gpioa->pupd_r, gpio_pupd_n(2)), GPIO_PULL_DIR_NONE); + ASSERT_EQ(regget(gpioa->ospeed_r, gpio_ospeed_n(2)), GPIO_OUTPUT_SPEED_VERY_HIGH); + ASSERT_EQ(regget(gpioa->otype_r, gpio_otype_n(2)), GPIO_OUTPUT_TYPE_PUSH_PULL); + + return 0; +} + +TEST(gpio_manager, gc) +{ + int ec; + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + + gpio_reserved_pin_t p1 = reserve_gpio_pin(GPIO_PIN_PA0, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + + gpio_reserved_pin_t p2 = reserve_gpio_pin(GPIO_PIN_PA1, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + + gpio_reserved_pin_t p3 = reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + + gpio_reserved_pin_t p4 = reserve_gpio_pin(GPIO_PIN_PB3, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + gpio_reserved_pin_t p5 = reserve_gpio_pin(GPIO_PIN_PB1, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + gpio_reserved_pin_t p6 = reserve_gpio_pin(GPIO_PIN_PB0, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p1); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p2); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p3); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p4); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p5); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p6); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 0); + + return 0; +} diff --git a/tests/test_irq.c b/tests/test_irq.c new file mode 100644 index 0000000..3c4ee9c --- /dev/null +++ b/tests/test_irq.c @@ -0,0 +1,43 @@ +#include "test_harness.h" + +#include "arch/stm32l4xxx/peripherals/irq.h" +#include "arch/stm32l4xxx/peripherals/nvic.h" + +TEST(irq, nvic) +{ + interrupt_set_t is = { 0 }; + + interrupt_set_add(&is, IRQ_USART2); + interrupt_set_add(&is, IRQ_USART3); + + enable_interrupts(&is); + + ASSERT_EQ(is.irqs[1], 0xC0); + ASSERT_EQ(NVIC.ise_r[1], 0xC0); + + return 0; +} + +TEST(irq, nvic_edgecase) +{ + interrupt_set_t is = { 0 }; + interrupt_set_add(&is, IRQ_WWDG_IRQ); + interrupt_set_add(&is, IRQ_I2C1_ER); + + enable_interrupts(&is); + + ASSERT_EQ(is.irqs[0], 1); + ASSERT_EQ(NVIC.ise_r[0], 1); + ASSERT_EQ(is.irqs[1], 1); + ASSERT_EQ(NVIC.ise_r[1], 1); + + return 0; +} + +TEST(irq, enable_single_interrupt) +{ + enable_interrupt(IRQ_USART2); + ASSERT_EQ(NVIC.ise_r[1], 0x40); + + return 0; +} diff --git a/tests/test_lib.c b/tests/test_lib.c new file mode 100644 index 0000000..33076c2 --- /dev/null +++ b/tests/test_lib.c @@ -0,0 +1,21 @@ +#include "test_harness.h" +#include "kern/lib.h" + +TEST(lib, hexify) +{ + char buf[10]; + + hexify(0xaaaaaaaa, buf); + ASSERT_EQ_STR(buf, "AAAAAAAA"); + + hexify(0xdddddddd, buf); + ASSERT_EQ_STR(buf, "DDDDDDDD"); + + hexify(0x02468ace, buf); + ASSERT_EQ_STR(buf, "02468ACE"); + + hexify(0xdeadbeef, buf); + ASSERT_EQ_STR(buf, "DEADBEEF"); + + return 0; +} diff --git a/tests/test_memory.c b/tests/test_memory.c new file mode 100644 index 0000000..04e9289 --- /dev/null +++ b/tests/test_memory.c @@ -0,0 +1,378 @@ +#ifndef FOR_TESTING +#define FOR_TESTING +#endif + +#include <stdlib.h> + +#include "arch.h" +#include "test_harness.c" +#include "kern/common.h" +#include "kern/mem.h" + +struct TEST_STRUCT { + uint32_t array[3]; +}; + +struct TEST_STRUCT2 { + uint32_t array[10]; +}; + +/* Copy of the node structure. */ +typedef struct HALLOC_NODE { + union { + uint32_t header; + struct { + /* Is this memory block currently in use (hasn't been hfree'd) */ + bool used:1; + /* Number of words allocated. Does not include the header. */ + uint16_t size:12; + /* The location of the previous block (in WORDS from offest) */ + uint16_t prev:12; + uint8_t canary:7; + } PACKED; + }; + + uint8_t mem[]; /* The memory to use. */ +} halloc_node_t; + +extern halloc_node_t* halloc_start; + +static void wipeout_halloc() +{ + memset(halloc_start, 0, 1024); + halloc_start = NULL; +} + + +static struct TEST_STRUCT* new_test_struct() +{ + struct TEST_STRUCT* ret = halloc(sizeof(struct TEST_STRUCT)); + + ret->array[0] = 1; + ret->array[1] = 2; + ret->array[2] = 3; + + return ret; +} + +static struct TEST_STRUCT2* new_test_struct2() +{ + struct TEST_STRUCT2* ret = halloc(sizeof(struct TEST_STRUCT2)); + + for (int i = 0; i < 10; ++ i) { + ret->array[i] = i; + } + + return ret; +} + +#define ASSERT_CHAIN(t1, t2) \ + ASSERT_EQ(V(t1) + sizeof(*t1) + 4, V(t2)) + +TEST(memory, halloc) +{ + +#define V(x) ((void*)(x)) + struct TEST_STRUCT* test1 = new_test_struct(); + struct TEST_STRUCT2* test2 = new_test_struct2(); + struct TEST_STRUCT* test3 = new_test_struct(); + struct TEST_STRUCT2* test4 = new_test_struct2(); + struct TEST_STRUCT2* test5 = new_test_struct2(); + + ASSERT_TRUE(V(test1) != V(test2)); + ASSERT_TRUE(V(test2) != V(test3)); + ASSERT_TRUE(V(test3) != V(test1)); + ASSERT_TRUE(V(test2) != V(test5)); + ASSERT_TRUE(V(test4) != V(test5)); + + ASSERT_CHAIN(test1, test2); + ASSERT_CHAIN(test2, test3); + ASSERT_CHAIN(test3, test4); + ASSERT_CHAIN(test4, test5); + + + char buf[1024]; + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf( + stderr, + "Consistency check failed. (%s:%d)\n", + __FILE__, + __LINE__); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + + wipeout_halloc(); + + return 0; +} + +struct UNEVEN_STRUCT { + uint8_t arr[5]; +}; + +struct UNEVEN_STRUCT* new_uneven_struct() +{ + struct UNEVEN_STRUCT* ret = halloc(sizeof(struct UNEVEN_STRUCT)); + + ret->arr[0] = 1; + ret->arr[1] = 2; + ret->arr[2] = 3; + ret->arr[3] = 4; + ret->arr[4] = 5; + + return ret; +} + +#define size_for(n) \ + (((n) / 4) + ((n) % 4 != 0)) + +TEST(memory, uneven_halloc) +{ + if (halloc_start) { + wipeout_halloc(); + } + + struct UNEVEN_STRUCT* test1 = new_uneven_struct(); + struct UNEVEN_STRUCT* test2 = new_uneven_struct(); + + ASSERT_EQ(V(test1) + 12, test2); + + wipeout_halloc(); + + return 0; +} + +TEST(memory, halloc_free) +{ + if (halloc_start) { + wipeout_halloc(); + } + + struct TEST_STRUCT* test1 = new_test_struct(); + struct TEST_STRUCT2* test2 = new_test_struct2(); + struct TEST_STRUCT* test3 = new_test_struct(); + struct TEST_STRUCT2* test4 = new_test_struct2(); + struct TEST_STRUCT2* test5 = new_test_struct2(); + + hfree(test2); + hfree(test4); + hfree(test3); + hfree(test1); + hfree(test5); + + ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + + test1 = new_test_struct(); + test2 = new_test_struct2(); + test3 = new_test_struct(); + test4 = new_test_struct2(); + test5 = new_test_struct2(); + + hfree(test1); + hfree(test3); + hfree(test2); + hfree(test4); + hfree(test5); + + ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + + test1 = new_test_struct(); + test2 = new_test_struct2(); + test3 = new_test_struct(); + test4 = new_test_struct2(); + test5 = new_test_struct2(); + + hfree(test4); + hfree(test3); + hfree(test1); + hfree(test2); + hfree(test5); + + ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + + wipeout_halloc(); + + return 0; +} + +TEST(memory, halloc_free_alloc2) +{ + if (halloc_start) { + wipeout_halloc(); + } + + struct TEST_STRUCT2* test1 = new_test_struct2(); + struct TEST_STRUCT2* test2 = new_test_struct2(); + + hfree(test1); + + struct TEST_STRUCT* test3 = new_test_struct(); + struct TEST_STRUCT* test4 = new_test_struct(); + + ASSERT_EQ(debug_halloc_get_next_ptr(test3), V(test4)); + + ASSERT_EQ( + // There should be a free block after test4. + debug_halloc_get_next_ptr(debug_halloc_get_next_ptr(test4)), + V(test2)); + + ASSERT_EQ( + // There should be a free block after test4. + debug_halloc_get_prev_ptr(debug_halloc_get_prev_ptr(test2)), + V(test4)); + + char buf[1024]; + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf(stderr, "Consistency check failed.\n"); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + + return 0; +} + +TEST(memory, relink_backref_after_free) +{ + if (halloc_start) { + wipeout_halloc(); + } + + struct TEST_STRUCT* test2 = new_test_struct(); + struct TEST_STRUCT* test3 = new_test_struct(); + + hfree(test2); + hfree(test3); + + char buf[1024]; + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf(stderr, "Consistency check failed.\n"); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + + return 0; +} + +TEST(memory, consistency_stress) +{ +#define NRUNS 500 + if (halloc_start) { + wipeout_halloc(); + } + + int i; + void* allocd[NRUNS] = { 0 }; + char buf[1024]; + + for (i = 0; i < NRUNS; ++ i) { + size_t nalloc = rand() % 20; + allocd[i] = halloc(nalloc); + + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf( + stderr, + "Consistency check failed. (At index=%d, %s:%d)\n", + i, + __FILE__, + __LINE__); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + + ASSERT_TRUE(allocd[i]); + + memset(allocd[i], 0xFF, nalloc); + size_t idx = rand() % NRUNS; + + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf( + stderr, + "Consistency check failed. (At index=%d, %s:%d)\n", + i, + __FILE__, + __LINE__); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + + hfree(allocd[idx]); + allocd[idx] = NULL; + + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf( + stderr, + "Consistency check failed. (At index=%d, %s:%d)\n", + i, + __FILE__, + __LINE__); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + + idx = rand() % NRUNS; + hfree(allocd[idx]); + allocd[idx] = NULL; + + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf( + stderr, + "Consistency check failed. (At index=%d, %s:%d)\n", + i, + __FILE__, + __LINE__); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + } + + for(i = 0; i < NRUNS; ++ i) { + if (allocd[i]) { + hfree(allocd[i]); + } + + if (debug_halloc_assert_consistency(buf, 1024)) { + fprintf( + stderr, + "Consistency check failed. (At index=%d, %s:%d)\n", + i, + __FILE__, + __LINE__); + fprintf(stderr, buf); + ASSERT_TRUE(false); + } + } + ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + + return 0; +} + +TEST(memory, halloc_free_alloc) +{ + if (halloc_start) { + wipeout_halloc(); + } + + new_test_struct(); + struct TEST_STRUCT2* test2 = new_test_struct2(); + new_test_struct(); + struct TEST_STRUCT2* test4 = new_test_struct2(); + new_test_struct2(); + + hfree(test4); + + struct TEST_STRUCT2* test6 = new_test_struct2(); + + // test_6 should have been allocated in test_4's spot. + ASSERT_EQ(test6, test4); + + hfree(test2); + struct TEST_STRUCT* test7 = new_test_struct(); + struct TEST_STRUCT* test8 = new_test_struct(); + + // Test 2 was large enough to accomodate 3 smaller structs. + ASSERT_EQ(V(test7), V(test2)); + ASSERT_EQ(V(test8), V(test2) + sizeof(*test7) + 4); + + return 0; +} diff --git a/tests/test_spi.c b/tests/test_spi.c new file mode 100644 index 0000000..cc25d6e --- /dev/null +++ b/tests/test_spi.c @@ -0,0 +1,11 @@ +#include "test_harness.h" + +#include "arch/stm32l4xxx/peripherals/spi.h" + +TEST(spi, smoke) +{ + __IO spi_t* spi = &SPI1; + spi->s_r = 1; + + return 0; +} diff --git a/tests/test_usart.c b/tests/test_usart.c new file mode 100644 index 0000000..b19d687 --- /dev/null +++ b/tests/test_usart.c @@ -0,0 +1,22 @@ +#include "test_harness.h" +#include "arch/stm32l4xxx/peripherals/usart.h" + +#include <stdlib.h> + +TEST(usart, enable_dma) +{ + __IO usart_t* usart = &USART1; + + usart->c_r3 = 0; + + usart_enable_dma(usart, USART_ENABLE_TX); + ASSERT_EQ(usart->c_r3, 128); + + usart_enable_dma(usart, USART_ENABLE_RX); + ASSERT_EQ(usart->c_r3, 192); + + usart_enable_dma(usart, USART_ENABLE_DISABLED); + ASSERT_EQ(usart->c_r3, 0); + + return 0; +} |