Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Removing Device Drivers with NSH

NuttX and Unix-like Operating Systems Compared

There are many things that are called device drivers. In this Wiki page, we are referring only to character device drivers. In NuttX, character devices drivers are represented by device driver nodes in the top-level pseudo filesystem.

...

But if the device node were simply removed in NuttX, then the entire device interface would also be removed and the driver would be basically broken. Internally, NuttX supports an interfaces called unregister_driver() that can be called to remove a device driver. So removing the device driver node must behave as though that interface were called.

The unlink method

How does NuttX accomplish this? It accomplish this using a special device driver method called unlink().



Wiki Markup
NuttX device drivers are implemented using a _vtable_ of function pointers.  That _vtable_ defines the interface between the pseudo-file system and a device driver.  This _vtable_ is the structure {{struct file_operations}} defined in the header file _\[nuttx]_{{/include/nuttx/fs/fs.h.}}  That interface defines several intefaces which, for the most part, closely match the standard POSIX interfaces -- {{open()}}, {{close()}}, {{read()}}, {{write()}}, etc. -- and also includes a method called {{unlink()}}.   This {{unlink()}} method is called by the NuttX VFS when the user attempts to remove a device driver nodes.



NOTE: Removal of device driver nodes is only permitted if CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not defined. All of operations on the pseudo-file system may be suppressed in order to reduce the FLASH footprint in very resource limited systems.

Removing a Device Node from NSH

Here, then, is a summary of what should happen when you delete a device node using the NSH rm command:

  • The user enters the rm command. The NSH parser recognizes the rm command and transfers control to the NSH function cmd_rm().


  • Wiki Markup
    {{cmd_rm()}} will verify the command, then call the standard POSIX {{unlink()}} interface.  The logic of the VFS {{unlink()}} function in _\[nuttx_{{/fs/vfs/fs_unlink.c}} will then run.



  • The VFS's unlink() will detect that the target to be removed is an a device node in the top-level pseudo-file system. It will call the device driver's unlink() method and, in any event, it will remove the device node from the pseudo-filesystem. The underlying resources needed to support the device driver interface may, however, persist until the device driver decides to free those resources.
  • When the device driver's unlink() method is called, it will determine if it is possible to free the device resources now. If so, it will free the device driver resources. But if, for example, there are clients of the device driver that still have open references to the device driver, it may defer freeing those resources until the last client has closed the device driver and there are no open references. In that case, it may simply set a flag indicating that the device driver has been unlinked.
  • If freeing of device driver resources has been deferred, then that flag will be examined later. For example, when the last client of the device driver has closed its reference to the driver it will check if the unlink operation has been deferred and, in that case, it will then free all of the device driver resources at that time.

WARNING

Some character device driver instances do not support the unlink() method. If you see problems removing character drivers in the manner described in this Wiki page, the most likely cause would be this missing implementation.