1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-05 13:24:11 +01:00
LibrePilot/flight/tests/logfs/pios_flash_ut.c

179 lines
4.1 KiB
C

#include <stdlib.h> /* abort */
#include <stdio.h> /* fopen/fread/fwrite/fseek */
#include <assert.h> /* assert */
#include <string.h> /* memset */
#include <unistd.h>
#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(uintptr_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(FLASH_IMAGE_FILE, "rb+");
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 = (uintptr_t)flash_dev;
return 0;
}
int32_t PIOS_Flash_UT_Destroy(uintptr_t flash_id)
{
/* Check inputs */
assert(flash_id);
struct flash_ut_dev *flash_dev = (void *)flash_id;
if (flash_dev->flash_file == NULL) {
return -1;
}
fclose(flash_dev->flash_file);
free(flash_dev);
unlink(FLASH_IMAGE_FILE);
return 0;
}
/**********************************
*
* Provide a PIOS flash driver API
*
*********************************/
#include "pios_flash.h"
static int32_t PIOS_Flash_UT_StartTransaction(uintptr_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(uintptr_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(uintptr_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(uintptr_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(uintptr_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,
};