hal_gdb_fileio — access host file system


#include <cyg/hal/hal_gdb_fileio.h>

int hal_gdb_fileio_open (const char* path , int flags , int mode );

int hal_gdb_fileio_close (int fd );

int hal_gdb_fileio_read (int fd , void* buffer , int count );

int hal_gdb_fileio_write (int fd , const void* buffer , int count );

cyg_int32 hal_gdb_fileio_lseek (int fd , cyg_int32 offset , int whence );

int hal_gdb_fileio_rename (const char* oldpath , const char* newpath );

int hal_gdb_fileio_unlink (const char* path );

int hal_gdb_fileio_stat (const char* path , struct hal_gdb_fileio_stat* stat );

int hal_gdb_fileio_fstat (int fd , struct hal_gdb_fileio_stat* stat );

int hal_gdb_fileio_gettimeofday (struct hal_gdb_fileio_timeval* tv , void * tz );

int hal_gdb_fileio_isatty (int fd );

int hal_gdb_fileio_system (const char* command );


In some configurations an eCos application can perform a number of file I/O and other operations on the host by interacting with gdb. For example the application can open a log file to the host and write very large amounts of debug data to that file over a period of time while consuming minimal target-side resources. However, the application will be completely blocked for the duration of the I/O operation with interrupts globally disabled. The functionality uses the gdb File I/O Remote Protocol Extension, described in the Remote Protocol appendix of the gdb documentation.

The gdb file I/O support is only available when the configuration option CYGFUN_HAL_GDB_FILEIO is enabled. In turn that option will have dependencies on other parts of the HAL, and the required functionality will not be available for all targets.

When debugging involves a hardware debug solution such as jtag or BDM, typically gdb will interact with a remote protocol server running inside or controlling the hardware debug unit. That server will implement the core parts of the remote protocol such as accessing memory, but typically there will be no way for the eCos application to get the server to send specific requests such as for file I/O. Instead a different approach is used. From inside the gdb session the command set hwdebug on should be used after attaching to the target. The next time the eCos application attempts a file I/O operation it will cause execution to halt at _gdb_hwdebug_breakpoint. Code inside gdb recognises that address, retrieves details of the I/O request from the target's memory, and then acts as if the request had come in a remote protocol message. The target resumes execution automatically once the I/O operation has been performed. If the hwdebug flag has not been set or if the application is running outside a gdb debug session, the behaviour of eCos is dependant on the CYGFUN_HAL_DIAG_VIA_GDB_FILEIO and CYGSEM_HAL_DIAG_VIA_GDB_FILEIO_IMMEDIATE configuration options. If both options are set, the target will halt at _gdb_hwdebug_breakpoint until a gdb session is established and the command set hwdebug on issued. Otherwise the file I/O operations will fail with error code HAL_GDB_FILEIO_ENOSYS.

This behaviour is useful during initial debugging using Eclipse as it allows diagnostic messages that would otherwise be discarded to be captured by a gdb session. A typical example is where an application is located in flash and diagnostic messages are issued by eCos before the application's main entry point is reached. During this initial stage of target bring-up eCos's internal data structures may not be adequately initialized so as to allow eCos to determine whether file I/O operations should either: (1) fail with diagnostic messages to gdb_hwdebug_fileio discarded (See HAL GDB File I/O Diagnostics Support); or (2) be passed to an underlying gdb session. See Use with the Eclipse CDT extensions for eCosPro application development for additional information regarding the use of Eclipse for debugging.

The Functions

Full details of the functions, parameters, data structures and error codes can be found in the header file cyg/hal/hal_gdb_fileio.h. The I/O calls are loosely modelled after the equivalent POSIX calls. They return 0 or a positive number for success, a negative number to indicate an error. The specific error code is the absolute value of the return value, so for example hal_gdb_fileio_open will return -HAL_GDB_FILEIO_ENOENT when attempting to open a file that does not exist. Some example code can be found in the testcase gdb_fileio.c.

hal_gdb_fileio_open is used to open a file on the host file system. It should only be used on files, not on special devices such as serial port or Unix-domain sockets: the gdb file I/O functionality is limited and has no support for select, non-blocking I/O, ioctl-style control, and so on. Hence if the eCos application does attempt to open and read from a serial port that will cause gdb to block and both the application and the debug session will freeze. Valid flags include HAL_GDB_FILEIO_O_RDONLY, HAL_GDB_FILEIO_O_WRONLY, and HAL_GDB_FILEIO_O_CREAT. The mode argument is used only when creating a new file and is used to set the access rights, for example HAL_GDB_FILEIO_S_IURSR+HAL_GDB_FILEIO_S_IWUSR.

The return value of hal_gdb_fileio_open is an integer file descriptor. Note that this is distinct from the file descriptor returned by the eCos open call. The two types of file descriptor are not interchangeable. For example hal_gdb_fileio_read should only be used with a file descriptor returned from hal_gdb_fileio_open, not with the return value of open.

hal_gdb_fileio_read, hal_gdb_fileio_write, hal_gdb_fileio_lseek, hal_gdb_fileio_fstat and hal_gdb_fileio_isatty perform operations on a file opened with hal_gdb_fileio_open. hal_gdb_fileio_write can also be used with the predefined file descriptor HAL_GDB_FILEIO_STDOUT, corresponding to gdb's standard output. For hal_gdb_fileio_lseek valid whence parameters are HAL_GDB_FILEIO_SEEK_SET, HAL_GDB_FILEIO_SEEK_CUR and HAL_GDB_FILEIO_SEEK_END. Due to limitations within the protocol and the implementation hal_gdb_fileio_lseek cannot fully support files of 2GB or larger. In other words offsets are limited to 31 bits.

The hal_gdb_fileio_stat and hal_gdb_fileio_fstat functions should be called with a struct hal_gdb-fileio_stat buffer:

struct hal_gdb_fileio_stat
    cyg_uint32 st_dev;
    cyg_uint32 st_ino;
    cyg_uint32 st_mode;
    cyg_uint32 st_nlink;
    cyg_uint32 st_uid;
    cyg_uint32 st_gid;
    cyg_uint32 st_rdev;
    cyg_uint64 st_size;
    cyg_uint64 st_blksize;
    cyg_uint64 st_blocks;
    cyg_uint32 st_atime;
    cyg_uint32 st_mtime;
    cyg_uint32 st_ctime;

The time values obtained are not year 2038 safe, as only space for a 32-bit time_t has been allocated. It is hoped that newlib and GDB will update the protocol in order to support 64-bit time_t, at which point eCos will be able to conform to whatever mechanism they use to supply the updated time, but this has not yet happened. It is therefore recommended that the time values are not used if this function is intended to be used after year 2038.

The first argument to hal_gdb_fileio_gettimeofday should be hal_gdb_fileio_timeval structure:

struct hal_gdb_fileio_timeval
    cyg_uint32 tv_sec;
    cyg_uint32 tv_usec;

The second argument to hal_gdb_fileio_gettimeofday is not currently used and application code should use a NULL pointer for this.


Again, the time values obtained are not year 2038 safe, as only space for a 32-bit time_t has been allocated. eCos will be updated when the GDB maintainers update the protocol to exchange a 64-bit time value. It is therefore strongly recommended that this function is not used if it may still be in use after year 2038.

hal_gdb_fileio_system can be used to invoke an arbitrary command on the host. For obvious security reasons this functionality is disabled within gdb by default. It must be explicitly enabled within gdb using a set remote system-call-allowed command.

Diagnostics Support

When the eCos application is built stand-alone and will be debugged via a hardware debug solution such as jtag or BDM, some platforms will allow HAL diagnostics to be sent a destination gdb_hwdebug_fileio. This output will end up being written to the gdb console via hal_gdb_fileio_write if the application is running inside a gdb session and the set hwdebug on command has been used after connecting to the target. Otherwise, if both CYGFUN_HAL_DIAG_VIA_GDB_FILEIO and CYGSEM_HAL_DIAG_VIA_GDB_FILEIO_IMMEDIATE configuration options are set, the eCos application will halt at a simulated breakpoint at _gdb_hwdebug_breakpoint until a gdb session is established. If CYGSEM_HAL_DIAG_VIA_GDB_FILEIO_IMMEDIATE is not set, the eCos application will not halt and HAL diagnostics will be discarded. Upon establishing a gdb session, the GDB console command set hwdebug on command must be used. On resuming the target and eCos application with the GDB command continue, the original HAL diagnostics message will appear within the gdb console and execution of the eCos application continue. Subsequent HAL diagnostics messages will appear without further interaction as GDB automatically resumes the application once hwdebug has been set. (See HAL GDB File I/O Description)

If the eCos application is resumed by a gdb session without the set hwdebug on command being issued, this output will be discarded and execution resumed until the next time the application performs a GDB file I/O operation and halts at the simulated breakpoint at _gdb_hwdebug_breakpoint. This behaviour will continue until set hwdebug on is issued as automatic resumption of execution is only performed by GDB once it has been issued. If subsequent HAL diagnostics are to be discarded, the set hwdebug off can be issued although this will also disable any further GDB file I/O operations as well.

Use with the Eclipse CDT extensions for eCosPro application development

The eCosCentric CDT extensions for eCosPro application development for the Eclipse Kepler release and above always effectively test if an eCos application is configured with option CYGFUN_HAL_GDB_FILEIO enabled and automatically issues the command set hwdebug on when enabled. This ensures that all HAL diagnostics messages will be visible within the GDB console window prior to and after the initial application entry point is reached (normally either main or cyg_user_start). The eCos application developer therefore does not need to be concerned with issuing these GDB commands when using eCosCentric's Eclipse CDT extensions for the Kepler release and above. They only need to configure eCos appropriately when they wish to make use of GDB file I/O operations or capture HAL diagnostics messages when debugging through either jtag or BDM when no alternative stream is available for HAL diagnostics messages (e.g. serial). (See HAL GDB File I/O Diagnostics Support and HAL GDB File I/O Description)