mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-23 09:01:46 +08:00
usb01: Simplify test program
This commit is contained in:
parent
8eb888394a
commit
ec5b97bed1
@ -2558,7 +2558,7 @@ def tests(mm):
|
|||||||
mod.addTest(mm.generator['test']('syscalls01', ['test_main']))
|
mod.addTest(mm.generator['test']('syscalls01', ['test_main']))
|
||||||
mod.addTest(mm.generator['test']('program01', ['test_main']))
|
mod.addTest(mm.generator['test']('program01', ['test_main']))
|
||||||
mod.addTest(mm.generator['test']('commands01', ['test_main']))
|
mod.addTest(mm.generator['test']('commands01', ['test_main']))
|
||||||
mod.addTest(mm.generator['test']('usb01', ['init', 'test-file-system'], False))
|
mod.addTest(mm.generator['test']('usb01', ['init'], False))
|
||||||
mod.addTest(mm.generator['test']('loopback01', ['test_main']))
|
mod.addTest(mm.generator['test']('loopback01', ['test_main']))
|
||||||
mod.addTest(mm.generator['test']('netshell01', ['test_main', 'shellconfig'], False))
|
mod.addTest(mm.generator['test']('netshell01', ['test_main', 'shellconfig'], False))
|
||||||
mod.addTest(mm.generator['test']('swi01', ['init', 'swi_test']))
|
mod.addTest(mm.generator['test']('swi01', ['init', 'swi_test']))
|
||||||
|
@ -1580,8 +1580,7 @@ def build(bld):
|
|||||||
lib = ["m", "z"],
|
lib = ["m", "z"],
|
||||||
install_path = None)
|
install_path = None)
|
||||||
|
|
||||||
test_usb01 = ['testsuite/usb01/init.c',
|
test_usb01 = ['testsuite/usb01/init.c']
|
||||||
'testsuite/usb01/test-file-system.c']
|
|
||||||
bld.program(target = "usb01.exe",
|
bld.program(target = "usb01.exe",
|
||||||
features = "cprogram",
|
features = "cprogram",
|
||||||
cflags = cflags,
|
cflags = cflags,
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
> + Sebastian.. any test code that would initialize all this?
|
|
||||||
> Any advice and/or sample code on this is really valued
|
|
||||||
> as this is the next step.
|
|
||||||
>
|
|
||||||
> Basically anything that would help me get this initialized
|
|
||||||
> and have some confidence before I make it available.
|
|
||||||
|
|
||||||
Attached are two source files of a simple USB demo.
|
|
||||||
|
|
||||||
https://www.rtems.org/bugzilla/show_bug.cgi?id=1601
|
|
||||||
|
|
||||||
The FreeBSD initialization is performed in mi_startup() (file
|
|
||||||
init_main.c). Use the demo and single step through this with the
|
|
||||||
debugger. A lot is done with linker sets, e.g. the driver initialization.
|
|
||||||
|
|
||||||
Look at c/src/lib/libbsp/arm/shared/startup/linkcmds.base and search for
|
|
||||||
"_bsd".
|
|
||||||
|
|
||||||
See (with links in "SEE ALSO"):
|
|
||||||
|
|
||||||
http://www.freebsd.org/cgi/man.cgi?query=SYSINIT&sektion=9&apropos=0&manpath=FreeBSD+9-current
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @ingroup demo
|
|
||||||
*
|
|
||||||
* @brief Shell configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 embedded brains GmbH. All rights reserved.
|
|
||||||
*
|
|
||||||
* embedded brains GmbH
|
|
||||||
* Obere Lagerstr. 30
|
|
||||||
* 82178 Puchheim
|
|
||||||
* Germany
|
|
||||||
* <rtems@embedded-brains.de>
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.com/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DEMO_SHELL_BLOCK_DEVICES_H
|
|
||||||
#define DEMO_SHELL_BLOCK_DEVICES_H
|
|
||||||
|
|
||||||
#include "demo-shell-minimal.h"
|
|
||||||
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_FDISK
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_BLKSYNC
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_MSDOSFMT
|
|
||||||
|
|
||||||
#endif /* DEMO_SHELL_BLOCK_DEVICES_H */
|
|
@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @ingroup demo
|
|
||||||
*
|
|
||||||
* @brief Shell configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 embedded brains GmbH. All rights reserved.
|
|
||||||
*
|
|
||||||
* embedded brains GmbH
|
|
||||||
* Obere Lagerstr. 30
|
|
||||||
* 82178 Puchheim
|
|
||||||
* Germany
|
|
||||||
* <rtems@embedded-brains.de>
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.com/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DEMO_SHELL_MINIMAL_H
|
|
||||||
#define DEMO_SHELL_MINIMAL_H
|
|
||||||
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_CPUUSE
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_PERIODUSE
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_STACKUSE
|
|
||||||
|
|
||||||
#if defined(BSP_HAS_IRQ_INFO)
|
|
||||||
#include <bsp/irq-info.h>
|
|
||||||
|
|
||||||
#define CONFIGURE_SHELL_USER_COMMANDS \
|
|
||||||
&bsp_interrupt_shell_command
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* DEMO_SHELL_MINIMAL_H */
|
|
@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @ingroup demo
|
|
||||||
*
|
|
||||||
* @brief Shell configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 embedded brains GmbH. All rights reserved.
|
|
||||||
*
|
|
||||||
* embedded brains GmbH
|
|
||||||
* Obere Lagerstr. 30
|
|
||||||
* 82178 Puchheim
|
|
||||||
* Germany
|
|
||||||
* <rtems@embedded-brains.de>
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.com/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DEMO_SHELL_H
|
|
||||||
#define DEMO_SHELL_H
|
|
||||||
|
|
||||||
#include "demo-shell-minimal.h"
|
|
||||||
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_CP
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_PWD
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_LS
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_CHDIR
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_CD
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_MKDIR
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_RMDIR
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_CAT
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_MV
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_RM
|
|
||||||
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_WKSPACE_INFO
|
|
||||||
|
|
||||||
#define CONFIGURE_SHELL_COMMAND_RTC
|
|
||||||
|
|
||||||
#endif /* DEMO_SHELL_H */
|
|
@ -1,319 +1,190 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @brief File system test.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010-2012 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2010, 2016 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* found in the file LICENSE in this distribution or at
|
* modification, are permitted provided that the following conditions
|
||||||
* http://www.rtems.com/license/LICENSE.
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include <rtems.h>
|
#include <rtems/bdbuf.h>
|
||||||
#include <rtems/media.h>
|
|
||||||
#include <rtems/chain.h>
|
|
||||||
#include <rtems/libio_.h>
|
|
||||||
#include <rtems/shell.h>
|
|
||||||
#include <rtems/console.h>
|
#include <rtems/console.h>
|
||||||
#include <rtems/diskdevs.h>
|
#include <rtems/media.h>
|
||||||
|
#include <rtems/shell.h>
|
||||||
#include <rtems/bsd/bsd.h>
|
#include <rtems/bsd/bsd.h>
|
||||||
|
|
||||||
#include "test.h"
|
#define TEST_NAME "LIBBSD USB 1"
|
||||||
|
|
||||||
#define ASSERT_SC(sc) assert((sc) == RTEMS_SUCCESSFUL)
|
static rtems_status_code
|
||||||
|
media_listener(rtems_media_event event, rtems_media_state state,
|
||||||
#define ASSERT_ENO(eno) assert((eno) == 0)
|
const char *src, const char *dest, void *arg)
|
||||||
|
|
||||||
#define WORKER_COUNT 13
|
|
||||||
|
|
||||||
#define WORKER_EVENT RTEMS_EVENT_13
|
|
||||||
|
|
||||||
void test_file_system(unsigned index, const char *disk_path, const char *mount_path);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_chain_node node;
|
|
||||||
char *disk_or_partition_path;
|
|
||||||
rtems_id task;
|
|
||||||
} worker;
|
|
||||||
|
|
||||||
static worker worker_table [WORKER_COUNT];
|
|
||||||
|
|
||||||
RTEMS_CHAIN_DEFINE_EMPTY(free_worker_list);
|
|
||||||
|
|
||||||
static const rtems_name WORKER_NAME = rtems_build_name('W', 'O', 'R', 'K');
|
|
||||||
|
|
||||||
static pthread_mutex_t worker_mutex;
|
|
||||||
|
|
||||||
static pthread_cond_t worker_changed;
|
|
||||||
|
|
||||||
static void add_worker_to_free_list(worker *w)
|
|
||||||
{
|
{
|
||||||
rtems_chain_append(&free_worker_list, &w->node);
|
printf(
|
||||||
|
"media listener: event = %s, state = %s, src = %s",
|
||||||
|
rtems_media_event_description(event),
|
||||||
|
rtems_media_state_description(state),
|
||||||
|
src
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dest != NULL) {
|
||||||
|
printf(", dest = %s", dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg != NULL) {
|
||||||
|
printf(", arg = %p\n", arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (event == RTEMS_MEDIA_EVENT_MOUNT && state == RTEMS_MEDIA_STATE_SUCCESS) {
|
||||||
|
char name[256];
|
||||||
|
int n = snprintf(&name[0], sizeof(name), "%s/test.txt", dest);
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
assert(n < (int) sizeof(name));
|
||||||
|
|
||||||
|
printf("write file %s\n", &name[0]);
|
||||||
|
file = fopen(&name[0], "w");
|
||||||
|
if (file != NULL) {
|
||||||
|
const char hello[] = "Hello, world!\n";
|
||||||
|
|
||||||
|
fwrite(&hello[0], sizeof(hello) - 1, 1, file);
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static worker *get_free_worker(void)
|
static void
|
||||||
|
Init(rtems_task_argument arg)
|
||||||
{
|
{
|
||||||
return (worker *) rtems_chain_get(&free_worker_list);
|
rtems_status_code sc;
|
||||||
|
|
||||||
|
(void) arg;
|
||||||
|
puts( "*** " TEST_NAME " TEST ***" );
|
||||||
|
|
||||||
|
sc = rtems_bdbuf_init();
|
||||||
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_media_initialize();
|
||||||
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_media_listener_add(media_listener, NULL);
|
||||||
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_media_server_initialize(
|
||||||
|
200,
|
||||||
|
32 * 1024,
|
||||||
|
RTEMS_DEFAULT_MODES,
|
||||||
|
RTEMS_DEFAULT_ATTRIBUTES
|
||||||
|
);
|
||||||
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_bsd_initialize();
|
||||||
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_shell_init("SHLL", 16 * 1024, 1, CONSOLE_DEVICE_NAME,
|
||||||
|
false, true, NULL);
|
||||||
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_worker(char *disk_or_partition_path)
|
#define CONFIGURE_MICROSECONDS_PER_TICK 1000
|
||||||
{
|
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
|
||||||
worker *w = get_free_worker();
|
|
||||||
|
|
||||||
if (w != NULL) {
|
|
||||||
w->disk_or_partition_path = disk_or_partition_path;
|
|
||||||
|
|
||||||
sc = rtems_event_send(w->task, WORKER_EVENT);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
} else {
|
|
||||||
free(disk_or_partition_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static worker *find_worker_for_disk_or_partition(const char *disk_or_partition_path)
|
|
||||||
{
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < WORKER_COUNT; ++i) {
|
|
||||||
worker *w = &worker_table [i];
|
|
||||||
|
|
||||||
if (w->disk_or_partition_path != NULL && strcmp(w->disk_or_partition_path, disk_or_partition_path) == 0) {
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wait_for_worker_finished(const char *disk_or_partition_path)
|
|
||||||
{
|
|
||||||
int eno = 0;
|
|
||||||
worker *w = NULL;
|
|
||||||
|
|
||||||
eno = pthread_mutex_lock(&worker_mutex);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
|
|
||||||
w = find_worker_for_disk_or_partition(disk_or_partition_path);
|
|
||||||
|
|
||||||
if (w != NULL) {
|
|
||||||
while (w->disk_or_partition_path != NULL) {
|
|
||||||
eno = pthread_cond_wait(&worker_changed, &worker_mutex);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eno = pthread_mutex_unlock(&worker_mutex);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
}
|
|
||||||
|
|
||||||
static rtems_status_code media_listener(rtems_media_event event, rtems_media_state state, const char *src, const char *dest, void *arg)
|
|
||||||
{
|
|
||||||
rtems_status_code rsc = RTEMS_SUCCESSFUL;
|
|
||||||
char *disk_or_partition_path = NULL;
|
|
||||||
|
|
||||||
printf("media listener: event = %s, state = %s, src = %s", rtems_media_event_description(event), rtems_media_state_description(state), src);
|
|
||||||
|
|
||||||
if (dest != NULL) {
|
|
||||||
printf(", dest = %s", dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg != NULL) {
|
|
||||||
printf(", arg = %p\n", arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (state == RTEMS_MEDIA_STATE_INQUIRY) {
|
|
||||||
if (event == RTEMS_MEDIA_EVENT_MOUNT) {
|
|
||||||
rsc = RTEMS_IO_ERROR;
|
|
||||||
} else if (event == RTEMS_MEDIA_EVENT_PARTITION_DETACH || event == RTEMS_MEDIA_EVENT_DISK_DETACH) {
|
|
||||||
wait_for_worker_finished(src);
|
|
||||||
} else if (event == RTEMS_MEDIA_EVENT_UNMOUNT) {
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
} else if (state == RTEMS_MEDIA_STATE_SUCCESS) {
|
|
||||||
if (event == RTEMS_MEDIA_EVENT_PARTITION_ATTACH) {
|
|
||||||
disk_or_partition_path = strdup(dest);
|
|
||||||
}
|
|
||||||
} else if (state == RTEMS_MEDIA_STATE_FAILED) {
|
|
||||||
if (event == RTEMS_MEDIA_EVENT_PARTITION_INQUIRY) {
|
|
||||||
disk_or_partition_path = strdup(src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disk_or_partition_path != NULL) {
|
|
||||||
activate_worker(disk_or_partition_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rsc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void worker_finished(worker *w)
|
|
||||||
{
|
|
||||||
int eno = 0;
|
|
||||||
|
|
||||||
eno = pthread_mutex_lock(&worker_mutex);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
|
|
||||||
free(w->disk_or_partition_path);
|
|
||||||
w->disk_or_partition_path = NULL;
|
|
||||||
|
|
||||||
eno = pthread_cond_broadcast(&worker_changed);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
|
|
||||||
eno = pthread_mutex_unlock(&worker_mutex);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void worker_task(rtems_task_argument arg)
|
|
||||||
{
|
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
|
||||||
unsigned index = arg;
|
|
||||||
worker *self = &worker_table [index];
|
|
||||||
char mount_path [] = "/work/????";
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
rv = snprintf(mount_path, sizeof(mount_path), "/work/%u", index);
|
|
||||||
assert(rv < (int) sizeof(mount_path));
|
|
||||||
|
|
||||||
sc = rtems_libio_set_private_env();
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
rv = rtems_mkdir(mount_path, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
||||||
assert(rv == 0);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
rtems_event_set events = 0;
|
|
||||||
|
|
||||||
sc = rtems_event_receive(WORKER_EVENT, RTEMS_EVENT_ALL | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
test_file_system(index, self->disk_or_partition_path, mount_path);
|
|
||||||
|
|
||||||
worker_finished(self);
|
|
||||||
|
|
||||||
add_worker_to_free_list(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char mac_address [6] = { 0x00, 0x1a, 0xf1, 0x00, 0x07, 0xa4 };
|
|
||||||
|
|
||||||
static void Init(rtems_task_argument arg)
|
|
||||||
{
|
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
|
||||||
int eno = 0;
|
|
||||||
rtems_id id = RTEMS_ID_NONE;
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
eno = pthread_mutex_init(&worker_mutex, NULL);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
|
|
||||||
eno = pthread_cond_init(&worker_changed, NULL);
|
|
||||||
ASSERT_ENO(eno);
|
|
||||||
|
|
||||||
for (i = 0; i < WORKER_COUNT; ++i) {
|
|
||||||
worker *w = &worker_table [i];
|
|
||||||
|
|
||||||
sc = rtems_task_create(
|
|
||||||
WORKER_NAME,
|
|
||||||
95 + 10 * (i % 4),
|
|
||||||
32 * 1024,
|
|
||||||
RTEMS_DEFAULT_MODES,
|
|
||||||
RTEMS_FLOATING_POINT,
|
|
||||||
&id
|
|
||||||
);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
w->task = id;
|
|
||||||
add_worker_to_free_list(w);
|
|
||||||
|
|
||||||
sc = rtems_task_start(id, worker_task, i);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
sc = rtems_disk_io_initialize();
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
sc = rtems_media_initialize();
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
sc = rtems_media_listener_add(media_listener, NULL);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
sc = rtems_media_server_initialize(200, 32 * 1024, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
sc = rtems_bsd_initialize();
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
sc = rtems_shell_init(
|
|
||||||
"SHLL",
|
|
||||||
16 * 1024,
|
|
||||||
10,
|
|
||||||
CONSOLE_DEVICE_NAME,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
|
||||||
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
|
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
|
||||||
|
|
||||||
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
#define CONFIGURE_MAXIMUM_DRIVERS 32
|
||||||
|
|
||||||
#define CONFIGURE_FILESYSTEM_IMFS
|
|
||||||
#define CONFIGURE_FILESYSTEM_DOSFS
|
#define CONFIGURE_FILESYSTEM_DOSFS
|
||||||
|
|
||||||
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
|
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
|
||||||
|
|
||||||
#define CONFIGURE_BDBUF_BUFFER_MIN_SIZE 512
|
|
||||||
#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE 512
|
|
||||||
#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (WORKER_COUNT * 512)
|
|
||||||
#define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS 0
|
|
||||||
|
|
||||||
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
|
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
|
||||||
|
|
||||||
#define CONFIGURE_UNLIMITED_OBJECTS
|
#define CONFIGURE_UNLIMITED_OBJECTS
|
||||||
|
|
||||||
#define CONFIGURE_UNIFIED_WORK_AREAS
|
#define CONFIGURE_UNIFIED_WORK_AREAS
|
||||||
|
|
||||||
|
#define CONFIGURE_STACK_CHECKER_ENABLED
|
||||||
|
|
||||||
|
#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024)
|
||||||
|
#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (256 * 1024)
|
||||||
|
|
||||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
|
|
||||||
|
#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
|
||||||
|
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
|
||||||
#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
|
#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
|
||||||
|
|
||||||
#define CONFIGURE_STACK_CHECKER_ENABLED
|
|
||||||
|
|
||||||
#define CONFIGURE_INIT
|
#define CONFIGURE_INIT
|
||||||
|
|
||||||
#include <rtems/confdefs.h>
|
#include <rtems/confdefs.h>
|
||||||
|
|
||||||
|
#include <bsp/nexus-devices.h>
|
||||||
|
|
||||||
#define CONFIGURE_SHELL_COMMANDS_INIT
|
#define CONFIGURE_SHELL_COMMANDS_INIT
|
||||||
|
|
||||||
#include "demo-shell.h"
|
#include <bsp/irq-info.h>
|
||||||
#include "demo-shell-block-devices.h"
|
|
||||||
|
#include <rtems/netcmds-config.h>
|
||||||
|
|
||||||
|
#define CONFIGURE_SHELL_USER_COMMANDS \
|
||||||
|
&bsp_interrupt_shell_command, \
|
||||||
|
&rtems_shell_SYSCTL_Command
|
||||||
|
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_CPUUSE
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_PERIODUSE
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_STACKUSE
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_PROFREPORT
|
||||||
|
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_CP
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_PWD
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_LS
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_LN
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_LSOF
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_CHDIR
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_CD
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_MKDIR
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_RMDIR
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_CAT
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_MV
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_RM
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO
|
||||||
|
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_BLKSTATS
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_BLKSYNC
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_MOUNT
|
||||||
|
#define CONFIGURE_SHELL_COMMAND_UNMOUNT
|
||||||
|
|
||||||
#include <rtems/shellconfig.h>
|
#include <rtems/shellconfig.h>
|
||||||
|
|
||||||
#define USB_SYSINIT_INIT
|
|
||||||
|
|
||||||
#include "usb-sysinit.h"
|
|
||||||
|
@ -1,593 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @brief File system test implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 embedded brains GmbH. All rights reserved.
|
|
||||||
*
|
|
||||||
* embedded brains GmbH
|
|
||||||
* Obere Lagerstr. 30
|
|
||||||
* 82178 Puchheim
|
|
||||||
* Germany
|
|
||||||
* <rtems@embedded-brains.de>
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.com/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/libio.h>
|
|
||||||
#include <rtems/dosfs.h>
|
|
||||||
|
|
||||||
#include "test.h"
|
|
||||||
|
|
||||||
#define ASSERT_SC(sc) assert((sc) == RTEMS_SUCCESSFUL)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Test states.
|
|
||||||
*
|
|
||||||
* digraph {
|
|
||||||
* INIT -> MOUNT;
|
|
||||||
* MOUNT -> INIT_ROOT;
|
|
||||||
* MOUNT -> FORMAT;
|
|
||||||
* INIT_ROOT -> CHOOSE_DIR_ACTION
|
|
||||||
* INIT_ROOT -> ERROR;
|
|
||||||
* CHOOSE_DIR_ACTION -> DIR_OPEN;
|
|
||||||
* CHOOSE_DIR_ACTION -> DIR_CLOSE;
|
|
||||||
* CHOOSE_DIR_ACTION -> DIR_CREATE;
|
|
||||||
* CHOOSE_DIR_ACTION -> DIR_DELETE;
|
|
||||||
* CHOOSE_DIR_ACTION -> DIR_SLEEP;
|
|
||||||
* DIR_OPEN -> CHOOSE_DIR_ACTION;
|
|
||||||
* DIR_OPEN -> CHOOSE_FILE_ACTION;
|
|
||||||
* DIR_OPEN -> ERROR;
|
|
||||||
* DIR_CLOSE -> CHOOSE_DIR_ACTION;
|
|
||||||
* DIR_CLOSE -> ERROR;
|
|
||||||
* DIR_CREATE -> CHOOSE_DIR_ACTION;
|
|
||||||
* DIR_CREATE -> DIR_DELETE;
|
|
||||||
* DIR_CREATE -> ERROR;
|
|
||||||
* DIR_DELETE -> CHOOSE_DIR_ACTION;
|
|
||||||
* DIR_DELETE -> ERROR;
|
|
||||||
* DIR_SLEEP -> CHOOSE_DIR_ACTION;
|
|
||||||
* CHOOSE_FILE_ACTION -> FILE_CLOSE;
|
|
||||||
* CHOOSE_FILE_ACTION -> FILE_APPEND;
|
|
||||||
* CHOOSE_FILE_ACTION -> FILE_SLEEP;
|
|
||||||
* FILE_CLOSE -> CHOOSE_DIR_ACTION;
|
|
||||||
* FILE_CLOSE -> ERROR;
|
|
||||||
* FILE_APPEND -> CHOOSE_FILE_ACTION;
|
|
||||||
* FILE_APPEND -> ERROR;
|
|
||||||
* FILE_SLEEP -> CHOOSE_FILE_ACTION;
|
|
||||||
* ERROR -> FORMAT;
|
|
||||||
* FORMAT -> MOUNT;
|
|
||||||
* FORMAT -> FINISH;
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
CHOOSE_DIR_ACTION,
|
|
||||||
CHOOSE_FILE_ACTION,
|
|
||||||
DIR_CLOSE,
|
|
||||||
DIR_CREATE,
|
|
||||||
DIR_DELETE,
|
|
||||||
DIR_OPEN,
|
|
||||||
DIR_SLEEP,
|
|
||||||
ERROR,
|
|
||||||
FILE_APPEND,
|
|
||||||
FILE_CLOSE,
|
|
||||||
FILE_SLEEP,
|
|
||||||
FINISH,
|
|
||||||
FORMAT,
|
|
||||||
INIT,
|
|
||||||
INIT_ROOT,
|
|
||||||
MOUNT
|
|
||||||
} test_state;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DIR *dir;
|
|
||||||
unsigned level;
|
|
||||||
unsigned content_count;
|
|
||||||
int fd;
|
|
||||||
int eno;
|
|
||||||
} fs_state;
|
|
||||||
|
|
||||||
static test_state do_format(unsigned index, fs_state *fs, const char *disk_path)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
printf("[%02u]: format: %s\n", index, disk_path);
|
|
||||||
|
|
||||||
rv = msdos_format(disk_path, NULL);
|
|
||||||
if (rv == 0) {
|
|
||||||
return MOUNT;
|
|
||||||
} else {
|
|
||||||
fs->eno = errno;
|
|
||||||
|
|
||||||
return FINISH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned get_bucket(unsigned count)
|
|
||||||
{
|
|
||||||
long unsigned unit = (1U << 31) / count;
|
|
||||||
long unsigned bucket = (long unsigned) lrand48() / unit;
|
|
||||||
|
|
||||||
if (bucket != count) {
|
|
||||||
return bucket;
|
|
||||||
} else {
|
|
||||||
return bucket - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_choose_dir_action(void)
|
|
||||||
{
|
|
||||||
switch (get_bucket(8)) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
return DIR_CLOSE;
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
return DIR_CREATE;
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
return DIR_OPEN;
|
|
||||||
case 6:
|
|
||||||
return DIR_DELETE;
|
|
||||||
case 7:
|
|
||||||
return DIR_SLEEP;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_choose_file_action(void)
|
|
||||||
{
|
|
||||||
switch (get_bucket(3)) {
|
|
||||||
case 0:
|
|
||||||
return FILE_CLOSE;
|
|
||||||
case 1:
|
|
||||||
return FILE_SLEEP;
|
|
||||||
case 2:
|
|
||||||
return FILE_APPEND;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_normal_entry(const char *entry_name)
|
|
||||||
{
|
|
||||||
return strcmp(entry_name, ".") != 0 && strcmp(entry_name, "..") != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool open_dir(fs_state *fs, const char *dir_path)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
bool change_dir = true;
|
|
||||||
|
|
||||||
if (dir_path == NULL) {
|
|
||||||
if (fs->level > 1) {
|
|
||||||
rv = chdir("..");
|
|
||||||
if (rv != 0) {
|
|
||||||
fs->eno = errno;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
--fs->level;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
dir_path = ".";
|
|
||||||
change_dir = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs->dir != NULL) {
|
|
||||||
rv = closedir(fs->dir);
|
|
||||||
if (rv != 0) {
|
|
||||||
fs->eno = errno;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fs->content_count = 0;
|
|
||||||
fs->dir = opendir(dir_path);
|
|
||||||
|
|
||||||
if (fs->dir != NULL) {
|
|
||||||
struct dirent *de = NULL;
|
|
||||||
|
|
||||||
rewinddir(fs->dir);
|
|
||||||
while ((de = readdir(fs->dir)) != NULL) {
|
|
||||||
if (is_normal_entry(de->d_name)) {
|
|
||||||
++fs->content_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fs->eno = errno;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (change_dir) {
|
|
||||||
rv = chdir(dir_path);
|
|
||||||
if (rv != 0) {
|
|
||||||
fs->eno = errno;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
++fs->level;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *get_dir_entry(fs_state *fs, bool *is_dir)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
char *entry_name = NULL;
|
|
||||||
|
|
||||||
if (fs->content_count > 0) {
|
|
||||||
struct dirent *de = NULL;
|
|
||||||
unsigned bucket = get_bucket(fs->content_count);
|
|
||||||
unsigned i = 0;
|
|
||||||
|
|
||||||
rewinddir(fs->dir);
|
|
||||||
while ((de = readdir(fs->dir)) != NULL) {
|
|
||||||
if (is_normal_entry(de->d_name)) {
|
|
||||||
if (i != bucket) {
|
|
||||||
++i;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (de != NULL) {
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
rv = stat(de->d_name, &st);
|
|
||||||
if (rv == 0) {
|
|
||||||
*is_dir = S_ISDIR(st.st_mode);
|
|
||||||
|
|
||||||
entry_name = strdup(de->d_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static test_state do_init_root(unsigned index, fs_state *fs, const char *mount_path)
|
|
||||||
{
|
|
||||||
printf("[%02u]: init root: %s\n", index, mount_path);
|
|
||||||
|
|
||||||
if (open_dir(fs, mount_path)) {
|
|
||||||
return CHOOSE_DIR_ACTION;
|
|
||||||
} else {
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_dir_close(unsigned index, fs_state *fs)
|
|
||||||
{
|
|
||||||
if (fs->level > 1) {
|
|
||||||
printf("[%02u]: close dir\n", index);
|
|
||||||
|
|
||||||
if (open_dir(fs, NULL)) {
|
|
||||||
return CHOOSE_DIR_ACTION;
|
|
||||||
} else {
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return CHOOSE_DIR_ACTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_dir_create(unsigned index, fs_state *fs)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
test_state state = ERROR;
|
|
||||||
long number = lrand48();
|
|
||||||
char name [64];
|
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "%li", number);
|
|
||||||
|
|
||||||
if ((number % 2) == 0) {
|
|
||||||
printf("[%02u]: create file: %s\n", index, name);
|
|
||||||
|
|
||||||
rv = open(name, O_RDONLY | O_CREAT, 0777);
|
|
||||||
|
|
||||||
if (rv >= 0) {
|
|
||||||
rv = close(rv);
|
|
||||||
|
|
||||||
if (rv == 0) {
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
}
|
|
||||||
} else if (errno == ENOSPC) {
|
|
||||||
state = DIR_DELETE;
|
|
||||||
} else {
|
|
||||||
fs->eno = errno;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("[%02u]: create dir: %s\n", index, name);
|
|
||||||
|
|
||||||
rv = mkdir(name, 0777);
|
|
||||||
|
|
||||||
if (rv == 0) {
|
|
||||||
++fs->content_count;
|
|
||||||
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
} else if (errno == EEXIST) {
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
} else if (errno == ENOSPC) {
|
|
||||||
state = DIR_DELETE;
|
|
||||||
} else {
|
|
||||||
fs->eno = errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_dir_delete(unsigned index, fs_state *fs)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
test_state state = ERROR;
|
|
||||||
|
|
||||||
if (fs->content_count > 0) {
|
|
||||||
bool is_dir = false;
|
|
||||||
char *dir_entry_path = get_dir_entry(fs, &is_dir);
|
|
||||||
|
|
||||||
if (dir_entry_path != NULL) {
|
|
||||||
if (is_dir) {
|
|
||||||
printf("[%02u]: remove dir: %s\n", index, dir_entry_path);
|
|
||||||
|
|
||||||
rv = rmdir(dir_entry_path);
|
|
||||||
} else {
|
|
||||||
printf("[%02u]: remove file: %s\n", index, dir_entry_path);
|
|
||||||
|
|
||||||
rv = unlink(dir_entry_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rv == 0) {
|
|
||||||
--fs->content_count;
|
|
||||||
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
} else if (errno == ENOTEMPTY) {
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
} else {
|
|
||||||
fs->eno = errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(dir_entry_path);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_dir_open(unsigned index, fs_state *fs)
|
|
||||||
{
|
|
||||||
test_state state = ERROR;
|
|
||||||
|
|
||||||
if (fs->content_count > 0) {
|
|
||||||
bool is_dir = false;
|
|
||||||
char *dir_entry_path = get_dir_entry(fs, &is_dir);
|
|
||||||
|
|
||||||
if (dir_entry_path != NULL) {
|
|
||||||
if (is_dir) {
|
|
||||||
printf("[%02u]: open dir: %s\n", index, dir_entry_path);
|
|
||||||
|
|
||||||
if (open_dir(fs, dir_entry_path)) {
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("[%02u]: open file: %s\n", index, dir_entry_path);
|
|
||||||
|
|
||||||
fs->fd = open(dir_entry_path, O_WRONLY | O_APPEND);
|
|
||||||
|
|
||||||
if (fs->fd >= 0) {
|
|
||||||
state = CHOOSE_FILE_ACTION;
|
|
||||||
} else {
|
|
||||||
fs->eno = errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(dir_entry_path);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_file_append(unsigned index, fs_state *fs)
|
|
||||||
{
|
|
||||||
static const char buf [511];
|
|
||||||
test_state state = ERROR;
|
|
||||||
ssize_t n = 0;
|
|
||||||
|
|
||||||
printf("[%02u]: append to file\n", index);
|
|
||||||
|
|
||||||
n = write(fs->fd, buf, sizeof(buf));
|
|
||||||
|
|
||||||
if (n == (ssize_t) sizeof(buf)) {
|
|
||||||
state = CHOOSE_FILE_ACTION;
|
|
||||||
} else if (n == -1) {
|
|
||||||
fs->eno = errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_file_close(unsigned index, fs_state *fs)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
test_state state = ERROR;
|
|
||||||
|
|
||||||
printf("[%02u]: close file\n", index);
|
|
||||||
|
|
||||||
rv = close(fs->fd);
|
|
||||||
fs->fd = -1;
|
|
||||||
|
|
||||||
if (rv == 0) {
|
|
||||||
state = CHOOSE_DIR_ACTION;
|
|
||||||
} else {
|
|
||||||
fs->eno = errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_sleep(unsigned index, test_state state)
|
|
||||||
{
|
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
|
||||||
rtems_interval ms = ((rtems_interval) get_bucket(10) + 1) * 100;
|
|
||||||
rtems_interval interval = ms / rtems_configuration_get_milliseconds_per_tick();
|
|
||||||
|
|
||||||
printf("[%02u]: sleep: %" PRIu32 " ms\n", index, ms);
|
|
||||||
|
|
||||||
sc = rtems_task_wake_after(interval);
|
|
||||||
ASSERT_SC(sc);
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_mount(unsigned index, const char *disk_path, const char *mount_path)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
printf("[%02u]: mount: %s -> %s\n", index, disk_path, mount_path);
|
|
||||||
|
|
||||||
rv = mount_and_make_target_path(
|
|
||||||
disk_path,
|
|
||||||
mount_path,
|
|
||||||
RTEMS_FILESYSTEM_TYPE_DOSFS,
|
|
||||||
RTEMS_FILESYSTEM_READ_WRITE,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (rv == 0) {
|
|
||||||
return INIT_ROOT;
|
|
||||||
} else {
|
|
||||||
return FORMAT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static test_state do_error(unsigned index, fs_state *fs, const char *mount_path)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
if (fs->eno > 0) {
|
|
||||||
printf("[%02u]: error: %s\n", index, strerror(fs->eno));
|
|
||||||
} else {
|
|
||||||
printf("[%02u]: error\n", index);
|
|
||||||
}
|
|
||||||
fs->eno = 0;
|
|
||||||
|
|
||||||
if (fs->fd >= 0) {
|
|
||||||
close(fs->fd);
|
|
||||||
fs->fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs->dir != NULL) {
|
|
||||||
closedir(fs->dir);
|
|
||||||
fs->dir = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
chdir("/");
|
|
||||||
fs->level = 0;
|
|
||||||
|
|
||||||
rv = unmount(mount_path);
|
|
||||||
if (rv == 0) {
|
|
||||||
return FORMAT;
|
|
||||||
} else {
|
|
||||||
return FINISH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_file_system(unsigned index, const char *disk_path, const char *mount_path)
|
|
||||||
{
|
|
||||||
test_state state = INIT;
|
|
||||||
fs_state fs = {
|
|
||||||
.dir = NULL,
|
|
||||||
.level = 0,
|
|
||||||
.content_count = 0,
|
|
||||||
.fd = -1,
|
|
||||||
.eno = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
printf("[%02u]: start\n", index);
|
|
||||||
|
|
||||||
while (state != FINISH) {
|
|
||||||
switch (state) {
|
|
||||||
case CHOOSE_DIR_ACTION:
|
|
||||||
state = do_choose_dir_action();
|
|
||||||
break;
|
|
||||||
case CHOOSE_FILE_ACTION:
|
|
||||||
state = do_choose_file_action();
|
|
||||||
break;
|
|
||||||
case DIR_CLOSE:
|
|
||||||
state = do_dir_close(index, &fs);
|
|
||||||
break;
|
|
||||||
case DIR_CREATE:
|
|
||||||
state = do_dir_create(index, &fs);
|
|
||||||
break;
|
|
||||||
case DIR_DELETE:
|
|
||||||
state = do_dir_delete(index, &fs);
|
|
||||||
break;
|
|
||||||
case DIR_OPEN:
|
|
||||||
state = do_dir_open(index, &fs);
|
|
||||||
break;
|
|
||||||
case DIR_SLEEP:
|
|
||||||
state = do_sleep(index, CHOOSE_DIR_ACTION);
|
|
||||||
break;
|
|
||||||
case ERROR:
|
|
||||||
state = do_error(index, &fs, mount_path);
|
|
||||||
break;
|
|
||||||
case FILE_APPEND:
|
|
||||||
state = do_file_append(index, &fs);
|
|
||||||
break;
|
|
||||||
case FILE_CLOSE:
|
|
||||||
state = do_file_close(index, &fs);
|
|
||||||
break;
|
|
||||||
case FILE_SLEEP:
|
|
||||||
state = do_sleep(index, CHOOSE_FILE_ACTION);
|
|
||||||
break;
|
|
||||||
case FORMAT:
|
|
||||||
state = do_format(index, &fs, disk_path);
|
|
||||||
break;
|
|
||||||
case INIT:
|
|
||||||
state = MOUNT;
|
|
||||||
break;
|
|
||||||
case INIT_ROOT:
|
|
||||||
state = do_init_root(index, &fs, mount_path);
|
|
||||||
break;
|
|
||||||
case MOUNT:
|
|
||||||
state = do_mount(index, disk_path, mount_path);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("[%02u]: finish\n", index);
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @ingroup demo
|
|
||||||
*
|
|
||||||
* @brief Test samples.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2010 embedded brains GmbH. All rights reserved.
|
|
||||||
*
|
|
||||||
* embedded brains GmbH
|
|
||||||
* Obere Lagerstr. 30
|
|
||||||
* 82178 Puchheim
|
|
||||||
* Germany
|
|
||||||
* <rtems@embedded-brains.de>
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.com/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DEMO_TEST_H
|
|
||||||
#define DEMO_TEST_H
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup demo
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
void test_file_system(unsigned index, const char *disk_path, const char *mount_path);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif /* DEMO_TEST_H */
|
|
@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @ingroup demo
|
|
||||||
*
|
|
||||||
* @brief USB system initialization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2009-2012 embedded brains GmbH. All rights reserved.
|
|
||||||
*
|
|
||||||
* embedded brains GmbH
|
|
||||||
* Obere Lagerstr. 30
|
|
||||||
* 82178 Puchheim
|
|
||||||
* Germany
|
|
||||||
* <rtems@embedded-brains.de>
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.com/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <machine/rtems-bsd-sysinit.h>
|
|
||||||
|
|
||||||
#include <bsp.h>
|
|
||||||
|
|
||||||
#ifdef USB_SYSINIT_INIT
|
|
||||||
|
|
||||||
#if defined(LIBBSP_ARM_LPC24XX_BSP_H) || defined(LIBBSP_ARM_LPC32XX_BSP_H)
|
|
||||||
#define NEED_USB_OHCI
|
|
||||||
#elif defined(__GEN83xx_BSP_h) || defined(LIBBSP_POWERPC_QORIQ_BSP_H)
|
|
||||||
#define NEED_USB_EHCI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SYSINIT_NEED_USB_CORE;
|
|
||||||
#ifdef NEED_USB_OHCI
|
|
||||||
SYSINIT_NEED_USB_OHCI;
|
|
||||||
#endif
|
|
||||||
#ifdef NEED_USB_EHCI
|
|
||||||
SYSINIT_NEED_USB_EHCI;
|
|
||||||
#endif
|
|
||||||
SYSINIT_NEED_USB_MASS_STORAGE;
|
|
||||||
|
|
||||||
#endif /* USB_SYSINIT_INIT */
|
|
Loading…
x
Reference in New Issue
Block a user