aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2017-02-19 14:14:10 -0500
committerPaul Selkirk <paul@psgd.org>2017-02-19 17:58:57 -0500
commit742cbe3d4090d62ee5f871e487ce88145d12c04e (patch)
tree3232ea6814a624c482a22f20b0eb250b983cba9b
parent1dc664a90471f165855c737c5ae649d01897b2d6 (diff)
Simplify spiflash test code slightly, add keystore test code.
-rw-r--r--projects/board-test/Makefile2
-rw-r--r--projects/board-test/keystore-perf.c198
-rw-r--r--projects/board-test/spiflash-perf.c68
-rw-r--r--spiflash_n25q128.c2
-rw-r--r--stm-keystore.h1
5 files changed, 239 insertions, 32 deletions
diff --git a/projects/board-test/Makefile b/projects/board-test/Makefile
index 0e60229..bb6a8cf 100644
--- a/projects/board-test/Makefile
+++ b/projects/board-test/Makefile
@@ -1,4 +1,4 @@
-TEST = led-test short-test uart-test fmc-test fmc-perf fmc-probe rtc-test spiflash-perf
+TEST = led-test short-test uart-test fmc-test fmc-perf fmc-probe rtc-test spiflash-perf keystore-perf
all: $(TEST:=.elf)
diff --git a/projects/board-test/keystore-perf.c b/projects/board-test/keystore-perf.c
new file mode 100644
index 0000000..7af4893
--- /dev/null
+++ b/projects/board-test/keystore-perf.c
@@ -0,0 +1,198 @@
+/*
+ * Test read/write/erase performance of the flash keystore.
+ */
+
+#include "string.h"
+
+#include "stm-init.h"
+#include "stm-led.h"
+#include "stm-uart.h"
+#include "stm-keystore.h"
+
+/*
+ * 1. Read the entire flash by subsectors, ignoring data.
+ */
+static void test_read_data(void)
+{
+ uint8_t read_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_read_data(i * KEYSTORE_SUBSECTOR_SIZE, read_buf, KEYSTORE_SUBSECTOR_SIZE);
+ if (err != 1) {
+ uart_send_string("ERROR: keystore_read_data returned ");
+ uart_send_integer(err, 0);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * Read the flash data and verify it against a known pattern.
+ */
+static void _read_verify(uint8_t *vrfy_buf)
+{
+ uint8_t read_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_read_data(i * KEYSTORE_SUBSECTOR_SIZE, read_buf, KEYSTORE_SUBSECTOR_SIZE);
+ if (err != 1) {
+ uart_send_string("ERROR: keystore_read_data returned ");
+ uart_send_integer(err, 0);
+ uart_send_string("\r\n");
+ break;
+ }
+ if (memcmp(read_buf, vrfy_buf, KEYSTORE_SUBSECTOR_SIZE) != 0) {
+ uart_send_string("ERROR: verify failed in subsector ");
+ uart_send_integer(i, 0);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2a. Erase the entire flash by sectors.
+ */
+static void test_erase_sector(void)
+{
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < KEYSTORE_NUM_SECTORS; ++i) {
+ err = keystore_erase_sectors(i, i);
+ if (err != 1) {
+ uart_send_string("ERROR: keystore_erase_sector returned ");
+ uart_send_integer(err, 0);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2b. Erase the entire flash by subsectors.
+ */
+static void test_erase_subsector(void)
+{
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_erase_subsectors(i, i);
+ if (err != 1) {
+ uart_send_string("ERROR: keystore_erase_subsector returned ");
+ uart_send_integer(err, 0);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2c. Read the entire flash, verify erasure.
+ */
+static void test_verify_erase(void)
+{
+ uint8_t vrfy_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+
+ for (i = 0; i < sizeof(vrfy_buf); ++i)
+ vrfy_buf[i] = 0xFF;
+
+ _read_verify(vrfy_buf);
+}
+
+/*
+ * 3a. Write the entire flash with a pattern.
+ */
+static void test_write_data(void)
+{
+ uint8_t write_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < sizeof(write_buf); ++i)
+ write_buf[i] = i & 0xFF;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_write_data(i * KEYSTORE_SUBSECTOR_SIZE, write_buf, KEYSTORE_SUBSECTOR_SIZE);
+ if (err != 1) {
+ uart_send_string("ERROR: keystore_write_data returned ");
+ uart_send_integer(err, 0);
+ uart_send_string(" for subsector ");
+ uart_send_integer(i, 0);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 3b. Read the entire flash, verify data.
+ */
+static void test_verify_write(void)
+{
+ uint8_t vrfy_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+
+ for (i = 0; i < sizeof(vrfy_buf); ++i)
+ vrfy_buf[i] = i & 0xFF;
+
+ _read_verify(vrfy_buf);
+}
+
+static void _time_check(char *label, const uint32_t t0, uint32_t n_rounds)
+{
+ uint32_t t = HAL_GetTick() - t0;
+
+ uart_send_string(label);
+ uart_send_integer(t / 1000, 0);
+ uart_send_char('.');
+ uart_send_integer(t % 1000, 3);
+ uart_send_string(" sec");
+ if (n_rounds > 1) {
+ uart_send_string(" for ");
+ uart_send_integer(n_rounds, 0);
+ uart_send_string(" rounds, ");
+ uart_send_integer(t / n_rounds, 0);
+ uart_send_char('.');
+ uart_send_integer(((t % n_rounds) * 100) / n_rounds, 2);
+ uart_send_string(" ms each");
+ }
+ uart_send_string("\r\n");
+}
+
+#define time_check(_label_, _expr_, _n_) \
+ do { \
+ uint32_t _t = HAL_GetTick(); \
+ (_expr_); \
+ _time_check(_label_, _t, _n_); \
+ } while (0)
+
+int main(void)
+{
+ stm_init();
+ uart_set_default(STM_UART_MGMT);
+
+ if (keystore_check_id() != 1) {
+ uart_send_string("ERROR: keystore_check_id failed\r\n");
+ return 0;
+ }
+
+ uart_send_string("Starting...\r\n");
+
+ time_check("read data ", test_read_data(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("erase sector ", test_erase_sector(), KEYSTORE_NUM_SECTORS);
+ time_check("erase subsector ", test_erase_subsector(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("verify erase ", test_verify_erase(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("write data ", test_write_data(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("verify write ", test_verify_write(), KEYSTORE_NUM_SUBSECTORS);
+
+ uart_send_string("Done.\r\n\r\n");
+ return 0;
+}
diff --git a/projects/board-test/spiflash-perf.c b/projects/board-test/spiflash-perf.c
index 7265098..52d3c0f 100644
--- a/projects/board-test/spiflash-perf.c
+++ b/projects/board-test/spiflash-perf.c
@@ -23,18 +23,6 @@ extern struct spiflash_ctx keystore_ctx;
static struct spiflash_ctx *ctx = &keystore_ctx;
/*
- * Based on _wait_while_wip in spiflash_n25q128.c, but can be more
- * aggressive about re-checking.
- */
-static inline void _wait_while_wip(uint32_t delay)
-{
- while (n25q128_get_wip_flag(ctx) != HAL_OK) {
- if (delay != 0)
- HAL_Delay(delay);
- }
-}
-
-/*
* 1. Read the entire flash by pages, ignoring data.
*/
static void test_read_page(void)
@@ -150,9 +138,24 @@ static void test_verify_erase(void)
}
/*
+ * Borrowed from spiflash_n25q128.c, since n25q128_write_page doesn't call it.
+ */
+inline int _wait_while_wip(struct spiflash_ctx *ctx, uint32_t timeout)
+{
+ int i;
+ while (timeout--) {
+ i = n25q128_get_wip_flag(ctx);
+ if (i < 0) return 0;
+ if (! i) break;
+ HAL_Delay(10);
+ }
+ return 1;
+}
+
+/*
* 3a. Write the entire flash with a pattern.
*/
-static void test_write_page(uint32_t delay)
+static void test_write_page(void)
{
uint8_t write_buf[N25Q128_PAGE_SIZE];
uint32_t i;
@@ -163,6 +166,8 @@ static void test_write_page(uint32_t delay)
for (i = 0; i < N25Q128_NUM_PAGES; ++i) {
err = n25q128_write_page(ctx, i, write_buf);
+ if (err == 1)
+ err = _wait_while_wip(ctx, 1000);
if (err != 1) {
uart_send_string("ERROR: n25q128_write_page returned ");
uart_send_integer(err, 0);
@@ -171,7 +176,6 @@ static void test_write_page(uint32_t delay)
uart_send_string("\r\n");
break;
}
- _wait_while_wip(delay);
}
}
@@ -197,11 +201,17 @@ static void _time_check(char *label, const uint32_t t0, uint32_t n_rounds)
uart_send_integer(t / 1000, 0);
uart_send_char('.');
uart_send_integer(t % 1000, 3);
- uart_send_string(" sec for ");
- uart_send_integer(n_rounds, 0);
- uart_send_string(" rounds, ");
- uart_send_integer((t + n_rounds/2) / n_rounds, 0);
- uart_send_string(" ms each\r\n");
+ uart_send_string(" sec");
+ if (n_rounds > 1) {
+ uart_send_string(" for ");
+ uart_send_integer(n_rounds, 0);
+ uart_send_string(" rounds, ");
+ uart_send_integer(t / n_rounds, 0);
+ uart_send_char('.');
+ uart_send_integer(((t % n_rounds) * 100) / n_rounds, 2);
+ uart_send_string(" ms each");
+ }
+ uart_send_string("\r\n");
}
#define time_check(_label_, _expr_, _n_) \
@@ -221,17 +231,15 @@ int main(void)
return 0;
}
- uart_send_string("Starting...\r\n\r\n");
-
- time_check("read_page ", test_read_page(), N25Q128_NUM_PAGES);
- time_check("erase_sector ", test_erase_sector(), N25Q128_NUM_SECTORS);
- time_check("erase_subsector ", test_erase_subsector(), N25Q128_NUM_SUBSECTORS);
- time_check("erase_bulk ", test_erase_bulk(), 1);
- time_check("verify_erase ", test_verify_erase(), N25Q128_NUM_PAGES);
- time_check("write_page 0ms ", test_write_page(0), N25Q128_NUM_PAGES);
- time_check("write_page 1ms ", test_write_page(1), N25Q128_NUM_PAGES);
- time_check("write_page 10ms ", test_write_page(10), N25Q128_NUM_PAGES);
- time_check("verify_write ", test_verify_write(), N25Q128_NUM_PAGES);
+ uart_send_string("Starting...\r\n");
+
+ time_check("read page ", test_read_page(), N25Q128_NUM_PAGES);
+ time_check("erase sector ", test_erase_sector(), N25Q128_NUM_SECTORS);
+ time_check("erase subsector ", test_erase_subsector(), N25Q128_NUM_SUBSECTORS);
+ time_check("erase bulk ", test_erase_bulk(), 1);
+ time_check("verify erase ", test_verify_erase(), N25Q128_NUM_PAGES);
+ time_check("write page ", test_write_page(), N25Q128_NUM_PAGES);
+ time_check("verify write ", test_verify_write(), N25Q128_NUM_PAGES);
uart_send_string("Done.\r\n\r\n");
return 0;
diff --git a/spiflash_n25q128.c b/spiflash_n25q128.c
index 68f96f1..371bef2 100644
--- a/spiflash_n25q128.c
+++ b/spiflash_n25q128.c
@@ -220,7 +220,7 @@ inline int _wait_while_wip(struct spiflash_ctx *ctx, uint32_t timeout)
int i;
while (timeout--) {
i = n25q128_get_wip_flag(ctx);
- if (i < 0) return 0; // impossible
+ if (i < 0) return 0;
if (! i) break;
HAL_Delay(10);
}
diff --git a/stm-keystore.h b/stm-keystore.h
index 9054db5..437cdf6 100644
--- a/stm-keystore.h
+++ b/stm-keystore.h
@@ -39,6 +39,7 @@
#include "spiflash_n25q128.h"
#define KEYSTORE_PAGE_SIZE N25Q128_PAGE_SIZE
+#define KEYSTORE_NUM_PAGES N25Q128_NUM_PAGES
#define KEYSTORE_SECTOR_SIZE N25Q128_SECTOR_SIZE
#define KEYSTORE_NUM_SECTORS N25Q128_NUM_SECTORS
#define KEYSTORE_SUBSECTOR_SIZE N25Q128_SUBSECTOR_SIZE