mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
ut: add basic unit test for logfs
Build it with: make ut_logfs Create a raw flash file like this: dd if=/dev/zero bs=1 count=2MiB | tr '\000' '\377' > theflash.bin Run it with: ./build/unit_tests/logfs/logfs.elf && echo 'all good' Conflicts: Makefile
This commit is contained in:
parent
7726b9e2a9
commit
7f53aa422a
40
Makefile
40
Makefile
@ -707,6 +707,46 @@ sim_osx_%: uavobjects_flight
|
||||
$(V1) mkdir -p $(BUILD_DIR)/sim_osx
|
||||
$(V1) $(MAKE) --no-print-directory \
|
||||
-C $(ROOT_DIR)/flight/targets/Revolution --file=$(ROOT_DIR)/flight/targets/Revolution/Makefile.osx $*
|
||||
|
||||
|
||||
##############################
|
||||
#
|
||||
# Unit Tests
|
||||
#
|
||||
##############################
|
||||
|
||||
UT_TARGETS := logfs
|
||||
.PHONY: ut_all
|
||||
ut_all: $(addprefix ut_, $(UT_TARGETS))
|
||||
|
||||
UT_OUT_DIR := $(BUILD_DIR)/unit_tests
|
||||
|
||||
$(UT_OUT_DIR):
|
||||
$(V1) mkdir -p $@
|
||||
|
||||
ut_%: $(UT_OUT_DIR)
|
||||
$(V1) cd $(ROOT_DIR)/flight/tests/$* && \
|
||||
$(MAKE) --no-print-directory \
|
||||
BUILD_TYPE=ut \
|
||||
BOARD_SHORT_NAME=$* \
|
||||
TCHAIN_PREFIX="" \
|
||||
REMOVE_CMD="$(RM)" \
|
||||
\
|
||||
TARGET=$* \
|
||||
OUTDIR="$(UT_OUT_DIR)/$*" \
|
||||
\
|
||||
PIOS=$(PIOS) \
|
||||
OPUAVOBJ=$(OPUAVOBJ) \
|
||||
OPUAVTALK=$(OPUAVTALK) \
|
||||
FLIGHTLIB=$(FLIGHTLIB) \
|
||||
\
|
||||
$*
|
||||
|
||||
.PHONY: ut_clean
|
||||
ut_clean:
|
||||
$(V0) @echo " CLEAN $@"
|
||||
$(V1) [ ! -d "$(UT_OUT_DIR)" ] || $(RM) -r "$(UT_OUT_DIR)"
|
||||
|
||||
##############################
|
||||
#
|
||||
# Packaging components
|
||||
|
41
flight/tests/logfs/Makefile
Normal file
41
flight/tests/logfs/Makefile
Normal file
@ -0,0 +1,41 @@
|
||||
###############################################################################
|
||||
# @file Makefile
|
||||
# @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||
# @addtogroup
|
||||
# @{
|
||||
# @addtogroup
|
||||
# @{
|
||||
# @brief Makefile for unit test
|
||||
###############################################################################
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
TOP := $(realpath $(WHEREAMI)/../../../)
|
||||
include $(TOP)/make/firmware-defs.mk
|
||||
|
||||
EXTRAINCDIRS += $(PIOS)/inc
|
||||
|
||||
CFLAGS += -O0
|
||||
CFLAGS += -Wall -Werror
|
||||
CFLAGS += -g
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) -I.
|
||||
|
||||
CONLYFLAGS += -std=gnu99
|
||||
|
||||
SRC := $(PIOS)/Common/pios_flashfs_logfs.c
|
||||
|
||||
include $(TOP)/make/unittest.mk
|
87
flight/tests/logfs/main.c
Normal file
87
flight/tests/logfs/main.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <stdio.h> /* printf */
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include "pios_flash.h" /* PIOS_FLASH_* API */
|
||||
#include "pios_flash_ut_priv.h"
|
||||
|
||||
const struct pios_flash_ut_cfg flash_config = {
|
||||
.size_of_flash = 0x00200000,
|
||||
.size_of_sector = 0x00010000,
|
||||
};
|
||||
|
||||
#include "pios_flashfs_logfs_priv.h"
|
||||
|
||||
const struct flashfs_logfs_cfg flashfs_config = {
|
||||
.fs_magic = 0x89abceef,
|
||||
.total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */
|
||||
.arena_size = 0x00010000, /* 256 * slot size */
|
||||
.slot_size = 0x00000100, /* 256 bytes */
|
||||
|
||||
.start_offset = 0, /* start at the beginning of the chip */
|
||||
.sector_size = 0x00010000, /* 64K bytes */
|
||||
.page_size = 0x00000100, /* 256 bytes */
|
||||
};
|
||||
|
||||
#include "pios_flashfs.h" /* PIOS_FLASHFS_* */
|
||||
|
||||
int main (int argc, char * argv[])
|
||||
{
|
||||
int32_t rc;
|
||||
|
||||
/* dd if=/dev/zero bs=1 count=2MiB | tr '\000' '\377' > theflash.bin */
|
||||
|
||||
uint32_t flash_id;
|
||||
rc = PIOS_Flash_UT_Init(&flash_id, &flash_config);
|
||||
if (rc != 0) {
|
||||
printf ("flash init failed (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
uint32_t fs_id;
|
||||
rc = PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &pios_ut_flash_driver, flash_id);
|
||||
if (rc != 0) {
|
||||
printf ("flash filesystem init failed (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
#define OBJ1_ID 0x12345678
|
||||
#define OBJ1_SIZE 76
|
||||
unsigned char obj1[OBJ1_SIZE];
|
||||
memset(obj1, 0xA5, sizeof(obj1));
|
||||
for (uint32_t i = 0; i < 10000; i++) {
|
||||
rc = PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1, sizeof(obj1));
|
||||
if (rc != 0) {
|
||||
printf ("failed to save obj1 (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char obj1_check[OBJ1_SIZE];
|
||||
memset(obj1_check, 0, sizeof(obj1_check));
|
||||
rc = PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check));
|
||||
if (rc != 0) {
|
||||
printf ("failed to load obj1 (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (memcmp(obj1, obj1_check, sizeof(obj1)) != 0) {
|
||||
printf ("read-back of obj1 failed\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
rc = PIOS_FLASHFS_ObjDelete(fs_id, OBJ1_ID, 0);
|
||||
if (rc != 0) {
|
||||
printf ("failed to delete obj1 (%d)\n", rc);
|
||||
abort();
|
||||
}
|
||||
|
||||
rc = PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check));
|
||||
if (rc == 0) {
|
||||
printf ("was able to load obj1 after delete!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
}
|
||||
|
5
flight/tests/logfs/openpilot.h
Normal file
5
flight/tests/logfs/openpilot.h
Normal file
@ -0,0 +1,5 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PIOS_Assert(x) if (!(x)) { while (1) ; }
|
||||
|
||||
#define PIOS_DEBUG_Assert(x) PIOS_Assert(x)
|
4
flight/tests/logfs/pios.h
Normal file
4
flight/tests/logfs/pios.h
Normal file
@ -0,0 +1,4 @@
|
||||
#if defined(PIOS_INCLUDE_FLASH)
|
||||
#include <pios_flash.h>
|
||||
#include <pios_flashfs.h>
|
||||
#endif
|
1
flight/tests/logfs/pios_config.h
Normal file
1
flight/tests/logfs/pios_config.h
Normal file
@ -0,0 +1 @@
|
||||
#define PIOS_INCLUDE_FLASH
|
159
flight/tests/logfs/pios_flash_ut.c
Normal file
159
flight/tests/logfs/pios_flash_ut.c
Normal file
@ -0,0 +1,159 @@
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <stdio.h> /* fopen/fread/fwrite/fseek */
|
||||
#include <assert.h> /* assert */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "pios_flash_ut_priv.h"
|
||||
|
||||
enum flash_ut_magic {
|
||||
FLASH_UT_MAGIC = 0x321dabc1,
|
||||
};
|
||||
|
||||
struct flash_ut_dev {
|
||||
enum flash_ut_magic magic;
|
||||
const struct pios_flash_ut_cfg * cfg;
|
||||
bool transaction_in_progress;
|
||||
FILE * flash_file;
|
||||
};
|
||||
|
||||
static struct flash_ut_dev * PIOS_Flash_UT_Alloc(void)
|
||||
{
|
||||
struct flash_ut_dev * flash_dev = malloc(sizeof(struct flash_ut_dev));
|
||||
|
||||
flash_dev->magic = FLASH_UT_MAGIC;
|
||||
|
||||
return flash_dev;
|
||||
}
|
||||
|
||||
int32_t PIOS_Flash_UT_Init(uint32_t * flash_id, const struct pios_flash_ut_cfg * cfg)
|
||||
{
|
||||
/* Check inputs */
|
||||
assert(flash_id);
|
||||
assert(cfg);
|
||||
assert(cfg->size_of_flash);
|
||||
assert(cfg->size_of_sector);
|
||||
assert((cfg->size_of_flash % cfg->size_of_sector) == 0);
|
||||
|
||||
struct flash_ut_dev * flash_dev = PIOS_Flash_UT_Alloc();
|
||||
assert(flash_dev);
|
||||
|
||||
flash_dev->cfg = cfg;
|
||||
flash_dev->transaction_in_progress = false;
|
||||
|
||||
flash_dev->flash_file = fopen ("theflash.bin", "r+");
|
||||
if (flash_dev->flash_file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fseek (flash_dev->flash_file, flash_dev->cfg->size_of_flash, SEEK_SET) != 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
*flash_id = (uint32_t)flash_dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************
|
||||
*
|
||||
* Provide a PIOS flash driver API
|
||||
*
|
||||
*********************************/
|
||||
#include "pios_flash.h"
|
||||
|
||||
static int32_t PIOS_Flash_UT_StartTransaction(uint32_t flash_id)
|
||||
{
|
||||
struct flash_ut_dev * flash_dev = (struct flash_ut_dev *)flash_id;
|
||||
|
||||
assert(!flash_dev->transaction_in_progress);
|
||||
|
||||
flash_dev->transaction_in_progress = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t PIOS_Flash_UT_EndTransaction(uint32_t flash_id)
|
||||
{
|
||||
struct flash_ut_dev * flash_dev = (struct flash_ut_dev *)flash_id;
|
||||
|
||||
assert(flash_dev->transaction_in_progress);
|
||||
|
||||
flash_dev->transaction_in_progress = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t PIOS_Flash_UT_EraseSector(uint32_t flash_id, uint32_t addr)
|
||||
{
|
||||
struct flash_ut_dev * flash_dev = (struct flash_ut_dev *)flash_id;
|
||||
|
||||
assert(flash_dev->transaction_in_progress);
|
||||
|
||||
if (fseek (flash_dev->flash_file, addr, SEEK_SET) != 0) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
unsigned char * buf = malloc(flash_dev->cfg->size_of_sector);
|
||||
assert (buf);
|
||||
memset((void *)buf, 0xFF, flash_dev->cfg->size_of_sector);
|
||||
|
||||
size_t s;
|
||||
s = fwrite (buf, 1, flash_dev->cfg->size_of_sector, flash_dev->flash_file);
|
||||
|
||||
assert (s == flash_dev->cfg->size_of_sector);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t PIOS_Flash_UT_WriteData(uint32_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
|
||||
{
|
||||
/* Check inputs */
|
||||
assert(data);
|
||||
|
||||
struct flash_ut_dev * flash_dev = (struct flash_ut_dev *)flash_id;
|
||||
|
||||
assert(flash_dev->transaction_in_progress);
|
||||
|
||||
if (fseek (flash_dev->flash_file, addr, SEEK_SET) != 0) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
size_t s;
|
||||
s = fwrite (data, 1, len, flash_dev->flash_file);
|
||||
|
||||
assert (s == len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t PIOS_Flash_UT_ReadData(uint32_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
|
||||
{
|
||||
/* Check inputs */
|
||||
assert(data);
|
||||
|
||||
struct flash_ut_dev * flash_dev = (struct flash_ut_dev *)flash_id;
|
||||
|
||||
assert(flash_dev->transaction_in_progress);
|
||||
|
||||
if (fseek (flash_dev->flash_file, addr, SEEK_SET) != 0) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
size_t s;
|
||||
s = fread (data, 1, len, flash_dev->flash_file);
|
||||
|
||||
assert (s == len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Provide a flash driver to external drivers */
|
||||
const struct pios_flash_driver pios_ut_flash_driver = {
|
||||
.start_transaction = PIOS_Flash_UT_StartTransaction,
|
||||
.end_transaction = PIOS_Flash_UT_EndTransaction,
|
||||
.erase_sector = PIOS_Flash_UT_EraseSector,
|
||||
.write_data = PIOS_Flash_UT_WriteData,
|
||||
.read_data = PIOS_Flash_UT_ReadData,
|
||||
};
|
||||
|
10
flight/tests/logfs/pios_flash_ut_priv.h
Normal file
10
flight/tests/logfs/pios_flash_ut_priv.h
Normal file
@ -0,0 +1,10 @@
|
||||
#include <stdint.h>
|
||||
|
||||
struct pios_flash_ut_cfg {
|
||||
uint32_t size_of_flash;
|
||||
uint32_t size_of_sector;
|
||||
};
|
||||
|
||||
int32_t PIOS_Flash_UT_Init(uint32_t * flash_id, const struct pios_flash_ut_cfg * cfg);
|
||||
|
||||
extern const struct pios_flash_driver pios_ut_flash_driver;
|
Loading…
x
Reference in New Issue
Block a user