[Cryptech-Commits] [sw/stm32] 02/02: Add performance tests for spiflash_n25q128.c

git at cryptech.is git at cryptech.is
Wed Feb 15 16:39:47 UTC 2017


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch ksng
in repository sw/stm32.

commit 1dc664a90471f165855c737c5ae649d01897b2d6
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Wed Feb 15 11:39:10 2017 -0500

    Add performance tests for spiflash_n25q128.c
---
 projects/board-test/Makefile        |   2 +-
 projects/board-test/spiflash-perf.c | 238 ++++++++++++++++++++++++++++++++++++
 2 files changed, 239 insertions(+), 1 deletion(-)

diff --git a/projects/board-test/Makefile b/projects/board-test/Makefile
index 9b1812f..0e60229 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
+TEST = led-test short-test uart-test fmc-test fmc-perf fmc-probe rtc-test spiflash-perf
 
 all: $(TEST:=.elf)
 
diff --git a/projects/board-test/spiflash-perf.c b/projects/board-test/spiflash-perf.c
new file mode 100644
index 0000000..7265098
--- /dev/null
+++ b/projects/board-test/spiflash-perf.c
@@ -0,0 +1,238 @@
+/*
+ * Test read/write/erase performance of the N25Q128 SPI flash chip.
+ */
+
+#include "string.h"
+
+#include "stm-init.h"
+#include "stm-led.h"
+#include "stm-uart.h"
+#include "stm-keystore.h"
+#include "spiflash_n25q128.h"
+
+/*
+ * Use the keystore memory for testing, because it's less involved than
+ * using the FPGA configuration memory, and less work to restore it to a
+ * useful configuration.
+ *
+ * However, rather than using the stm-keystore abstractions, this version
+ * goes straight to the low-level API.
+ */
+
+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)
+{
+    uint8_t read_buf[N25Q128_PAGE_SIZE];
+    uint32_t i;
+    int err;
+
+    for (i = 0; i < N25Q128_NUM_PAGES; ++i) {
+        err = n25q128_read_page(ctx, i, read_buf);
+        if (err != 1) {
+            uart_send_string("ERROR: n25q128_read_page returned ");
+            uart_send_integer(err, 0);
+            uart_send_string("\r\n");
+            break;
+        }
+    }
+}
+
+/*
+ * Read the flash data and verify it against a known pattern.
+ * It turns out that verification doesn't slow us down in any measurable
+ * way, because memcmp on 256 bytes is pretty inconsequential.
+ */
+static void _read_verify(uint8_t *vrfy_buf)
+{
+    uint8_t read_buf[N25Q128_PAGE_SIZE];
+    uint32_t i;
+    int err;
+
+    for (i = 0; i < N25Q128_NUM_PAGES; ++i) {
+        err = n25q128_read_page(ctx, i, read_buf);
+        if (err != 1) {
+            uart_send_string("ERROR: n25q128_read_page returned ");
+            uart_send_integer(err, 0);
+            uart_send_string("\r\n");
+            break;
+        }
+        if (memcmp(read_buf, vrfy_buf, N25Q128_PAGE_SIZE) != 0) {
+            uart_send_string("ERROR: verify failed in page ");
+            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 < N25Q128_NUM_SECTORS; ++i) {
+        err = n25q128_erase_sector(ctx, i);
+        if (err != 1) {
+            uart_send_string("ERROR: n25q128_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 < N25Q128_NUM_SUBSECTORS; ++i) {
+        err = n25q128_erase_subsector(ctx, i);
+        if (err != 1) {
+            uart_send_string("ERROR: n25q128_erase_subsector returned ");
+            uart_send_integer(err, 0);
+            uart_send_string("\r\n");
+            break;
+        }
+    }
+}
+
+/*
+ * 2c. Erase the entire flash in bulk.
+ */
+static void test_erase_bulk(void)
+{
+    int err;
+
+    err = n25q128_erase_bulk(ctx);
+    if (err != 1) {
+        uart_send_string("ERROR: n25q128_erase_bulk returned ");
+        uart_send_integer(err, 0);
+        uart_send_string("\r\n");
+    }
+}
+
+/*
+ * 2d. Read the entire flash, verify erasure.
+ */
+static void test_verify_erase(void)
+{
+    uint8_t vrfy_buf[N25Q128_PAGE_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_page(uint32_t delay)
+{
+    uint8_t write_buf[N25Q128_PAGE_SIZE];
+    uint32_t i;
+    int err;
+
+    for (i = 0; i < sizeof(write_buf); ++i)
+        write_buf[i] = i & 0xFF;
+
+    for (i = 0; i < N25Q128_NUM_PAGES; ++i) {
+        err = n25q128_write_page(ctx, i, write_buf);
+        if (err != 1) {
+            uart_send_string("ERROR: n25q128_write_page returned ");
+            uart_send_integer(err, 0);
+            uart_send_string(" for page ");
+            uart_send_integer(i, 0);
+            uart_send_string("\r\n");
+            break;
+        }
+        _wait_while_wip(delay);
+    }
+}
+
+/*
+ * 3b. Read the entire flash, verify data.
+ */
+static void test_verify_write(void)
+{
+    uint8_t vrfy_buf[N25Q128_PAGE_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 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");
+}
+
+#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 (n25q128_check_id(ctx) != 1) {
+        uart_send_string("ERROR: n25q128_check_id failed\r\n");
+        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("Done.\r\n\r\n");
+    return 0;
+}



More information about the Commits mailing list