⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileio.txt

📁 eCos操作系统源码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
infrastructure, any changes to it must be made with the appropriatelogical operations.Directories-----------Filesystem operations all take a directory pointer as one of theirarguments.  A directory pointer is an opaque handle managed by thefilesystem. It should encapsulate a reference to a specific directorywithin the filesystem. For example, it may be a pointer to the datastructure that represents that directory, or a pointer to a pathnamefor the directory.The _chdir_ filesystem function has two modes of use. When passed apointer in the _dir_out_ argument, it should locate the nameddirectory and place a directory pointer there. If the _dir_out_argument is NULL then the _dir_ argument is a previously generateddirectory pointer that can now be disposed of. When the infrastructureis implementing the chdir() function it makes two calls to filesystem_chdir_ functions. The first is to get a directory pointer for the newcurrent directory. If this succeeds the second is to dispose of theold current directory pointer.The _opendir_ function is used to open a directory for reading. Thisresults in an open file object that can be read to return a sequenceof _struct dirent_ objects. The only operation that are allowed onthis file are _read_, _lseek_ and _close_. Each read operation on thisfile should return a single _struct dirent_ object. When the end ofthe directory is reached, zero should be returned. The only seekoperation allowed is a rewind to the start of the directory, bysupplying an offset of zero and a _whence_ specifier of _SEEK_SET_.Most of these considerations are invisible to clients of a filesystemsince they will access directories via the POSIXopendir()/readdir()/closedir() functions.Support for the _getcwd()_ function is provided by three mechanisms.The first is to use the _FS_INFO_GETCWD_ getinfo key on the filesystemto use any internal support that it has for this. If that fails itfalls back on one of the two other mechanisms. If_CYGPKG_IO_FILEIO_TRACK_CWD_ is set then the current directory istracked textually in chdir() and the result of that is reported ingetcwd(). Otherwise an attempt is made to traverse the directory treeto its root using ".." entries.This last option is complicated and expensive, and relies on thefilesystem supporting "." and ".."  entries. This is not always thecase, particularly if the filesystem has been ported from anon-UNIX-compatible source. Tracking the pathname textually willusually work, but might not produce optimum results when symboliclinks are being used.Synchronization---------------The FILEIO infrastructure provides a synchronization mechanism forcontrolling concurrent access to filesystems. This allows existingfilesystems to be ported to eCos, even if they do not have their ownsynchronization mechanisms. It also allows new filesystems to beimplemented easily without having to consider the synchronizationissues.The infrastructure maintains a mutex for each entry in each ofthe main tables: filesystem table, mount table and file table. Foreach class of operation each of these mutexes may be locked before thecorresponding filesystem operation is invoked.The synchronization protocol implemented by a filesystem is describedby the _syncmode_ field of the filesystem table entry. This is acombination of the following flags:CYG_SYNCMODE_FILE_FILESYSTEM Lock the filesystem table entry mutex			     during all filesystem level operations.CYG_SYNCMODE_FILE_MOUNTPOINT Lock the mount table entry mutex			     during all filesystem level operations.CYG_SYNCMODE_IO_FILE	     Lock the file table entry mutex during all			     I/O operations.CYG_SYNCMODE_IO_FILESYSTEM   Lock the filesystem table entry mutex			     during all I/O operations.			     CYG_SYNCMODE_IO_MOUNTPOINT   Lock the mount table entry mutex during			     all I/O operations.CYG_SYNCMODE_SOCK_FILE       Lock the file table entry mutex during			     all socket operations.CYG_SYNCMODE_SOCK_NETSTACK   Lock the network stack table entry mutex			     during all socket operations.CYG_SYNCMODE_NONE	     Perform no locking at all during any			     operations.The value of the _syncmode_ in the filesystem table entry will becopied by the infrastructure to the open file object after asuccessful open() operation.Initialization and Mounting---------------------------As mentioned previously, mount table entries can be sourced from twoplaces. Static entries may be defined by using the MTAB_ENTRY()macro. Such entries will be automatically mounted on system startup.For each entry in the mount table that has a non-null _name_ field thefilesystem table is searched for a match with the _fsname_ field. If amatch is found the filesystem's _mount_ entry is called and ifsuccessful the mount table entry marked valid and the _fs_ fieldinitialized. The _mount_ function is responsible for initializing the_root_ field.The size of the mount table is defined by the configuration valueCYGNUM_FILEIO_MTAB_MAX. Any entries that have not been staticallydefined are available for use by dynamic mounts.A filesystem may be mounted dynamically by calling mount(). Thisfunction has the following prototype:int mount( const char *devname,           const char *dir,	   const char *fsname);The _devname_ argument identifies a device that will be used by thisfilesystem and will be assigned to the _devname_ field of the mounttable entry.The _dir_ argument is the mount point name, it will be assigned to the_name_ field of the mount table entry.The _fsname_ argument is the name of the implementing filesystem, itwill be assigned to the _fsname_ entry of the mount table entry.The process of mounting a filesystem dynamically is as follows. Firsta search is made of the mount table for an entry with a NULL _name_field to be used for the new mount point. The filesystem table is thensearched for an entry whose name matches _fsname_. If this issuccessful then the mount table entry is initialized and thefilesystem's _mount_ operation called. If this is successful, themount table entry is marked valid and the _fs_ field initialized.Unmounting a filesystem is done by the umount() function. This canunmount filesystems whether they were mounted statically ordynamically.The umount() function has the following prototype:int umount( const char *name );The mount table is searched for a match between the _name_ argumentand the entry _name_ field. When a match is found the filesystem's_umount_ operation is called and if successful, the mount table entryis invalidated by setting its _valid_ field false and the _name_ fieldto NULL.Sockets-------If a network stack is present, then the FILEIO infrastructure alsoprovides access to the standard BSD socket calls.The netstack table contains entries which describe the networkprotocol stacks that are in the system image. Each resident stackshould export an entry to this table using the NSTAB_ENTRY() macro.Each table entry has the following structure:struct cyg_nstab_entry{    cyg_bool            valid;          // true if stack initialized    cyg_uint32          syncmode;       // synchronization protocol    char                *name;          // stack name    char                *devname;       // hardware device name    CYG_ADDRWORD        data;           // private data value    int     (*init)( cyg_nstab_entry *nste );    int     (*socket)( cyg_nstab_entry *nste, int domain, int type,		       int protocol, cyg_file *file );};This table is analogous to a combination of the filesystem and mounttables.The _valid_ field is set true if the stack's _init_ function returnedsuccessfully and the _syncmode_ field contains the CYG_SYNCMODE_SOCK_*bits described above.The _name_ field contains the name of the protocol stack.The _devname_ field names the device that the stack is using. This mayreference a device under "/dev", or may be a name that is onlymeaningful to the stack itself.The _init_ function is called during system initialization to startthe protocol stack running. If it returns non-zero the _valid_ fieldis set false and the stack will be ignored subsequently.The _socket_ function is called to attempt to create a socket in thestack. When the socket() API function is called the netstack table isscanned and for each valid entry the _socket_ function is called. Ifthis returns non-zero then the scan continues to the next valid stack,or terminates with an error if the end of the table is reached.The result of a successful socket call is an initialized file objectwith the _f_xops_ field pointing to the following structure:struct cyg_sock_ops{    int (*bind)      ( cyg_file *fp, const sockaddr *sa, socklen_t len );    int (*connect)   ( cyg_file *fp, const sockaddr *sa, socklen_t len );    int (*accept)    ( cyg_file *fp, cyg_file *new_fp,                       struct sockaddr *name, socklen_t *anamelen );    int (*listen)    ( cyg_file *fp, int len );    int (*getname)   ( cyg_file *fp, sockaddr *sa, socklen_t *len, int peer );    int (*shutdown)  ( cyg_file *fp, int flags );    int (*getsockopt)( cyg_file *fp, int level, int optname,                       void *optval, socklen_t *optlen);    int (*setsockopt)( cyg_file *fp, int level, int optname,                       const void *optval, socklen_t optlen);    int (*sendmsg)   ( cyg_file *fp, const struct msghdr *m,                       int flags, ssize_t *retsize );    int (*recvmsg)   ( cyg_file *fp, struct msghdr *m,                       socklen_t *namelen, ssize_t *retsize );};It should be obvious from the names of these functions which API callsthey provide support for. The _getname_ function provides support forboth getsockname() and getpeername() while the _sendmsg_ and _recvmsg_functions provide support for send(), sendto(), sendmsg(), recv(),recvfrom() and recvmsg() as appropriate.Select------The infrastructure provides support for implementing a selectmechanism. This is modeled on the mechanism in the BSD kernel, but hasbeen modified to make it implementation independent.The main part of the mechanism is the select() API call. Thisprocesses its arguments and calls the _fo_select_ function on all fileobjects referenced by the file descriptor sets passed to it. If thesame descriptor appears in more than one descriptor set, the_fo_select_ function will be called separately for each appearance.The _which_ argument of the _fo_select_ function will either beCYG_FREAD to test for read conditions, CYG_FWRITE to test for writeconditions or zero to test for exceptions. For each of these optionsthe function should test whether the condition is satisfied and if soreturn true. If it is not satisfied then it should callcyg_selrecord() with the _info_ argument that was passed to thefunction and a pointer to a cyg_selinfo structure.The cyg_selinfo structure is used to record information about currentselect operations. Any object that needs to support select mustcontain an instance of this structure.  Separate cyg_selinfostructures should be kept for each of the options that the object canselect on - read, write or exception.If none of the file objects report that the select condition issatisfied, then the select() API function puts the calling thread tosleep waiting either for a condition to become satisfied, or for theoptional timeout to expire.A selectable object must have some asynchronous activity that maycause a select condition to become true - either via interrupts or theactivities of other threads. Whenever a selectable condition issatisfied, the object should call cyg_selwakeup() with a pointer tothe appropriate cyg_selinfo structure. If the thread is still waiting,this will cause it to wake up and repeat its poll of the filedescriptors. This time around, the object that caused the wakeupshould indicate that the select condition is satisfied, and the_select()_ API call will return.Note that _select()_ does not exhibit real time behaviour: theiterative poll of the descriptors, and the wakeup mechanism mitigateagainst this. If real time response to device or socket I/O isrequired then separate threads should be devoted to each device ofinterest.Devices-------Devices are accessed by means of a pseudo-filesystem, "devfs", that ismounted on "/dev". Open operations are translated into calls tocyg_io_lookup() and if successful result in a file object whose_f_ops_ functions translate filesystem API functions into calls intothe device API.// EOF fileio.txt

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -