2013-11-04 16:05:11 +01:00
|
|
|
/****************************************************************************
|
2021-06-16 09:22:16 +02:00
|
|
|
* apps/examples/configdata/configdata_main.c
|
2013-11-04 16:05:11 +01:00
|
|
|
*
|
2021-06-16 08:28:53 +02:00
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
|
|
* this work for additional information regarding copyright ownership. The
|
|
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
2013-11-04 16:05:11 +01:00
|
|
|
*
|
2021-06-16 08:28:53 +02:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2013-11-04 16:05:11 +01:00
|
|
|
*
|
2021-06-16 08:28:53 +02:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
2013-11-04 16:05:11 +01:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
2021-07-04 02:08:39 +02:00
|
|
|
#include <inttypes.h>
|
2013-11-04 16:05:11 +01:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2020-06-15 08:02:49 +02:00
|
|
|
#include <malloc.h>
|
2013-11-04 16:05:11 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <crc32.h>
|
|
|
|
#include <debug.h>
|
|
|
|
|
2013-11-15 18:22:23 +01:00
|
|
|
#include <nuttx/mtd/mtd.h>
|
2016-07-21 21:34:04 +02:00
|
|
|
#include <nuttx/mtd/configdata.h>
|
2013-11-04 16:05:11 +01:00
|
|
|
#include <nuttx/fs/ioctl.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
|
|
|
/****************************************************************************
|
2015-10-02 22:06:11 +02:00
|
|
|
* Pre-processor Definitions
|
2013-11-04 16:05:11 +01:00
|
|
|
****************************************************************************/
|
2020-04-11 20:56:24 +02:00
|
|
|
|
2013-11-04 16:05:11 +01:00
|
|
|
/* Configuration ************************************************************/
|
2020-04-11 20:56:24 +02:00
|
|
|
|
2013-11-04 16:05:11 +01:00
|
|
|
/* The default is to use the RAM MTD device at drivers/mtd/rammtd.c. But
|
|
|
|
* an architecture-specific MTD driver can be used instead by defining
|
2020-04-11 20:56:24 +02:00
|
|
|
* CONFIG_EXAMPLES_CONFIGDATA_ARCHINIT. In this case, the initialization
|
|
|
|
* logic will call configdata_archinitialize() to obtain the MTD driver
|
|
|
|
* instance.
|
2013-11-04 16:05:11 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_ARCHINIT
|
|
|
|
|
2020-04-11 20:56:24 +02:00
|
|
|
/* This must exactly match the default configuration in
|
|
|
|
* drivers/mtd/rammtd.c
|
|
|
|
*/
|
2013-11-04 16:05:11 +01:00
|
|
|
|
|
|
|
# ifndef CONFIG_RAMMTD_ERASESIZE
|
|
|
|
# define CONFIG_RAMMTD_ERASESIZE 4096
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# ifndef CONFIG_EXAMPLES_CONFIGDATA_NEBLOCKS
|
|
|
|
# define CONFIG_EXAMPLES_CONFIGDATA_NEBLOCKS (256)
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# define EXAMPLES_CONFIGDATA_BUFSIZE \
|
|
|
|
(CONFIG_RAMMTD_ERASESIZE * CONFIG_EXAMPLES_CONFIGDATA_NEBLOCKS)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_MAXSIZE
|
|
|
|
# define CONFIG_EXAMPLES_CONFIGDATA_MAXSIZE 512
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES
|
|
|
|
# define CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES 3000
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_NLOOPS
|
|
|
|
# define CONFIG_EXAMPLES_CONFIGDATA_NLOOPS 100
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define EXAMPLES_CONFIGDATA_REPORT (CONFIG_EXAMPLES_CONFIGDATA_NLOOPS / 20)
|
|
|
|
#if EXAMPLES_CONFIGDATA_REPORT == 0
|
|
|
|
# undef EXAMPLES_CONFIGDATA_REPORT
|
|
|
|
# define EXAMPLES_CONFIGDATA_REPORT 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_VERBOSE
|
|
|
|
# define CONFIG_EXAMPLES_CONFIGDATA_VERBOSE 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Private Types
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
struct configdata_entrydesc_s
|
|
|
|
{
|
|
|
|
uint16_t id;
|
|
|
|
uint8_t instance;
|
|
|
|
uint16_t len;
|
|
|
|
uint32_t crc;
|
|
|
|
uint8_t deleted;
|
|
|
|
uint8_t changed;
|
|
|
|
};
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Private Data
|
|
|
|
****************************************************************************/
|
2020-04-11 20:56:24 +02:00
|
|
|
|
2013-11-04 16:05:11 +01:00
|
|
|
/* Pre-allocated simulated flash */
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_ARCHINIT
|
2020-04-11 20:56:24 +02:00
|
|
|
static uint8_t g_simflash[EXAMPLES_CONFIGDATA_BUFSIZE << 1];
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static uint8_t g_entryimage[CONFIG_EXAMPLES_CONFIGDATA_MAXSIZE];
|
2020-04-11 20:56:24 +02:00
|
|
|
static struct configdata_entrydesc_s
|
|
|
|
g_entries[CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES];
|
|
|
|
|
2013-11-04 16:05:11 +01:00
|
|
|
static int g_nentries;
|
|
|
|
static int g_ndeleted;
|
|
|
|
static int g_fd;
|
2020-04-11 20:56:24 +02:00
|
|
|
static int g_ntests;
|
|
|
|
static int g_nverified;
|
|
|
|
static int g_ntotalalloc;
|
|
|
|
static int g_ntotaldelete;
|
2013-11-04 16:05:11 +01:00
|
|
|
|
|
|
|
static struct mallinfo g_mmbefore;
|
|
|
|
static struct mallinfo g_mmafter;
|
2015-11-29 22:00:52 +01:00
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
|
|
|
static struct mallinfo g_mmprevious;
|
|
|
|
#endif
|
2013-11-04 16:05:11 +01:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* External Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifdef CONFIG_EXAMPLES_CONFIGDATA_ARCHINIT
|
|
|
|
extern FAR struct mtd_dev_s *configdata_archinitialize(void);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Private Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_memusage
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static void configdata_showmemusage(struct mallinfo *mmbefore,
|
|
|
|
struct mallinfo *mmafter)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("VARIABLE BEFORE AFTER\n");
|
|
|
|
printf("======== ======== ========\n");
|
|
|
|
printf("arena %8x %8x\n", mmbefore->arena, mmafter->arena);
|
|
|
|
printf("ordblks %8d %8d\n", mmbefore->ordblks, mmafter->ordblks);
|
|
|
|
printf("mxordblk %8x %8x\n", mmbefore->mxordblk, mmafter->mxordblk);
|
|
|
|
printf("uordblks %8x %8x\n", mmbefore->uordblks, mmafter->uordblks);
|
|
|
|
printf("fordblks %8x %8x\n", mmbefore->fordblks, mmafter->fordblks);
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_loopmemusage
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-11-29 21:41:34 +01:00
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
2013-11-04 16:05:11 +01:00
|
|
|
static void configdata_loopmemusage(void)
|
|
|
|
{
|
|
|
|
/* Get the current memory usage */
|
|
|
|
|
|
|
|
g_mmafter = mallinfo();
|
|
|
|
|
|
|
|
/* Show the change from the previous loop */
|
|
|
|
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("\nEnd of loop memory usage:\n");
|
2013-11-04 16:05:11 +01:00
|
|
|
configdata_showmemusage(&g_mmprevious, &g_mmafter);
|
|
|
|
|
|
|
|
/* Set up for the next test */
|
|
|
|
|
|
|
|
g_mmprevious = g_mmafter;
|
|
|
|
}
|
2015-11-29 21:41:34 +01:00
|
|
|
#endif
|
2013-11-04 16:05:11 +01:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_endmemusage
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static void configdata_endmemusage(void)
|
|
|
|
{
|
|
|
|
g_mmafter = mallinfo();
|
2020-04-11 20:13:56 +02:00
|
|
|
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("\nFinal memory usage:\n");
|
2013-11-04 16:05:11 +01:00
|
|
|
configdata_showmemusage(&g_mmbefore, &g_mmafter);
|
|
|
|
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("\nTotal adds: %d Total deletes : %d\n",
|
|
|
|
g_ntotalalloc, g_ntotaldelete);
|
|
|
|
printf("Total tests: %d Number passed: %d Failed: %d\n",
|
|
|
|
g_ntests, g_nverified, g_ntests - g_nverified);
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_randid
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static inline uint16_t configdata_randid(void)
|
|
|
|
{
|
|
|
|
int x;
|
|
|
|
int value;
|
|
|
|
|
|
|
|
retry:
|
2020-04-11 20:56:24 +02:00
|
|
|
value = rand() & 0x7fff;
|
2013-11-04 16:05:11 +01:00
|
|
|
if (value == 0)
|
|
|
|
{
|
|
|
|
value = 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ensure we don't have a duplicate id */
|
|
|
|
|
|
|
|
for (x = 0; x < g_nentries; x++)
|
|
|
|
{
|
|
|
|
if (value == g_entries[x].id)
|
|
|
|
{
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_randlen
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static inline uint16_t configdata_randlen(void)
|
|
|
|
{
|
|
|
|
int value = rand() % CONFIG_EXAMPLES_CONFIGDATA_MAXSIZE;
|
|
|
|
|
|
|
|
if (value == 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_randinstance
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static inline uint8_t configdata_randinstance(void)
|
|
|
|
{
|
|
|
|
return rand() & 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_freefile
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-11-29 22:00:52 +01:00
|
|
|
#if 0 /* Not used */
|
2013-11-04 16:05:11 +01:00
|
|
|
static void configdata_freeentry(FAR struct configdata_entrydesc_s *entry)
|
|
|
|
{
|
|
|
|
memset(entry, 0, sizeof(struct configdata_entrydesc_s));
|
|
|
|
}
|
2015-11-29 22:00:52 +01:00
|
|
|
#endif
|
2013-11-04 16:05:11 +01:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_wrentry
|
|
|
|
****************************************************************************/
|
|
|
|
|
2020-04-11 20:56:24 +02:00
|
|
|
static inline int
|
|
|
|
configdata_wrentry(FAR struct configdata_entrydesc_s *entry)
|
2013-11-04 16:05:11 +01:00
|
|
|
{
|
|
|
|
size_t x;
|
|
|
|
int ret;
|
|
|
|
struct config_data_s config;
|
|
|
|
|
|
|
|
/* Create a random entry */
|
|
|
|
|
|
|
|
entry->id = configdata_randid();
|
|
|
|
entry->instance = configdata_randinstance();
|
|
|
|
entry->len = configdata_randlen();
|
|
|
|
|
|
|
|
/* Write some random data to the entry */
|
|
|
|
|
|
|
|
for (x = 0; x < entry->len; x++)
|
|
|
|
{
|
2020-04-11 20:56:24 +02:00
|
|
|
g_entryimage[x] = rand() & 0xff;
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate the crc32 for the data */
|
|
|
|
|
|
|
|
entry->crc = crc32(g_entryimage, entry->len);
|
|
|
|
|
|
|
|
/* Write the entry to the /dev/config device */
|
|
|
|
|
|
|
|
config.id = entry->id;
|
|
|
|
config.instance = entry->instance;
|
|
|
|
config.len = entry->len;
|
|
|
|
config.configdata = g_entryimage;
|
|
|
|
ret = ioctl(g_fd, CFGDIOC_SETCONFIG, (unsigned long) &config);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
entry->id = 0;
|
|
|
|
entry->len = 0;
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_fillconfig
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static int configdata_fillconfig(void)
|
|
|
|
{
|
|
|
|
FAR struct configdata_entrydesc_s *entry;
|
|
|
|
int ret;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Create a file for each unused file structure */
|
|
|
|
|
|
|
|
for (i = 0; i < CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES; i++)
|
|
|
|
{
|
|
|
|
entry = &g_entries[i];
|
|
|
|
if (entry->id == 0)
|
|
|
|
{
|
|
|
|
ret = configdata_wrentry(entry);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf(" /dev/config full\n");
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf(" Created entry %04X, %d Len=%d\n",
|
|
|
|
entry->id, entry->instance, entry->len);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
g_nentries++;
|
|
|
|
g_ntotalalloc++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_rdentry
|
|
|
|
****************************************************************************/
|
|
|
|
|
2020-04-11 20:56:24 +02:00
|
|
|
static inline int
|
|
|
|
configdata_rdentry(FAR struct configdata_entrydesc_s *entry)
|
2013-11-04 16:05:11 +01:00
|
|
|
{
|
|
|
|
struct config_data_s config;
|
|
|
|
uint32_t crc;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* Read the config entry from /dev/config */
|
|
|
|
|
|
|
|
config.id = entry->id;
|
|
|
|
config.instance = entry->instance;
|
|
|
|
config.len = entry->len;
|
|
|
|
config.configdata = g_entryimage;
|
|
|
|
ret = ioctl(g_fd, CFGDIOC_GETCONFIG, (unsigned long) &config);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify the file image CRC */
|
|
|
|
|
|
|
|
crc = crc32(g_entryimage, entry->len);
|
|
|
|
if (crc != entry->crc)
|
|
|
|
{
|
2021-07-04 02:08:39 +02:00
|
|
|
printf("ERROR: Bad CRC: %" PRIu32 " vs %" PRIu32 "\n",
|
|
|
|
crc, entry->crc);
|
2014-10-08 16:33:00 +02:00
|
|
|
printf(" Entry id: %04X\n", entry->id);
|
|
|
|
printf(" Entry size: %d\n", entry->len);
|
2013-11-04 16:05:11 +01:00
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_verifyconfig
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static int configdata_verifyconfig(void)
|
|
|
|
{
|
|
|
|
FAR struct configdata_entrydesc_s *entry;
|
|
|
|
int ret;
|
2016-06-11 22:49:55 +02:00
|
|
|
int errcode = OK;
|
2013-11-04 16:05:11 +01:00
|
|
|
int i;
|
|
|
|
static int iteration = 0;
|
|
|
|
|
|
|
|
/* Create a file for each unused file structure */
|
|
|
|
|
|
|
|
iteration++;
|
|
|
|
for (i = 0; i < CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES; i++)
|
|
|
|
{
|
|
|
|
entry = &g_entries[i];
|
|
|
|
if (entry->id != 0)
|
|
|
|
{
|
|
|
|
g_ntests++;
|
|
|
|
ret = configdata_rdentry(entry);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
/* Check if this entry has been deleted */
|
|
|
|
|
|
|
|
if (entry->deleted)
|
|
|
|
{
|
|
|
|
/* Good, it wasn't found (as it shouldn't be) */
|
|
|
|
|
|
|
|
g_nverified++;
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf(" Verified delete %04X, %d\n", entry->id,
|
|
|
|
entry->instance);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: Failed to read an entry: %d\n", i);
|
|
|
|
printf(" Entry id: %04X\n", entry->id);
|
|
|
|
printf(" Entry size: %d\n", entry->len);
|
2016-06-11 22:49:55 +02:00
|
|
|
errcode = ERROR;
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-11 20:56:24 +02:00
|
|
|
/* Check if this entry has been deleted and should report an
|
|
|
|
* error.
|
|
|
|
*/
|
2013-11-04 16:05:11 +01:00
|
|
|
|
|
|
|
if (entry->deleted)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: Succesffully read a deleted entry\n");
|
|
|
|
printf(" Entry id: %04X\n", entry->id);
|
|
|
|
printf(" Entry size: %d\n", entry->len);
|
2016-06-11 22:49:55 +02:00
|
|
|
errcode = ERROR;
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_nverified++;
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2020-04-11 20:56:24 +02:00
|
|
|
printf(" Verifed entry %04X, %d\n",
|
|
|
|
entry->id, entry->instance);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-11 22:49:55 +02:00
|
|
|
return errcode;
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_delentries
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static int configdata_delentries(void)
|
|
|
|
{
|
|
|
|
FAR struct configdata_entrydesc_s *entry;
|
|
|
|
struct config_data_s hdr;
|
|
|
|
int ndel;
|
|
|
|
int ret;
|
|
|
|
int i;
|
|
|
|
int j;
|
|
|
|
|
|
|
|
/* Are there any files to be deleted? */
|
|
|
|
|
|
|
|
int nentries = g_nentries - g_ndeleted;
|
|
|
|
if (nentries < 1)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Yes... How many files should we delete? */
|
|
|
|
|
|
|
|
ndel = (rand() % nentries) + 1;
|
|
|
|
|
|
|
|
/* Now pick which files to delete */
|
|
|
|
|
|
|
|
for (i = 0; i < ndel; i++)
|
|
|
|
{
|
|
|
|
/* Guess a file index */
|
|
|
|
|
|
|
|
int ndx = (rand() % (g_nentries - g_ndeleted));
|
|
|
|
|
|
|
|
/* And delete the next undeleted file after that random index */
|
|
|
|
|
2020-04-11 20:56:24 +02:00
|
|
|
for (j = ndx + 1; j != ndx; )
|
2013-11-04 16:05:11 +01:00
|
|
|
{
|
|
|
|
entry = &g_entries[j];
|
|
|
|
if (entry->id && !entry->deleted)
|
|
|
|
{
|
|
|
|
hdr.id = entry->id;
|
|
|
|
hdr.instance = entry->instance;
|
|
|
|
hdr.len = 0;
|
|
|
|
ret = ioctl(g_fd, CFGDIOC_SETCONFIG, (unsigned long) &hdr);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2020-04-11 20:56:24 +02:00
|
|
|
printf("ERROR: Delete %d failed: %d\n", i + 1, errno);
|
2014-10-08 16:33:00 +02:00
|
|
|
printf(" Entry id: %04X\n", entry->id);
|
|
|
|
printf(" Entry size: %d\n", entry->len);
|
|
|
|
printf(" Entry index: %d\n", j);
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf(" Deleted entry %04X\n", entry->id);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
entry->deleted = true;
|
|
|
|
g_ndeleted++;
|
|
|
|
g_ntotaldelete++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Increment the index and test for wrap-around */
|
|
|
|
|
|
|
|
if (++j >= CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES)
|
|
|
|
{
|
|
|
|
j = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_getnextdeleted
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
static int configdata_getnextdeleted(void)
|
|
|
|
{
|
|
|
|
int x;
|
|
|
|
int nextdeleted = -1;
|
|
|
|
|
|
|
|
/* Find next deleted entry */
|
|
|
|
|
|
|
|
for (x = 0; x < CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES; x++)
|
|
|
|
{
|
|
|
|
if (g_entries[x].deleted)
|
|
|
|
{
|
|
|
|
nextdeleted = x;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nextdeleted;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_cleardeleted
|
|
|
|
****************************************************************************/
|
|
|
|
|
2015-11-29 21:41:34 +01:00
|
|
|
static void configdata_cleardeleted(void)
|
2013-11-04 16:05:11 +01:00
|
|
|
{
|
|
|
|
int nextdeleted;
|
|
|
|
int x;
|
|
|
|
|
|
|
|
while ((nextdeleted = configdata_getnextdeleted()) != -1)
|
|
|
|
{
|
|
|
|
/* Find next non-deleted entry after the deleted one */
|
|
|
|
|
2020-04-11 20:56:24 +02:00
|
|
|
for (x = nextdeleted + 1;
|
|
|
|
x < CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES;
|
|
|
|
x++)
|
2013-11-04 16:05:11 +01:00
|
|
|
{
|
|
|
|
if (g_entries[x].id && !g_entries[x].deleted)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Test if an non-deleted entry found */
|
|
|
|
|
|
|
|
if (x < CONFIG_EXAMPLES_CONFIGDATA_MAXENTRIES)
|
|
|
|
{
|
|
|
|
/* Move this entry to the deleted entry location */
|
|
|
|
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf(" Overwrite entry %d, OLD=%04X NEW=%04X\n",
|
|
|
|
nextdeleted, g_entries[nextdeleted].id, g_entries[x].id);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
g_entries[nextdeleted] = g_entries[x];
|
|
|
|
g_entries[x].id = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Just remove the entry */
|
2020-04-11 20:56:24 +02:00
|
|
|
|
2013-11-04 16:05:11 +01:00
|
|
|
g_entries[nextdeleted].id = 0;
|
|
|
|
g_entries[nextdeleted].deleted = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_nentries -= g_ndeleted;
|
|
|
|
g_ndeleted = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Public Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: configdata_main
|
|
|
|
****************************************************************************/
|
|
|
|
|
2014-09-06 17:23:23 +02:00
|
|
|
int main(int argc, FAR char *argv[])
|
2013-11-04 16:05:11 +01:00
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
int ret;
|
|
|
|
FAR struct mtd_dev_s *mtd;
|
|
|
|
|
|
|
|
/* Seed the random number generated */
|
|
|
|
|
|
|
|
srand(0x93846);
|
|
|
|
|
|
|
|
/* Create and initialize a RAM MTD device instance */
|
|
|
|
|
|
|
|
#ifdef CONFIG_EXAMPLES_CONFIGDATA_ARCHINIT
|
|
|
|
mtd = configdata_archinitialize();
|
|
|
|
#else
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("Creating %d byte RAM drive\n", EXAMPLES_CONFIGDATA_BUFSIZE);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
mtd = rammtd_initialize(g_simflash, EXAMPLES_CONFIGDATA_BUFSIZE);
|
|
|
|
#endif
|
|
|
|
if (!mtd)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: Failed to create RAM MTD instance\n");
|
|
|
|
fflush(stdout);
|
2013-11-04 16:05:11 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize to provide CONFIGDATA on an MTD interface */
|
|
|
|
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("Registering /dev/config device\n");
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
MTD_IOCTL(mtd, MTDIOC_BULKERASE, 0);
|
|
|
|
ret = mtdconfig_register(mtd);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: /dev/config registration failed: %d\n", -ret);
|
|
|
|
fflush(stdout);
|
2013-11-04 16:05:11 +01:00
|
|
|
exit(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Zero out our entry array */
|
|
|
|
|
|
|
|
memset(g_entries, 0, sizeof(g_entries));
|
|
|
|
|
|
|
|
/* Open the /dev/config device */
|
|
|
|
|
|
|
|
g_fd = open("/dev/config", O_RDOK);
|
|
|
|
if (g_fd == -1)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: Failed to open /dev/config %d\n", -errno);
|
|
|
|
fflush(stdout);
|
2013-11-04 16:05:11 +01:00
|
|
|
exit(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize the before memory values */
|
|
|
|
|
|
|
|
g_mmbefore = mallinfo();
|
|
|
|
|
|
|
|
/* Loop seveal times ... create some config data items, delete them
|
|
|
|
* randomly, verify them randomly, add new config items.
|
|
|
|
*/
|
|
|
|
|
|
|
|
g_ntests = g_nverified = 0;
|
|
|
|
g_ntotaldelete = g_ntotalalloc = 0;
|
|
|
|
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_NLOOPS == 0
|
|
|
|
for (i = 0; ; i++)
|
|
|
|
#else
|
|
|
|
for (i = 1; i <= CONFIG_EXAMPLES_CONFIGDATA_NLOOPS; i++)
|
|
|
|
#endif
|
|
|
|
{
|
2020-04-11 20:56:24 +02:00
|
|
|
/* Write config data to the /dev/config device until either (1) all of
|
|
|
|
* the open file structures are utilized or until (2) CONFIGDATA
|
|
|
|
* reports an error (hopefully that the /dev/config device is full)
|
2013-11-04 16:05:11 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("\n=== FILLING %u =============================\n", i);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
2020-01-02 13:09:50 +01:00
|
|
|
configdata_fillconfig();
|
2013-11-04 16:05:11 +01:00
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("Filled /dev/config\n");
|
|
|
|
printf(" Number of entries: %d\n", g_nentries);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Verify all files entries to FLASH */
|
|
|
|
|
|
|
|
ret = configdata_verifyconfig();
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: Failed to verify partition\n");
|
|
|
|
printf(" Number of entries: %d\n", g_nentries);
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("Verified!\n");
|
|
|
|
printf(" Number of entries: %d\n", g_nentries);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete some entries */
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("\n=== DELETING %u ============================\n", i);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
ret = configdata_delentries();
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: Failed to delete enries\n");
|
|
|
|
printf(" Number of entries: %d\n", g_nentries);
|
|
|
|
printf(" Number deleted: %d\n", g_ndeleted);
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("Deleted some enries\n");
|
|
|
|
printf(" Number of entries: %d\n", g_nentries);
|
|
|
|
printf(" Number deleted: %d\n", g_ndeleted);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify all files written to FLASH */
|
|
|
|
|
|
|
|
ret = configdata_verifyconfig();
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("ERROR: Failed to verify partition\n");
|
|
|
|
printf(" Number of entries: %d\n", g_nentries);
|
|
|
|
printf(" Number deleted: %d\n", g_ndeleted);
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
|
|
|
#if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("Verified!\n");
|
|
|
|
printf(" Number of entries: %d\n", g_nentries);
|
|
|
|
printf(" Number deleted: %d\n", g_ndeleted);
|
2013-11-04 16:05:11 +01:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear deleted entries */
|
|
|
|
|
|
|
|
configdata_cleardeleted();
|
|
|
|
|
|
|
|
/* Show memory usage */
|
|
|
|
|
|
|
|
#ifndef CONFIG_EXAMPLES_CONFIGDATA_SILENT
|
|
|
|
configdata_loopmemusage();
|
2014-10-08 16:33:00 +02:00
|
|
|
fflush(stdout);
|
2013-11-04 16:05:11 +01:00
|
|
|
#else
|
|
|
|
if ((i % EXAMPLES_CONFIGDATA_REPORT) == 0)
|
|
|
|
{
|
2014-10-08 16:33:00 +02:00
|
|
|
printf("%u\n", i);
|
|
|
|
fflush(stdout);
|
2013-11-04 16:05:11 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-04-11 20:56:24 +02:00
|
|
|
#if 0
|
2013-11-04 16:05:11 +01:00
|
|
|
/* Delete all files then show memory usage again */
|
|
|
|
|
2020-04-11 20:56:24 +02:00
|
|
|
configdata_delallfiles();
|
|
|
|
#endif
|
|
|
|
|
2013-11-04 16:05:11 +01:00
|
|
|
configdata_endmemusage();
|
2014-10-08 16:33:00 +02:00
|
|
|
fflush(stdout);
|
2013-11-04 16:05:11 +01:00
|
|
|
return 0;
|
|
|
|
}
|