📄 main.c
字号:
/***********************************************************************/
/* */
/* Module: main.c */
/* Release: 2004.5 */
/* Version: 2003.1 */
/* Purpose: TargetFFS Powerloss Recovery Test */
/* */
/*---------------------------------------------------------------------*/
/* */
/* This program simulates using TargetFFS to hold both the current */
/* version of an application and an upgrade that is being downloaded */
/* over a network. After the download is complete, the current copy */
/* is deleted. Subsequent boots use the latest version. */
/* */
/* This application tests TargetFFS's powerloss recovery. Two files */
/* are used: "exe1" and "exe2". At startup, the program checks that */
/* at least one of these files exists and ends with a valid four */
/* byte checksum. When files are written, they are padded to a */
/* multiple of four bytes before the checksum is appended. */
/* */
/* If both files exist and have valid checksums, the most recent */
/* becomes the boot file. The other file is used for the next down- */
/* load. The program enters an infinite loop in which a new upgrade */
/* is loaded, the old boot file is deleted, and then the boot and */
/* upgrade file names are swapped. */
/* */
/* The test is performed by "randomly" removing power while the */
/* application is running. It is a fatal error if the program is not */
/* able to mount the flash volume and find at least one valid file. */
/* */
/* Before the test can be run, the volume must be formatted and */
/* written with at least one valid file. */
/* */
/***********************************************************************/
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <targetos.h>
#include <kernel.h>
#include <sys.h>
#include "../../posix.h"
/***********************************************************************/
/* Configuration */
/***********************************************************************/
#define ID_REG 0
#define CWD_WD1 1
#define CWD_WD2 2
/***********************************************************************/
/* Local Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* error: Print error message and call fatal error handler */
/* */
/* Input: msg = pointer to error message */
/* */
/***********************************************************************/
static void error(char *msg)
{
perror(msg);
taskSleep(50);
SysFatalError(errno);
}
/***********************************************************************/
/* download: Simulate downloading a new executable over a network */
/* connection. Just write a file with semi-random values */
/* with a length that is a multiple of four bytes, then */
/* append a 32-bit checksum. */
/* */
/* Input: fname = the name of the file to be created */
/* */
/***********************************************************************/
static void download(char *fname)
{
int fid, length, rc;
ui32 i, checksum;
/*-------------------------------------------------------------------*/
/* Create the download file. */
/*-------------------------------------------------------------------*/
fid = open(fname, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IXUSR);
/*-------------------------------------------------------------------*/
/* Choose a somewhat random length >= 128KB. */
/*-------------------------------------------------------------------*/
length = (128 * 1024 + (rand() % 2048)) & ~3;
/*-------------------------------------------------------------------*/
/* Fill the download file with data. */
/*-------------------------------------------------------------------*/
length >>= 2;
checksum = 0;
for (i = 0; i < length; ++i)
{
checksum += i;
rc = write(fid, &i, sizeof(i));
if (rc != sizeof(i))
error("Unable to write file data");
}
/*-------------------------------------------------------------------*/
/* Write the 32-bit checksum. */
/*-------------------------------------------------------------------*/
rc = write(fid, &checksum, sizeof(checksum));
if (rc != sizeof(checksum))
error("Unable to write file checksum");
/*-------------------------------------------------------------------*/
/* Close the file, flushing its contents to flash. */
/*-------------------------------------------------------------------*/
close(fid);
}
/***********************************************************************/
/* valid: Check if file identifier is valid, the file length is */
/* non-zero and a multiple of four bytes, and the file */
/* ends with a 32-bit checksum of the previous contents. */
/* */
/* Input: fid = identifier of file to be checked */
/* */
/***********************************************************************/
static int valid(int fid)
{
int rc, length;
struct stat sbuf;
ui32 lword, expected, checksum;
/*-------------------------------------------------------------------*/
/* Check if the file identifier is valid. */
/*-------------------------------------------------------------------*/
if (fid == -1)
return FALSE;
/*-------------------------------------------------------------------*/
/* Read the file state information. */
/*-------------------------------------------------------------------*/
if (fstat(fid, &sbuf))
error("fstat() error in valid()");
/*-------------------------------------------------------------------*/
/* Return FALSE if the length is zero or not a multiple of four. */
/*-------------------------------------------------------------------*/
length = sbuf.st_size;
if ((length == 0) || (length & 3))
return FALSE;
/*-------------------------------------------------------------------*/
/* Read and checksum all but the last four bytes. */
/*-------------------------------------------------------------------*/
length >>= 2;
expected = checksum = 0;
while (--length)
{
rc = read(fid, &lword, sizeof(lword));
if (rc == -1)
error("read() returned -1 while reading data");
if (lword != expected)
error("data error");
checksum += lword;
++expected;
}
/*-------------------------------------------------------------------*/
/* Read and verify the checksum. */
/*-------------------------------------------------------------------*/
rc = read(fid, &lword, sizeof(lword));
if (rc == -1)
error("read() returned -1 while reading checksum");
return lword == checksum;
}
/***********************************************************************/
/* prepare: Verify most recent boot image and then load a new one */
/* */
/* Input: vol_name = pointer to volume name */
/* */
/***********************************************************************/
static void prepare(char *vol_name)
{
/*-------------------------------------------------------------------*/
/* Format and mount the volume. */
/*-------------------------------------------------------------------*/
if (format(vol_name))
error("format flash failed");
if (mount(vol_name))
error("Unable to mount flash volume!");
if (chdir(vol_name))
error("Unable to 'cd' to flash directory!");
/*-------------------------------------------------------------------*/
/* Change to volume's root directory and install "exe1". */
/*-------------------------------------------------------------------*/
download("exe1");
/*-------------------------------------------------------------------*/
/* Unmount the volume. */
/*-------------------------------------------------------------------*/
if (unmount(vol_name))
error("Unable to unmount flash volume!");
}
/***********************************************************************/
/* boot: Verify most recent boot image and then load a new one */
/* */
/* Input: vol_name = pointer to volume name */
/* */
/***********************************************************************/
static void boot(char *vol_name)
{
int fid1, fid2, valid1, valid2;
char *boot, *path, *upgrade;
/*-------------------------------------------------------------------*/
/* Mount the volume and change to its root directory. */
/*-------------------------------------------------------------------*/
if (mount(vol_name))
error("Unable to mount flash volume!");
if (chdir(vol_name))
error("Unable to 'cd' to flash directory!");
/*-------------------------------------------------------------------*/
/* Attempt to open both files. Ensure at least one exists. */
/*-------------------------------------------------------------------*/
fid1 = open("exe1", O_RDONLY);
fid2 = open("exe2", O_RDONLY);
if ((fid1 == -1) && (fid2 == -1))
error("Neither file exists!");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -