Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_FlashStorage/examples/FlashTest/FlashTest.cpp
Views: 1800
//1// Unit tests for the AP_Math rotations code2//34#include <AP_HAL/AP_HAL.h>5#include <AP_Math/AP_Math.h>6#include <AP_FlashStorage/AP_FlashStorage.h>7#include <stdio.h>8#include <AP_HAL/utility/sparse-endian.h>910const AP_HAL::HAL& hal = AP_HAL::get_HAL();1112class FlashTest : public AP_HAL::HAL::Callbacks {13public:14// HAL::Callbacks implementation.15void setup() override;16void loop() override;1718private:19static const uint32_t flash_sector_size = 32U * 1024U;2021uint8_t mem_buffer[AP_FlashStorage::storage_size];22uint8_t mem_mirror[AP_FlashStorage::storage_size];2324// flash buffer25uint8_t *flash[2];2627bool flash_write(uint8_t sector, uint32_t offset, const uint8_t *data, uint16_t length);28bool flash_read(uint8_t sector, uint32_t offset, uint8_t *data, uint16_t length);29bool flash_erase(uint8_t sector);30bool flash_erase_ok(void);3132AP_FlashStorage storage{mem_buffer,33flash_sector_size,34FUNCTOR_BIND_MEMBER(&FlashTest::flash_write, bool, uint8_t, uint32_t, const uint8_t *, uint16_t),35FUNCTOR_BIND_MEMBER(&FlashTest::flash_read, bool, uint8_t, uint32_t, uint8_t *, uint16_t),36FUNCTOR_BIND_MEMBER(&FlashTest::flash_erase, bool, uint8_t),37FUNCTOR_BIND_MEMBER(&FlashTest::flash_erase_ok, bool)};3839// write to storage and mem_mirror40void write(uint16_t offset, const uint8_t *data, uint16_t length);4142bool erase_ok;43};4445bool FlashTest::flash_write(uint8_t sector, uint32_t offset, const uint8_t *data, uint16_t length)46{47if (sector > 1) {48AP_HAL::panic("FATAL: write to sector %u", (unsigned)sector);49}50if (offset + length > flash_sector_size) {51AP_HAL::panic("FATAL: write to sector %u at offset %u length %u",52(unsigned)sector,53(unsigned)offset,54(unsigned)length);55}56uint8_t *b = &flash[sector][offset];57if ((offset & 1) || (length & 1)) {58AP_HAL::panic("FATAL: invalid write at %u:%u len=%u",59(unsigned)sector,60(unsigned)offset,61(unsigned)length);62}63uint16_t len16 = length/2;64for (uint16_t i=0; i<len16; i++) {65const uint16_t v = le16toh_ptr(&data[i*2]);66uint16_t v2 = le16toh_ptr(&b[i*2]);67if (v & !v2) {68AP_HAL::panic("FATAL: invalid write16 at %u:%u 0x%04x 0x%04x",69(unsigned)sector,70unsigned(offset+i),71b[i],72data[i]);73}74#ifndef AP_FLASHSTORAGE_MULTI_WRITE75if (v != v2 && v != 0xFFFF && v2 != 0xFFFF) {76AP_HAL::panic("FATAL: invalid write16 at %u:%u 0x%04x 0x%04x",77(unsigned)sector,78unsigned(offset+i),79b[i],80data[i]);81}82#endif83v2 &= v;84put_le16_ptr(&b[i*2], v2);85}86return true;87}8889bool FlashTest::flash_read(uint8_t sector, uint32_t offset, uint8_t *data, uint16_t length)90{91if (sector > 1) {92AP_HAL::panic("FATAL: read from sector %u", (unsigned)sector);93}94if (offset + length > flash_sector_size) {95AP_HAL::panic("FATAL: read from sector %u at offset %u length %u",96(unsigned)sector,97(unsigned)offset,98(unsigned)length);99}100memcpy(data, &flash[sector][offset], length);101return true;102}103104bool FlashTest::flash_erase(uint8_t sector)105{106if (sector > 1) {107AP_HAL::panic("FATAL: erase sector %u", (unsigned)sector);108}109memset(&flash[sector][0], 0xFF, flash_sector_size);110return true;111}112113bool FlashTest::flash_erase_ok(void)114{115return erase_ok;116}117118void FlashTest::write(uint16_t offset, const uint8_t *data, uint16_t length)119{120memcpy(&mem_mirror[offset], data, length);121memcpy(&mem_buffer[offset], data, length);122if (!storage.write(offset, length)) {123if (erase_ok) {124printf("Failed to write at %u for %u\n", offset, length);125}126}127}128129/*130* test flash storage131*/132void FlashTest::setup(void)133{134hal.console->printf("AP_FlashStorage test\n");135}136137void FlashTest::loop(void)138{139flash[0] = (uint8_t *)malloc(flash_sector_size);140flash[1] = (uint8_t *)malloc(flash_sector_size);141flash_erase(0);142flash_erase(1);143144if (!storage.init()) {145AP_HAL::panic("Failed first init()");146}147148// fill with 10k random writes149for (uint32_t i=0; i<5000000; i++) {150uint16_t ofs = get_random16() % sizeof(mem_buffer);151uint16_t length = get_random16() & 0x1F;152length = MIN(length, sizeof(mem_buffer) - ofs);153uint8_t data[length];154for (uint8_t j=0; j<length; j++) {155data[j] = get_random16() & 0xFF;156}157158erase_ok = (i % 1000 == 0);159write(ofs, data, length);160161if (erase_ok) {162if (memcmp(mem_buffer, mem_mirror, sizeof(mem_buffer)) != 0) {163AP_HAL::panic("FATAL: data mis-match at i=%u", (unsigned)i);164}165}166}167168// force final write to allow for flush with erase_ok169erase_ok = true;170uint8_t b = 42;171write(37, &b, 1);172173if (memcmp(mem_buffer, mem_mirror, sizeof(mem_buffer)) != 0) {174AP_HAL::panic("FATAL: data mis-match before re-init");175}176177// re-init178printf("re-init\n");179memset(mem_buffer, 0, sizeof(mem_buffer));180if (!storage.init()) {181AP_HAL::panic("Failed second init()");182}183184if (memcmp(mem_buffer, mem_mirror, sizeof(mem_buffer)) != 0) {185AP_HAL::panic("FATAL: data mis-match");186}187while (true) {188hal.console->printf("TEST PASSED");189hal.scheduler->delay(20000);190}191}192193FlashTest flashtest;194195AP_HAL_MAIN_CALLBACKS(&flashtest);196197198