forked from Imagelibrary/rtems
bsp: Move umon support to bsps
The umon support is only used by the csb337 BSP. This patch is a part of the BSP source reorganization. Update #3285.
This commit is contained in:
@@ -8,9 +8,6 @@ dist_project_lib_DATA = startup/bsp_specs
|
||||
if ENABLE_LCD
|
||||
endif
|
||||
|
||||
if ENABLE_UMON
|
||||
endif
|
||||
|
||||
DISTCLEANFILES = include/bspopts.h
|
||||
noinst_PROGRAMS =
|
||||
|
||||
@@ -61,12 +58,12 @@ libbsp_a_SOURCES += console/sed1356.c console/fbcons.c
|
||||
endif
|
||||
# umon
|
||||
if ENABLE_UMON
|
||||
libbsp_a_SOURCES += ../../shared/umon/umonrtemsglue.c \
|
||||
../../shared/umon/monlib.c ../../shared/umon/tfsDriver.c \
|
||||
../../shared/umon/umoncons.c startup/umonsupp.c
|
||||
libbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/umon/monlib.c
|
||||
libbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/umon/tfsDriver.c
|
||||
libbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/umon/umonrtemsglue.c
|
||||
endif
|
||||
if ENABLE_UMON_CONSOLE
|
||||
libbsp_a_SOURCES += ../../shared/umon/umoncons.c
|
||||
libbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/umon/umoncons.c
|
||||
endif
|
||||
|
||||
# Cache
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# Fernando Nicodemos <fgnicodemos@terra.com.br>
|
||||
# from NCB - Sistemas Embarcados Ltda. (Brazil)
|
||||
#
|
||||
# Joel Sherill
|
||||
# from OAR Corporation
|
||||
#
|
||||
|
||||
This directory contains support for utilitizing MicroMonitor
|
||||
(http://www.umonfw.com/) capabilities from within an RTEMS
|
||||
application. This directory contiains:
|
||||
|
||||
+ "MonLib" functionality as documented in the MicroMonitor
|
||||
User's Manual.
|
||||
+ TFS filesystem which makes the MicroMonitor TFS filesystem
|
||||
available under RTEMS as a regular filesystem.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
For any of this functionality to work, the application is
|
||||
responsible for connecting the library to the monitor.
|
||||
This is done by calling rtems_umon_connect() early in the
|
||||
application. This routine assumes that the BSP has provided
|
||||
the routine rtems_bsp_get_umon_monptr() which returns the
|
||||
value referred to as MONCOMPTR by MicroMonitor.
|
||||
|
||||
To use the TFS filesystem, it is necessary to mount it
|
||||
by calling the rtems_initialize_tfs_filesystem() routine
|
||||
and providing it the name of the mount point directory.
|
||||
|
||||
CONFIGURATION
|
||||
=============
|
||||
The TFS filesystem uses a single Classic API Semaphore.
|
||||
|
||||
The monlib functionality will eventually also use a single
|
||||
Classic API Semaphore.
|
||||
|
||||
STATUS
|
||||
======
|
||||
|
||||
+ Limited testing -- especially of TFS RTEMS filesystem.
|
||||
+ monlib is NOT currently protected by a mutex.
|
||||
|
||||
SOURCE ORIGIN
|
||||
=============
|
||||
Some of the files in this directory are included in the
|
||||
MicroMonitor distribution and may need to be updated
|
||||
in the future.
|
||||
|
||||
12 June 2009: Source is from umon 1.17
|
||||
@@ -1,7 +0,0 @@
|
||||
/**
|
||||
* @defgroup shared_umon SHARED UMON Modules
|
||||
*
|
||||
* @ingroup bsp_shared
|
||||
*
|
||||
* @brief SHARED UMON Modules
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,683 +0,0 @@
|
||||
/*
|
||||
* tfsDriver.c - MicroMonitor TFS Hookup to RTEMS FS
|
||||
*
|
||||
* Initial release: Oct 1, 2004 by Ed Sutter
|
||||
*
|
||||
* Modifications to support reference counting in the file system are
|
||||
* Copyright (c) 2012 embedded brains GmbH.
|
||||
*
|
||||
* This code was derived from the tftpDriver.c code written by
|
||||
* W. Eric Norum, which was apparently derived from the IMFS driver.
|
||||
*
|
||||
* This code was reformatted by Joel Sherrill from OAR Corporation and
|
||||
* Fernando Nicodemos <fgnicodemos@terra.com.br> from NCB - Sistemas
|
||||
* Embarcados Ltda. (Brazil) to be more compliant with RTEMS coding
|
||||
* standards and to eliminate C++ style comments.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/libio_.h>
|
||||
#include <rtems/seterr.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/umon.h>
|
||||
|
||||
#include <umon/tfs.h>
|
||||
#include <umon/monlib.h>
|
||||
|
||||
#ifdef RTEMS_TFS_DRIVER_DEBUG
|
||||
#define RTEMS_TFS_DEBUG 1
|
||||
#else
|
||||
#define RTEMS_TFS_DEBUG 0
|
||||
#endif
|
||||
|
||||
#define MAXFILESIZE 0x4000
|
||||
#define MAXTFDS 15
|
||||
|
||||
/* Define these for thread safety...
|
||||
*/
|
||||
#ifndef newlib_tfdlock
|
||||
#define newlib_tfdlock()
|
||||
#endif
|
||||
|
||||
#ifndef newlib_tfdunlock
|
||||
#define newlib_tfdunlock()
|
||||
#endif
|
||||
|
||||
/* TFS file descriptor info:
|
||||
*/
|
||||
struct tfdinfo {
|
||||
int inuse;
|
||||
int tfd;
|
||||
char *buf;
|
||||
char name[TFSNAMESIZE+1];
|
||||
char info[TFSNAMESIZE+1];
|
||||
} tfdtable[MAXTFDS];
|
||||
|
||||
/*
|
||||
* Pathname prefix
|
||||
*/
|
||||
char TFS_PATHNAME_PREFIX[128];
|
||||
|
||||
static const rtems_filesystem_operations_table rtems_tfs_ops;
|
||||
static const rtems_filesystem_file_handlers_r rtems_tfs_handlers;
|
||||
|
||||
static bool rtems_tfs_is_directory(
|
||||
const char *path,
|
||||
size_t pathlen
|
||||
)
|
||||
{
|
||||
return path [pathlen - 1] == '/';
|
||||
}
|
||||
|
||||
static int rtems_tfs_mount_me(
|
||||
rtems_filesystem_mount_table_entry_t *mt_entry,
|
||||
const void *data
|
||||
)
|
||||
{
|
||||
char *root_path = strdup("/");
|
||||
|
||||
if (root_path == NULL) {
|
||||
rtems_set_errno_and_return_minus_one(ENOMEM);
|
||||
}
|
||||
|
||||
mt_entry->ops = &rtems_tfs_ops;
|
||||
mt_entry->mt_fs_root->location.handlers = &rtems_tfs_handlers;
|
||||
mt_entry->mt_fs_root->location.node_access = root_path;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize the TFS-RTEMS file system
|
||||
*/
|
||||
int rtems_initialize_tfs_filesystem(
|
||||
const char *path
|
||||
)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!path) {
|
||||
printk( "TFS: No mount point specified\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy( TFS_PATHNAME_PREFIX, path, sizeof(TFS_PATHNAME_PREFIX) );
|
||||
|
||||
status = mkdir( TFS_PATHNAME_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO );
|
||||
if ( status == -1 ) {
|
||||
printk( "TFS: Unable to mkdir %s\n", TFS_PATHNAME_PREFIX );
|
||||
return status;
|
||||
}
|
||||
|
||||
if (rtems_filesystem_register( "tfs", rtems_tfs_mount_me ) < 0)
|
||||
return -1;
|
||||
|
||||
status = mount( "umon", TFS_PATHNAME_PREFIX, "tfs", RTEMS_FILESYSTEM_READ_WRITE, NULL);
|
||||
|
||||
if (status < 0) {
|
||||
printk( "TFS: Unable to mount on %s\n", TFS_PATHNAME_PREFIX );
|
||||
perror("TFS mount failed");
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a path to canonical form
|
||||
*/
|
||||
static void fixPath(char *path)
|
||||
{
|
||||
char *inp, *outp, *base;
|
||||
|
||||
outp = inp = path;
|
||||
base = NULL;
|
||||
for (;;) {
|
||||
if (inp[0] == '.') {
|
||||
if (inp[1] == '\0')
|
||||
break;
|
||||
if (inp[1] == '/') {
|
||||
inp += 2;
|
||||
continue;
|
||||
}
|
||||
if (inp[1] == '.') {
|
||||
if (inp[2] == '\0') {
|
||||
if ((base != NULL) && (outp > base)) {
|
||||
outp--;
|
||||
while ((outp > base) && (outp[-1] != '/'))
|
||||
outp--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (inp[2] == '/') {
|
||||
inp += 3;
|
||||
if (base == NULL)
|
||||
continue;
|
||||
if (outp > base) {
|
||||
outp--;
|
||||
while ((outp > base) && (outp[-1] != '/'))
|
||||
outp--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (base == NULL)
|
||||
base = inp;
|
||||
while (inp[0] != '/') {
|
||||
if ((*outp++ = *inp++) == '\0')
|
||||
return;
|
||||
}
|
||||
*outp++ = '/';
|
||||
while (inp[0] == '/')
|
||||
inp++;
|
||||
}
|
||||
*outp = '\0';
|
||||
}
|
||||
|
||||
static void rtems_tfs_eval_path(rtems_filesystem_eval_path_context_t *self)
|
||||
{
|
||||
int eval_flags = rtems_filesystem_eval_path_get_flags(self);
|
||||
|
||||
if ((eval_flags & RTEMS_FS_MAKE) == 0) {
|
||||
int rw = RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE;
|
||||
|
||||
if ((eval_flags & rw) != rw) {
|
||||
rtems_filesystem_location_info_t *currentloc =
|
||||
rtems_filesystem_eval_path_get_currentloc(self);
|
||||
char *current = currentloc->node_access;
|
||||
size_t currentlen = strlen(current);
|
||||
const char *path = rtems_filesystem_eval_path_get_path(self);
|
||||
size_t pathlen = rtems_filesystem_eval_path_get_pathlen(self);
|
||||
size_t len = currentlen + pathlen;
|
||||
|
||||
rtems_filesystem_eval_path_clear_path(self);
|
||||
|
||||
current = realloc(current, len + 1);
|
||||
if (current != NULL) {
|
||||
memcpy(current + currentlen, path, pathlen);
|
||||
current [len] = '\0';
|
||||
if (!rtems_tfs_is_directory(current, len)) {
|
||||
fixPath (current);
|
||||
}
|
||||
currentloc->node_access = current;
|
||||
} else {
|
||||
rtems_filesystem_eval_path_error(self, ENOMEM);
|
||||
}
|
||||
} else {
|
||||
rtems_filesystem_eval_path_error(self, EINVAL);
|
||||
}
|
||||
} else {
|
||||
rtems_filesystem_eval_path_error(self, EIO);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The routine which does most of the work for the IMFS open handler
|
||||
* The full_path_name here is all text AFTER the TFS_PATHNAME_PREFIX
|
||||
* string, so if the filename is "/TFS/abc", the full_path_name string
|
||||
* is "abc"...
|
||||
*
|
||||
* Attempts to remap the incoming flags to TFS equivalent.
|
||||
* Its not a perfect mapping, but gets pretty close.
|
||||
* A comma-delimited path is supported to allow the user
|
||||
* to specify TFS-stuff (flag string, info string, and a buffer).
|
||||
* For example:
|
||||
* abc,e,script,0x400000
|
||||
* This is a file called "abc" that will have the TFS 'e' flag
|
||||
* and the TFS info field of "script". The storage buffer is
|
||||
* supplied by the user at 0x400000.
|
||||
*/
|
||||
static int rtems_tfs_open_worker(
|
||||
rtems_libio_t *iop,
|
||||
char *path,
|
||||
int oflag,
|
||||
mode_t mode
|
||||
)
|
||||
{
|
||||
static int beenhere = 0;
|
||||
long flagmode;
|
||||
int tfdidx, tfd;
|
||||
struct tfdinfo *tip;
|
||||
char *buf, *fstr, *istr, *bstr, pathcopy[TFSNAMESIZE*3+1];
|
||||
|
||||
if (RTEMS_TFS_DEBUG)
|
||||
printk("_open_r(%s,0x%x,0x%" PRIx32 ")\n",path,oflag,mode);
|
||||
|
||||
if (!beenhere) {
|
||||
newlib_tfdlock();
|
||||
for(tfdidx=0;tfdidx<MAXTFDS;tfdidx++)
|
||||
tfdtable[tfdidx].inuse = 0;
|
||||
|
||||
tfdtable[0].inuse = 1; /* fake entry for stdin */
|
||||
tfdtable[1].inuse = 1; /* fake entry for stdout */
|
||||
tfdtable[2].inuse = 1; /* fake entry for stderr */
|
||||
newlib_tfdunlock();
|
||||
beenhere = 1;
|
||||
}
|
||||
|
||||
istr = fstr = bstr = buf = (char *)0;
|
||||
|
||||
/* Copy the incoming path to a local array so that we can safely
|
||||
* modify the string...
|
||||
*/
|
||||
if (strlen(path) > TFSNAMESIZE*3) {
|
||||
return(ENAMETOOLONG);
|
||||
}
|
||||
strcpy(pathcopy,path);
|
||||
|
||||
/* The incoming string may have commas that are used to delimit the
|
||||
* name from the TFS flag string, TFS info string and buffer.
|
||||
* Check for the commas and test for maximum string length...
|
||||
*/
|
||||
fstr = strchr(pathcopy,',');
|
||||
if (fstr) {
|
||||
*fstr++ = 0;
|
||||
istr = strchr(fstr,',');
|
||||
if (istr) {
|
||||
*istr++ = 0;
|
||||
bstr = strchr(istr,',');
|
||||
if (bstr)
|
||||
*bstr++ = 0;
|
||||
}
|
||||
}
|
||||
if (strlen(pathcopy) > TFSNAMESIZE) {
|
||||
return(ENAMETOOLONG);
|
||||
}
|
||||
if (istr) {
|
||||
if (strlen(istr) > TFSNAMESIZE) {
|
||||
return(ENAMETOOLONG);
|
||||
}
|
||||
}
|
||||
|
||||
/* If O_EXCL and O_CREAT are set, then fail if the file exists...
|
||||
*/
|
||||
if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
|
||||
if (mon_tfsstat((char *)pathcopy)) {
|
||||
return(EEXIST);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only a few flag combinations are supported...
|
||||
* O_RDONLY Simple read-only
|
||||
* O_WRONLY | O_APPEND Each write starts at end of file
|
||||
* O_WRONLY | O_TRUNC If file exists, truncate it
|
||||
* O_WRONLY | O_CREAT Create if it doesn't exist
|
||||
* O_WRONLY | O_CREAT | O_EXCL Fail if file exists
|
||||
*/
|
||||
switch(oflag & O_ACCMODE) {
|
||||
case O_RDONLY:
|
||||
flagmode = TFS_RDONLY;
|
||||
break;
|
||||
case O_WRONLY|O_APPEND:
|
||||
flagmode = TFS_APPEND;
|
||||
break;
|
||||
case O_WRONLY|O_TRUNC:
|
||||
case O_WRONLY|O_CREAT|O_TRUNC:
|
||||
mon_tfsunlink((char *)pathcopy);
|
||||
flagmode = TFS_CREATE|TFS_APPEND;
|
||||
break;
|
||||
case O_WRONLY|O_CREAT:
|
||||
case O_WRONLY|O_CREAT|O_APPEND:
|
||||
flagmode = TFS_CREATE|TFS_APPEND;
|
||||
break;
|
||||
case O_RDWR:
|
||||
case O_WRONLY|O_CREAT|O_EXCL:
|
||||
flagmode = TFS_CREATE|TFS_APPEND;
|
||||
break;
|
||||
default:
|
||||
printk("_open_r(): flag 0x%i not supported\n",oflag);
|
||||
return(ENOTSUP);
|
||||
}
|
||||
|
||||
/* Find an open slot in our tfd table:
|
||||
*/
|
||||
newlib_tfdlock();
|
||||
for(tfdidx=0;tfdidx<MAXTFDS;tfdidx++) {
|
||||
if (tfdtable[tfdidx].inuse == 0)
|
||||
break;
|
||||
}
|
||||
if (tfdidx == MAXTFDS) {
|
||||
newlib_tfdunlock();
|
||||
return(EMFILE);
|
||||
}
|
||||
tip = &tfdtable[tfdidx];
|
||||
tip->inuse = 1;
|
||||
newlib_tfdunlock();
|
||||
|
||||
/* If file is opened for something other than O_RDONLY, then
|
||||
* we need to allocate a buffer for the file..
|
||||
* WARNING: It is the user's responsibility to make sure that
|
||||
* the file size does not exceed this buffer. Note that the
|
||||
* buffer may be specified as part of the comma-delimited path.
|
||||
*/
|
||||
if (flagmode == TFS_RDONLY) {
|
||||
buf = (char *)0;
|
||||
} else {
|
||||
if (bstr)
|
||||
buf = (char *)strtol(bstr,0,0);
|
||||
else
|
||||
buf = malloc(MAXFILESIZE);
|
||||
if (!buf) {
|
||||
newlib_tfdlock();
|
||||
tip->inuse = 0;
|
||||
newlib_tfdunlock();
|
||||
return(ENOMEM);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deal with tfs flags and tfs info fields if necessary:
|
||||
*/
|
||||
if (fstr) {
|
||||
long bflag;
|
||||
|
||||
bflag = mon_tfsctrl(TFS_FATOB,(long)fstr,0);
|
||||
if (bflag == -1) {
|
||||
return(EINVAL);
|
||||
}
|
||||
flagmode |= bflag;
|
||||
}
|
||||
|
||||
if (istr)
|
||||
strcpy(tip->info,istr);
|
||||
else
|
||||
tip->info[0] = 0;
|
||||
|
||||
tfd = mon_tfsopen((char *)pathcopy,flagmode,buf);
|
||||
if (tfd >= 0) {
|
||||
tip->tfd = tfd;
|
||||
tip->buf = buf;
|
||||
strcpy(tip->name,pathcopy);
|
||||
iop->data0 = (uint32_t)tfdidx;
|
||||
return(0);
|
||||
} else {
|
||||
printk("%s: %s\n",pathcopy,
|
||||
(char *)mon_tfsctrl(TFS_ERRMSG,tfd,0));
|
||||
}
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
|
||||
newlib_tfdlock();
|
||||
tip->inuse = 0;
|
||||
newlib_tfdunlock();
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* The IMFS open handler
|
||||
*/
|
||||
static int rtems_tfs_open(
|
||||
rtems_libio_t *iop,
|
||||
const char *new_name,
|
||||
int oflag,
|
||||
mode_t mode
|
||||
)
|
||||
{
|
||||
char *full_path_name;
|
||||
int err;
|
||||
|
||||
full_path_name = iop->pathinfo.node_access;
|
||||
|
||||
if (RTEMS_TFS_DEBUG)
|
||||
printk("rtems_tfs_open(%s)\n",full_path_name);
|
||||
|
||||
if (rtems_tfs_is_directory(full_path_name, strlen(full_path_name))) {
|
||||
rtems_set_errno_and_return_minus_one (ENOTSUP);
|
||||
}
|
||||
|
||||
err = rtems_tfs_open_worker (iop, full_path_name, oflag, mode);
|
||||
if (err != 0) {
|
||||
rtems_set_errno_and_return_minus_one (err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from an open TFS file...
|
||||
*/
|
||||
static ssize_t rtems_tfs_read(
|
||||
rtems_libio_t *iop,
|
||||
void *buffer,
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
int ret, fd;
|
||||
|
||||
fd = (int) iop->data0;
|
||||
|
||||
if (RTEMS_TFS_DEBUG)
|
||||
printk("_read_r(%d,%zi)\n",fd,count);
|
||||
|
||||
if ((fd < 3) || (fd >= MAXTFDS))
|
||||
return(EBADF);
|
||||
|
||||
ret = mon_tfsread(tfdtable[fd].tfd,buffer,count);
|
||||
if (ret == TFSERR_EOF)
|
||||
ret = 0;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the open tfs file.
|
||||
*/
|
||||
static int rtems_tfs_close(
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
int fd;
|
||||
char *info;
|
||||
struct tfdinfo *tip;
|
||||
|
||||
fd = (int)iop->data0;
|
||||
|
||||
if (RTEMS_TFS_DEBUG)
|
||||
printk("rtems_tfs_close(%d)\n",fd);
|
||||
|
||||
if ((fd < 3) || (fd >= MAXTFDS)) {
|
||||
rtems_set_errno_and_return_minus_one (EBADF);
|
||||
}
|
||||
|
||||
tip = &tfdtable[fd];
|
||||
|
||||
if (tip->info[0])
|
||||
info = tip->info;
|
||||
else
|
||||
info = (char *)0;
|
||||
|
||||
mon_tfsclose(tip->tfd,info);
|
||||
|
||||
if (tip->buf)
|
||||
free(tip->buf);
|
||||
|
||||
newlib_tfdlock();
|
||||
tip->inuse = 0;
|
||||
newlib_tfdunlock();
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static ssize_t rtems_tfs_write(
|
||||
rtems_libio_t *iop,
|
||||
const void *buffer,
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
int ret, fd;
|
||||
|
||||
fd = (int) iop->data0;
|
||||
|
||||
if (RTEMS_TFS_DEBUG)
|
||||
printk("rtems_tfs_write(%d,%zi)\n",fd,count);
|
||||
|
||||
if ((fd <= 0) || (fd >= MAXTFDS)) {
|
||||
rtems_set_errno_and_return_minus_one (EBADF);
|
||||
}
|
||||
|
||||
ret = mon_tfswrite(tfdtable[fd].tfd,(char *)buffer,count);
|
||||
if (ret < 0)
|
||||
return(-1);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static off_t rtems_tfs_lseek(
|
||||
rtems_libio_t *iop,
|
||||
off_t offset,
|
||||
int whence
|
||||
)
|
||||
{
|
||||
int ret, fd;
|
||||
|
||||
fd = (int) iop->data0;
|
||||
|
||||
if (RTEMS_TFS_DEBUG)
|
||||
printk("rtems_tfs_lseek(%d,%ld,%d)\n",fd,(long)offset,whence);
|
||||
|
||||
switch (whence) {
|
||||
case SEEK_END:
|
||||
printk("rtems_tfs_lseek doesn't support SEEK_END\n");
|
||||
return(-1);
|
||||
case SEEK_CUR:
|
||||
whence = TFS_CURRENT;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
whence = TFS_BEGIN;
|
||||
break;
|
||||
}
|
||||
ret = mon_tfsseek(tfdtable[fd].tfd,offset,whence);
|
||||
|
||||
if (ret < 0)
|
||||
return(-1);
|
||||
|
||||
return (off_t)ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static int rtems_tfs_ftruncate(
|
||||
rtems_libio_t *iop,
|
||||
off_t count
|
||||
)
|
||||
{
|
||||
int ret, fd;
|
||||
|
||||
fd = (int) iop->data0;
|
||||
ret = mon_tfstruncate(tfdtable[fd].tfd,count);
|
||||
if (ret != TFS_OKAY)
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int rtems_tfs_ioctl(
|
||||
rtems_libio_t *iop,
|
||||
uint32_t cmd,
|
||||
void *buf
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mon_tfsctrl(cmd,(long)buf,0);
|
||||
if (ret != TFS_OKAY)
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int rtems_tfs_fstat(
|
||||
const rtems_filesystem_location_info_t *loc,
|
||||
struct stat *buf
|
||||
)
|
||||
{
|
||||
const char *path = loc->node_access;
|
||||
size_t pathlen = strlen(path);
|
||||
|
||||
buf->st_mode = S_IRWXU | S_IRWXG | S_IRWXO
|
||||
| (rtems_tfs_is_directory(path, pathlen) ? S_IFDIR : S_IFREG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtems_tfs_clone_node_info(
|
||||
rtems_filesystem_location_info_t *loc
|
||||
)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
loc->node_access = strdup(loc->node_access);
|
||||
|
||||
if (loc->node_access == NULL) {
|
||||
errno = ENOMEM;
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void rtems_tfs_free_node_info(
|
||||
const rtems_filesystem_location_info_t *loc
|
||||
)
|
||||
{
|
||||
free(loc->node_access);
|
||||
}
|
||||
|
||||
static bool rtems_tfs_are_nodes_equal(
|
||||
const rtems_filesystem_location_info_t *a,
|
||||
const rtems_filesystem_location_info_t *b
|
||||
)
|
||||
{
|
||||
return strcmp(a->node_access, b->node_access) == 0;
|
||||
}
|
||||
|
||||
static const rtems_filesystem_operations_table rtems_tfs_ops = {
|
||||
.lock_h = rtems_filesystem_default_lock,
|
||||
.unlock_h = rtems_filesystem_default_unlock,
|
||||
.eval_path_h = rtems_tfs_eval_path,
|
||||
.link_h = rtems_filesystem_default_link,
|
||||
.are_nodes_equal_h = rtems_tfs_are_nodes_equal,
|
||||
.mknod_h = rtems_filesystem_default_mknod,
|
||||
.rmnod_h = rtems_filesystem_default_rmnod,
|
||||
.fchmod_h = rtems_filesystem_default_fchmod,
|
||||
.chown_h = rtems_filesystem_default_chown,
|
||||
.clonenod_h = rtems_tfs_clone_node_info,
|
||||
.freenod_h = rtems_tfs_free_node_info,
|
||||
.mount_h = rtems_filesystem_default_mount,
|
||||
.unmount_h = rtems_filesystem_default_unmount,
|
||||
.fsunmount_me_h = rtems_filesystem_default_fsunmount,
|
||||
.utime_h = rtems_filesystem_default_utime,
|
||||
.symlink_h = rtems_filesystem_default_symlink,
|
||||
.readlink_h = rtems_filesystem_default_readlink,
|
||||
.rename_h = rtems_filesystem_default_rename,
|
||||
.statvfs_h = rtems_filesystem_default_statvfs
|
||||
};
|
||||
|
||||
static const rtems_filesystem_file_handlers_r rtems_tfs_handlers = {
|
||||
.open_h = rtems_tfs_open,
|
||||
.close_h = rtems_tfs_close,
|
||||
.read_h = rtems_tfs_read,
|
||||
.write_h = rtems_tfs_write,
|
||||
.ioctl_h = rtems_tfs_ioctl,
|
||||
.lseek_h = rtems_tfs_lseek,
|
||||
.fstat_h = rtems_tfs_fstat,
|
||||
.ftruncate_h = rtems_tfs_ftruncate,
|
||||
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
|
||||
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
|
||||
.fcntl_h = rtems_filesystem_default_fcntl,
|
||||
.kqfilter_h = rtems_filesystem_default_kqfilter,
|
||||
.poll_h = rtems_filesystem_default_poll,
|
||||
.readv_h = rtems_filesystem_default_readv,
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* uMon Support Output Driver
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2009.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
|
||||
* from NCB - Sistemas Embarcados Ltda. (Brazil)
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/umon.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
/* static function prototypes */
|
||||
static int umoncons_first_open(int major, int minor, void *arg);
|
||||
static int umoncons_last_close(int major, int minor, void *arg);
|
||||
static int umoncons_read(int minor);
|
||||
static ssize_t umoncons_write(int minor, const char *buf, size_t len);
|
||||
static void umoncons_init(int minor);
|
||||
static void umoncons_write_polled(int minor, char c);
|
||||
static int umoncons_set_attributes(int minor, const struct termios *t);
|
||||
|
||||
/* Pointers to functions for handling the UART. */
|
||||
const console_fns umoncons_fns =
|
||||
{
|
||||
libchip_serial_default_probe,
|
||||
umoncons_first_open,
|
||||
umoncons_last_close,
|
||||
umoncons_read,
|
||||
umoncons_write,
|
||||
umoncons_init,
|
||||
umoncons_write_polled, /* not used in this driver */
|
||||
umoncons_set_attributes,
|
||||
false /* TRUE if interrupt driven, FALSE if not. */
|
||||
};
|
||||
|
||||
/*********************************************************************/
|
||||
/* Functions called via callbacks (i.e. the ones in uart_fns */
|
||||
/*********************************************************************/
|
||||
|
||||
/*
|
||||
* This is called the first time each device is opened. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd enable interrupts here.
|
||||
*/
|
||||
static int umoncons_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called the last time each device is closed. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd disable interrupts here.
|
||||
*/
|
||||
static int umoncons_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read one character from UART.
|
||||
*
|
||||
* return -1 if there's no data, otherwise return
|
||||
* the character in lowest 8 bits of returned int.
|
||||
*/
|
||||
static int umoncons_read(int minor)
|
||||
{
|
||||
if ( !mon_gotachar() )
|
||||
return -1;
|
||||
return mon_getchar();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write buffer to LCD
|
||||
*
|
||||
* return 1 on success, -1 on error
|
||||
*/
|
||||
static ssize_t umoncons_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for ( i=0 ; i<len ; i++ )
|
||||
mon_putchar( buf[i] );
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* Set up the uMon driver. */
|
||||
static void umoncons_init(int minor)
|
||||
{
|
||||
rtems_umon_connect();
|
||||
}
|
||||
|
||||
/* This is used for putchark support */
|
||||
static void umoncons_write_polled(int minor, char c)
|
||||
{
|
||||
mon_putchar( c );
|
||||
}
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int umoncons_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* The following functions are not used by TERMIOS, but other RTEMS
|
||||
* functions use them instead.
|
||||
*/
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* Read from UART. This is used in the exit code, and can't
|
||||
* rely on interrupts.
|
||||
*/
|
||||
int umoncons_poll_read(int minor)
|
||||
{
|
||||
if (!mon_gotachar())
|
||||
return -1;
|
||||
return mon_getchar();
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2009.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
|
||||
* from NCB - Sistemas Embarcados Ltda. (Brazil)
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/umon.h>
|
||||
|
||||
/* XXX eventually add lock/unlock methods */
|
||||
|
||||
static int rtems_umon_connected = 0;
|
||||
|
||||
void rtems_umon_connect(void)
|
||||
{
|
||||
int(*moncomptr)(int,void *,void *,void *);
|
||||
|
||||
if ( rtems_umon_connected )
|
||||
return;
|
||||
|
||||
rtems_umon_connected = 1;
|
||||
|
||||
moncomptr = rtems_bsp_get_umon_monptr();
|
||||
monConnect(
|
||||
moncomptr, /* monitor base */
|
||||
(void *)0, /* lock */
|
||||
(void *)0 /* unlock */
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user