Documentation: migrate /drivers
This commit is contained in:
parent
8e40cfd1b6
commit
9bef53bbdd
9 changed files with 631 additions and 29 deletions
|
|
@ -38,3 +38,9 @@ Block device drivers have these properties:
|
|||
- **Examples**. ``drivers/loop.c``,
|
||||
``drivers/mmcsd/mmcsd_spi.c``, ``drivers/ramdisk.c``, etc.
|
||||
|
||||
``ramdisk.c``
|
||||
=============
|
||||
|
||||
Can be used to set up a block of memory or (read-only) FLASH as
|
||||
a block driver that can be mounted as a file system. See
|
||||
include/nuttx/drivers/ramdisk.h.
|
||||
|
|
|
|||
|
|
@ -67,4 +67,5 @@ Character device drivers have these properties:
|
|||
foc.rst
|
||||
ws2812.rst
|
||||
se05x.rst
|
||||
nullzero.rst
|
||||
|
||||
|
|
|
|||
8
Documentation/components/drivers/character/nullzero.rst
Normal file
8
Documentation/components/drivers/character/nullzero.rst
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
=================================
|
||||
``dev_null.c`` and ``dev_zero.c``
|
||||
=================================
|
||||
|
||||
These files provide the standard /dev/null and /dev/zero devices. See
|
||||
include/nuttx/drivers/drivers.h for prototypes of functions that should
|
||||
be called if you want to register these devices (devnull_register()
|
||||
and devzero_register()).
|
||||
|
|
@ -30,3 +30,218 @@ Drivers in NuttX generally work in two distinct layers:
|
|||
* A "lower half" which is typically hardware-specific. This is
|
||||
usually implemented at the architecture or board level.
|
||||
|
||||
Subdirectories of `nuttx/drivers`
|
||||
=================================
|
||||
|
||||
* ``analog/``
|
||||
|
||||
This directory holds implementations of analog device drivers.
|
||||
This includes drivers for Analog to Digital Conversion (ADC) as
|
||||
well as drivers for Digital to Analog Conversion (DAC).
|
||||
See ``include/nuttx/analog/*.h`` for registration information.
|
||||
|
||||
* ``audio/``
|
||||
|
||||
Audio device drivers.
|
||||
|
||||
See ``include/nuttx/audio/audio.h`` for interface definitions.
|
||||
See also the audio subsystem at ``nuttx/audio/``.
|
||||
|
||||
* ``bch/``
|
||||
|
||||
Contains logic that may be used to convert a block driver into
|
||||
a character driver. This is the complementary conversion as that
|
||||
performed by loop.c.
|
||||
|
||||
See ``include/nuttx/fs/fs.h`` for registration information.
|
||||
|
||||
* ``can/``
|
||||
|
||||
This is the CAN drivers and logic support.
|
||||
|
||||
See ``include/nuttx/can/can.h`` for usage information.
|
||||
|
||||
* ``contactless/``
|
||||
|
||||
Contactless devices are related to wireless devices. They are not
|
||||
communication devices with other similar peers, but couplers/interfaces
|
||||
to contactless cards and tags.
|
||||
|
||||
* ``crypto/``
|
||||
|
||||
Contains crypto drivers and support logic, including the ``/dev/urandom`` device.
|
||||
|
||||
* ``eeprom/``
|
||||
|
||||
An EEPROM is a form of Memory Technology Device (see ``drivers/mtd``).
|
||||
EEPROMs are non-volatile memory like FLASH, but differ in underlying
|
||||
memory technology and differ in usage in many respects: They may not
|
||||
be organized into blocks (at least from the standpoint of the user)
|
||||
and it is not necessary to erase the EEPROM memory before re-writing
|
||||
it. In addition, EEPROMs tend to be much smaller than FLASH parts,
|
||||
usually only a few kilobytes vs megabytes for FLASH. EEPROM tends to
|
||||
be used to retain a small amount of device configuration information;
|
||||
FLASH tends to be used for program or massive data storage. For these
|
||||
reasons, it may not be convenient to use the more complex MTD
|
||||
interface but instead use the simple character interface provided by
|
||||
the EEPROM drivers.
|
||||
|
||||
* ``i2c/``
|
||||
|
||||
I2C drivers and support logic.
|
||||
|
||||
See ``include/nuttx/i2c/i2c_master.h``
|
||||
|
||||
* ``i2s/``
|
||||
|
||||
I2S drivers and support logic.
|
||||
|
||||
See ``include/nuttx/audio/i2s.h``
|
||||
|
||||
* ``input/``
|
||||
|
||||
This directory holds implementations of human input device (HID) drivers.
|
||||
This includes such things as mouse, touchscreen, joystick,
|
||||
keyboard and keypad drivers.
|
||||
|
||||
See ``include/nuttx/input/*.h`` for registration information.
|
||||
|
||||
Note that USB HID devices are treated differently. These can be found under
|
||||
``usbdev/`` or ``usbhost/``.
|
||||
|
||||
* ``lcd/``
|
||||
|
||||
Drivers for parallel and serial LCD and OLED type devices. These drivers support
|
||||
interfaces as defined in ``include/nuttx/lcd/lcd.h``
|
||||
|
||||
* ``leds/``
|
||||
|
||||
Various LED-related drivers including discrete as well as PWM- driven LEDs.
|
||||
|
||||
* ``loop/``
|
||||
|
||||
Supports the standard loop device that can be used to export a
|
||||
file (or character device) as a block device.
|
||||
|
||||
See ``losetup()`` and ``loteardown()`` in ``include/nuttx/fs/fs.h``.
|
||||
|
||||
* ``mmcsd/``
|
||||
|
||||
Support for MMC/SD block drivers. MMC/SD block drivers based on
|
||||
SPI and SDIO/MCI interfaces are supported.
|
||||
|
||||
See include/nuttx/mmcsd.h and include/nuttx/sdio.h for further information.
|
||||
|
||||
* ``mtd/``
|
||||
|
||||
Memory Technology Device (MTD) drivers. Some simple drivers for
|
||||
memory technologies like FLASH, EEPROM, NVRAM, etc.
|
||||
|
||||
|
||||
See ``include/nuttx/mtd/mtd.h``
|
||||
|
||||
(Note: This is a simple memory interface and should not be
|
||||
confused with the "real" MTD developed at infradead.org. This
|
||||
logic is unrelated; I just used the name MTD because I am not
|
||||
aware of any other common way to refer to this class of devices).
|
||||
|
||||
* ``net/``
|
||||
|
||||
Network interface drivers.
|
||||
|
||||
See also ``include/nuttx/net/net.h``
|
||||
|
||||
* ``pipes/``
|
||||
|
||||
FIFO and named pipe drivers. Standard interfaces are declared in ``include/unistd.h``
|
||||
|
||||
* ``power/``
|
||||
|
||||
Power management (PM) driver interfaces. These interfaces are used
|
||||
to manage power usage of a platform by monitoring driver activity
|
||||
and by placing drivers into reduce power usage modes when the
|
||||
drivers are not active.
|
||||
|
||||
* ``pwm/``
|
||||
|
||||
Provides the "upper half" of a pulse width modulation (PWM) driver.
|
||||
The "lower half" of the PWM driver is provided by device-specific logic.
|
||||
|
||||
See ``include/nuttx/timers/pwm.h`` for usage information.
|
||||
|
||||
* ``sensors/``
|
||||
|
||||
Drivers for various sensors. A sensor driver differs little from
|
||||
other types of drivers other than they are use to provide measurements
|
||||
of things in environment like temperature, orientation, acceleration,
|
||||
altitude, direction, position, etc.
|
||||
|
||||
DACs might fit this definition of a sensor driver as well since they
|
||||
measure and convert voltage levels. DACs, however, are retained in
|
||||
the ``analog/`` sub-directory.
|
||||
|
||||
* ``serial/``
|
||||
|
||||
Front-end character drivers for chip-specific UARTs.
|
||||
This provide some TTY-like functionality and are commonly used (but
|
||||
not required for) the NuttX system console.
|
||||
|
||||
See also ``include/nuttx/serial/serial.h``
|
||||
|
||||
* ``spi/``
|
||||
|
||||
SPI drivers and support logic.
|
||||
|
||||
See ``include/nuttx/spi/spi.h``
|
||||
|
||||
* ``syslog/``
|
||||
|
||||
System logging devices.
|
||||
|
||||
See ``include/syslog.h`` and ``include/nuttx/syslog/syslog.h``
|
||||
|
||||
* ``timers/``
|
||||
|
||||
Includes support for various timer devices including:
|
||||
|
||||
- An "upper half" for a generic timer driver.
|
||||
See ``include/nuttx/timers/timer.h`` for more information.
|
||||
|
||||
- An "upper half" for a generic watchdog driver.
|
||||
See ``include/nuttx/timers/watchdog.h`` for more information.
|
||||
|
||||
- RTC drivers
|
||||
|
||||
* ``usbdev/``
|
||||
|
||||
USB device drivers.
|
||||
|
||||
See also ``include/nuttx/usb/usbdev.h``
|
||||
|
||||
* ``usbhost/``
|
||||
|
||||
USB host drivers.
|
||||
|
||||
See also ``include/nuttx/usb/usbhost.h``
|
||||
|
||||
* ``video/``
|
||||
|
||||
Video-related drivers.
|
||||
|
||||
See ``include/nuttx/video/``
|
||||
|
||||
* ``wireless/``
|
||||
|
||||
Drivers for various wireless devices.
|
||||
|
||||
Skeleton Files
|
||||
==============
|
||||
|
||||
Skeleton files are "empty" frameworks for NuttX drivers. They are provided to
|
||||
give you a good starting point if you want to create a new NuttX driver.
|
||||
The following skeleton files are available::
|
||||
|
||||
drivers/lcd/skeleton.c -- Skeleton LCD driver
|
||||
drivers/mtd/skeleton.c -- Skeleton memory technology device drivers
|
||||
drivers/net/skeleton.c -- Skeleton network/Ethernet drivers
|
||||
drivers/usbhost/usbhost_skeleton.c -- Skeleton USB host class driver
|
||||
|
|
|
|||
|
|
@ -33,4 +33,5 @@ following section.
|
|||
sdio.rst
|
||||
usbhost.rst
|
||||
usbdev.rst
|
||||
|
||||
rwbuffer.rst
|
||||
regmap.rst
|
||||
|
|
|
|||
|
|
@ -6,16 +6,19 @@ The LCD driver exposes the LCD interface to userspace via ``ioctl()`` commands.
|
|||
|
||||
The LCD driver is intended to be used in the following scenarios:
|
||||
|
||||
#. On memory-constrained devices, as it doesn't require a buffer to represent the whole display:
|
||||
* On memory-constrained devices, as it doesn't require a buffer to represent
|
||||
the whole display:
|
||||
|
||||
#. Hence, it's an alternative to the :doc:`framebuffer`;
|
||||
* Hence, it's an alternative to the :doc:`framebuffer`
|
||||
|
||||
#. For graphics libraries that draw specific areas of the displays, like ``LVGL``;
|
||||
* For graphics libraries that draw specific areas of the displays, like ``LVGL``
|
||||
|
||||
Binding
|
||||
========
|
||||
LCD drivers usually are not directly accessed by user code, but are usually bound to another, higher-level device driver.
|
||||
In general, the binding sequence is:
|
||||
=======
|
||||
|
||||
|
||||
LCD drivers usually are not directly accessed by user code, but are usually
|
||||
bound to another, higher-level device driver. In general, the binding sequence is:
|
||||
|
||||
#. Get an instance of ``struct lcd_dev_s`` from the hardware-specific LCD screen driver, and
|
||||
#. Provide that instance to the initialization method of the higher-level character driver.
|
||||
|
|
@ -25,20 +28,29 @@ In general, the binding sequence is:
|
|||
Generic LCD Character Driver
|
||||
----------------------------
|
||||
|
||||
This example will walk through the path from userspace to hardware-specific details on how an LCD screen is bound to an LCD character driver.
|
||||
This example will walk through the path from userspace to hardware-specific
|
||||
details on how an LCD screen is bound to an LCD character driver.
|
||||
|
||||
#. ``include/nuttx/lcd/lcd.h`` provides all structures and APIs needed to work with LCD screens drivers:
|
||||
* ``include/nuttx/lcd/lcd.h`` provides all structures and APIs needed to work
|
||||
with LCD screens drivers:
|
||||
|
||||
#. This header file also depends on some of the same definitions used for the frame buffer driver as provided in ``include/nuttx/video/fb.h``;
|
||||
#. ``drivers/lcd/lcd_dev.c`` is the higher-level device driver. An instance of ``struct lcd_dev_s`` will be provided to it:
|
||||
* This header file also depends on some of the same definitions used for the
|
||||
frame buffer driver as provided in ``include/nuttx/video/fb.h``
|
||||
|
||||
#. ``include/nuttx/lcd/lcd_dev.h`` prototypes public structures and functions;
|
||||
#. ``lcddev_register`` registers the LCD character driver as ``/dev/lcdN`` where N is the display number and,
|
||||
#. calls the ``board_lcd_getdev``, an LCD-specific function usually defined in ``boards/<arch>/<chip>/<board>/src`` and prototyped in ``include/nuttx/board.h``;
|
||||
* ``drivers/lcd/lcd_dev.c`` is the higher-level device driver. An instance of
|
||||
``struct lcd_dev_s`` will be provided to it:
|
||||
|
||||
#. Finally, the LCD screen drivers are usually available at ``drivers/lcd/`` and implement the callbacks defined at ``include/nuttx/lcd/lcd.h``:
|
||||
* ``include/nuttx/lcd/lcd_dev.h`` prototypes public structures and functions;
|
||||
* ``lcddev_register`` registers the LCD character driver as ``/dev/lcdN``
|
||||
where N is the display number and,
|
||||
* calls the ``board_lcd_getdev``, an LCD-specific function usually defined in
|
||||
``boards/<arch>/<chip>/<board>/src`` and prototyped in ``include/nuttx/board.h``
|
||||
|
||||
#. ``include/nuttx/lcd/lcd.h`` provides structures and APIs needed to work with LCD screens, whether using the framebuffer adapter or the :doc:`lcd`;
|
||||
* Finally, the LCD screen drivers are usually available at ``drivers/lcd/`` and
|
||||
implement the callbacks defined at ``include/nuttx/lcd/lcd.h``:
|
||||
|
||||
* ``include/nuttx/lcd/lcd.h`` provides structures and APIs needed to work
|
||||
with LCD screens, whether using the framebuffer adapter or the :doc:`lcd`;
|
||||
|
||||
|
||||
Examples
|
||||
|
|
@ -52,9 +64,11 @@ TTGO T-Display ESP32 board
|
|||
---------------------------
|
||||
|
||||
This board contains an ST7789 TFT Display (135x240).
|
||||
By selecting the ``ttgo_t_display_esp32:lvgl_lcd`` config, the ``lvgldemo`` example will be built with the LCD character interface.
|
||||
By selecting the ``ttgo_t_display_esp32:lvgl_lcd`` config, the ``lvgldemo``
|
||||
example will be built with the LCD character interface.
|
||||
|
||||
* ``boards/xtensa/esp32/ttgo_t_display_esp32/src/esp32_bringup.c`` registers the LCD character driver:
|
||||
* ``boards/xtensa/esp32/ttgo_t_display_esp32/src/esp32_bringup.c`` registers the
|
||||
LCD character driver:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
|
@ -72,16 +86,22 @@ By selecting the ``ttgo_t_display_esp32:lvgl_lcd`` config, the ``lvgldemo`` exam
|
|||
}
|
||||
#endif
|
||||
|
||||
* ``board_lcd_initialize`` and ``board_lcd_getdev`` are defined at ``boards/xtensa/esp32/common/src/esp32_st7789.c``;
|
||||
* ``board_lcd_initialize`` and ``board_lcd_getdev`` are defined at
|
||||
``boards/xtensa/esp32/common/src/esp32_st7789.c``;
|
||||
|
||||
* ``board_lcd_initialize`` initializes the LCD hardware on the board by defining the SPI interface which is connected to the display controller;
|
||||
* ``board_lcd_initialize`` initializes the LCD hardware on the board by
|
||||
defining the SPI interface which is connected to the display controller;
|
||||
|
||||
* ``lcddev_register`` then calls ``board_lcd_getdev``:
|
||||
|
||||
* ``board_lcd_getdev`` calls the ``st7789_lcdinitialize`` and returns a reference to the LCD object for the specified LCD;
|
||||
* ``st7789_lcdinitialize`` is part of the LCD screen driver at ``drivers/lcd/st7789.c``;
|
||||
* ``board_lcd_getdev`` calls the ``st7789_lcdinitialize`` and returns a
|
||||
reference to the LCD object for the specified LCD;
|
||||
* ``st7789_lcdinitialize`` is part of the LCD screen driver at
|
||||
``drivers/lcd/st7789.c``;
|
||||
|
||||
* The LVGL demo application (``lvgldemo``) makes use of the ``ioctl`` system call to trigger an ``LCDDEVIO_PUTAREA`` request to the higher-level device driver to refresh the LCD screen with data:
|
||||
* The LVGL demo application (``lvgldemo``) makes use of the ``ioctl`` system
|
||||
call to trigger an ``LCDDEVIO_PUTAREA`` request to the higher-level device
|
||||
driver to refresh the LCD screen with data:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
|
@ -90,15 +110,25 @@ By selecting the ``ttgo_t_display_esp32:lvgl_lcd`` config, the ``lvgldemo`` exam
|
|||
NuttX Simulator
|
||||
----------------
|
||||
|
||||
:doc:`NuttX Simulator </platforms/sim/sim/index>` provides a X11-based LCD character driver to simulate the LCD character displat usage into a X11-compatible host.
|
||||
:doc:`NuttX Simulator </platforms/sim/sim/index>` provides a X11-based LCD
|
||||
character driver to simulate the LCD character displat usage into a
|
||||
X11-compatible host.
|
||||
|
||||
By selecting the ``sim:lvgl_lcd`` config, the ``lvgldemo`` example will be built with the LCD character interface.
|
||||
By selecting the ``sim:lvgl_lcd`` config, the ``lvgldemo`` example will be
|
||||
built with the LCD character interface.
|
||||
|
||||
* ``boards/sim/sim/sim/src/sim_bringup.c`` registers the lcd driver the same way :ref:`ttgotdisplayesp32_lcd`;
|
||||
* ``arch/sim/src/sim/up_lcd.c`` and ``arch/sim/src/sim/up_x11framebuffer.c`` will be built as ``CONFIG_SIM_LCDDRIVER = y`` and ``CONFIG_SIM_X11FB = y`` are set, respectively;
|
||||
* ``boards/sim/sim/sim/src/sim_bringup.c`` registers the lcd driver the
|
||||
same way :ref:`ttgotdisplayesp32_lcd`;
|
||||
* ``arch/sim/src/sim/up_lcd.c`` and ``arch/sim/src/sim/up_x11framebuffer.c``
|
||||
will be built as ``CONFIG_SIM_LCDDRIVER = y`` and ``CONFIG_SIM_X11FB = y``
|
||||
are set, respectively;
|
||||
|
||||
* ``up_lcd.c`` provides ``board_lcd_initialize`` and ``board_lcd_getdev``:
|
||||
|
||||
* ``board_lcd_initialize`` calls ``up_x11initialize`` from ``up_x11framebuffer.c`` that initializes a X11-based window as an LCD character device. This is the underlying "driver".
|
||||
* ``board_lcd_initialize`` calls ``up_x11initialize`` from
|
||||
``up_x11framebuffer.c`` that initializes a X11-based window as an LCD
|
||||
character device. This is the underlying "driver".
|
||||
|
||||
* The LVGL demo application (``lvgldemo``) makes use of the ``ioctl`` system call to trigger an ``LCDDEVIO_PUTAREA`` request to the higher-level device driver to refresh the LCD screen with data as usual;
|
||||
* The LVGL demo application (``lvgldemo``) makes use of the ``ioctl`` system
|
||||
call to trigger an ``LCDDEVIO_PUTAREA`` request to the higher-level device
|
||||
driver to refresh the LCD screen with data as usual;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
Memory Technology Device Drivers
|
||||
================================
|
||||
|
||||
MTD stands for "Memory Technology Devices". This directory contains
|
||||
drivers that operate on various memory technology devices and provide an
|
||||
MTD interface. That MTD interface may then be used by higher level logic
|
||||
to control access to the memory device.
|
||||
|
||||
See include/nuttx/mtd/mtd.h for additional information.
|
||||
|
||||
- ``include/nuttx/mtd/mtd.h``. All structures and APIs needed
|
||||
to work with MTD drivers are provided in this header file.
|
||||
|
||||
|
|
@ -43,3 +50,151 @@ Memory Technology Device Drivers
|
|||
higher level device driver.
|
||||
|
||||
- **Examples**: ``drivers/mtd/m25px.c`` and ``drivers/mtd/ftl.c``
|
||||
|
||||
EEPROM
|
||||
======
|
||||
|
||||
EEPROMs are a form of Memory Technology Device (MTD). EEPROMs are non-
|
||||
volatile memory like FLASH, but differ in underlying memory technology and
|
||||
differ in usage in many respects: They may not be organized into blocks
|
||||
(at least from the standpoint of the user) and it is not necessary to
|
||||
erase the EEPROM memory before re-writing it. In addition, EEPROMs tend
|
||||
to be much smaller than FLASH parts, usually only a few kilobytes vs
|
||||
megabytes for FLASH. EEPROM tends to be used to retain a small amount of
|
||||
device configuration information; FLASH tends to be used for program or
|
||||
massive data storage. For these reasons, it may not be convenient to use
|
||||
the more complex MTD interface but instead use the simple character
|
||||
interface provided by the EEPROM drivers. See drivers/eeprom.
|
||||
|
||||
|
||||
NAND MEMORY
|
||||
===========
|
||||
|
||||
Files
|
||||
-----
|
||||
|
||||
This directory also includes drivers for NAND memory. These include::
|
||||
|
||||
mtd_nand.c: The "upper half" NAND MTD driver
|
||||
mtd_nandecc.c, mtd_nandscheme.c, and hamming.c: Implement NAND software
|
||||
ECC
|
||||
mtd_onfi.c, mtd_nandmodel.c, and mtd_modeltab.c: Implement NAND FLASH
|
||||
identification logic.
|
||||
|
||||
File Systems
|
||||
------------
|
||||
|
||||
NAND support is only partial in that there is no file system that works
|
||||
with it properly. It should be considered a work in progress. You will
|
||||
not want to use NAND unless you are interested in investing a little
|
||||
effort. See the STATUS section below.
|
||||
|
||||
NXFFS
|
||||
~~~~~
|
||||
|
||||
The NuttX FLASH File System (NXFFS) works well with NOR-like FLASH
|
||||
but does not work well with NAND. Some simple usability issues
|
||||
include:
|
||||
|
||||
- NXFFS can be very slow. The first time that you start the system,
|
||||
be prepared for a wait; NXFFS will need to format the NAND volume.
|
||||
I have lots of debug on so I don't yet know what the optimized wait
|
||||
will be. But with debug ON, software ECC, and no DMA the wait is
|
||||
in many tens of minutes (and substantially longer if many debug
|
||||
options are enabled.
|
||||
|
||||
- On subsequent boots, after the NXFFS file system has been created
|
||||
the delay will be less. When the new file system is empty, it will
|
||||
be very fast. But the NAND-related boot time can become substantial
|
||||
whenthere has been a lot of usage of the NAND. This is because
|
||||
NXFFS needs to scan the NAND device and build the in-memory dataset
|
||||
needed to access NAND and there is more that must be scanned after
|
||||
the device has been used. You may want tocreate a separate thread at
|
||||
boot time to bring up NXFFS so that you don't delay the boot-to-prompt
|
||||
time excessively in these longer delay cases.
|
||||
|
||||
- There is another NXFFS related performance issue: When the FLASH
|
||||
is fully used, NXFFS will restructure the entire FLASH, the delay
|
||||
to restructure the entire FLASH will probably be even larger. This
|
||||
solution in this case is to implement an NXFSS clean-up daemon that
|
||||
does the job a little-at-a-time so that there is no massive clean-up
|
||||
when the FLASH becomes full.
|
||||
|
||||
But there is a more serious, showstopping problem with NXFFS and NAND:
|
||||
|
||||
- Bad NXFFS behavior with NAND: If you restart NuttX, the files that
|
||||
you wrote to NAND will be gone. Why? Because the multiple writes
|
||||
have corrupted the NAND ECC bits. See STATUS below. NXFFS would
|
||||
require a major overhaul to be usable with NAND.
|
||||
|
||||
There are a few reasons whay NXFFS does not work with NAND. NXFFS was
|
||||
designed to work with NOR-like FLASH and NAND differs from other that
|
||||
FLASH model in several ways. For one thing, NAND requires error
|
||||
correction (ECC) bytes that must be set in order to work around bit
|
||||
failures. This affects NXFFS in two ways:
|
||||
|
||||
- First, write failures are not fatal. Rather, they should be tried by
|
||||
bad blocks and simply ignored. This is because unrecoverable bit
|
||||
failures will cause read failures when reading from NAND. Setting
|
||||
the CONFIG_EXPERIMENTAL+CONFIG_NXFFS_NAND option will enable this
|
||||
behavior.
|
||||
|
||||
[CONFIG_NXFFS_NAND is only available is CONFIG_EXPERIMENTAL is also
|
||||
selected.]
|
||||
|
||||
- Secondly, NXFFS will write a block many times. It tries to keep
|
||||
bits in the erased state and assumes that it can overwrite those bits
|
||||
to change them from the erased to the non-erased state. This works
|
||||
will with NOR-like FLASH. NAND behaves this way too. But the
|
||||
problem with NAND is that the ECC bits cannot be re-written in this
|
||||
way. So once a block has been written, it cannot be modified. This
|
||||
behavior has NOT been fixed in NXFFS. Currently, NXFFS will attempt
|
||||
to re-write the ECC bits causing the ECC to become corrupted because
|
||||
the ECC bits cannot be overwritten without erasing the entire block.
|
||||
|
||||
This may prohibit NXFFS from ever being used with NAND.
|
||||
|
||||
FAT
|
||||
~~~
|
||||
|
||||
Another option is FAT. FAT can be used if the Flast Translation Layer
|
||||
(FTL) is enabled. FTL converts the NAND MTD interface to a block driver
|
||||
that can then be used with FAT.
|
||||
|
||||
FAT, however, will not handle bad blocks and does not perform any wear
|
||||
leveling. So you can bring up a NAND file system with FAT and a new,
|
||||
clean NAND FLASH but you need to know that eventually, there will be
|
||||
NAND bit failures and FAT will stop working: If you hit a bad block,
|
||||
then FAT is finished. There is no mechanism in place in FAT not to
|
||||
mark and skip over bad blocks.
|
||||
|
||||
FTL writes are also particularly inefficient with NAND. In order to
|
||||
write a sector, FTL will read the entire erase block into memory, erase
|
||||
the block on FLASH, modify the sector and re-write the erase block back
|
||||
to FLASH. For large NANDs this can be very inefficient. For example,
|
||||
I am currently using nand with a 128KB erase block size and 2K page size
|
||||
so each write can cause a 256KB data transfer!
|
||||
|
||||
NOTE that there is some caching logic within FAT and FTL so that this
|
||||
cached erase block can be re-used if possible and writes will be
|
||||
deferred as long as possible.
|
||||
|
||||
SMART FS
|
||||
~~~~~~~~
|
||||
|
||||
I have not yet tried SmartFS. It does support some wear-leveling
|
||||
similar to NXFFS, but like FAT, cannot handle bad blocks and like NXFFS,
|
||||
it will try to re-write erased bits. So SmartFS is not really an
|
||||
option either.
|
||||
|
||||
What is Needed
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
What is needed to work with FAT properly would be another MTD layer
|
||||
between the FTL layer and the NAND FLASH layer. That layer would
|
||||
perform bad block detection and sparing so that FAT works transparently
|
||||
on top of the NAND.
|
||||
|
||||
Another, less general, option would be support bad blocks within FAT.
|
||||
Such a solution migh be possible for SLC NAND, but would not be
|
||||
sufficiently general for all NAND types.
|
||||
|
|
|
|||
180
Documentation/components/drivers/special/regmap.rst
Normal file
180
Documentation/components/drivers/special/regmap.rst
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
==============
|
||||
drivers/regmap
|
||||
==============
|
||||
|
||||
This is the documentation page for the drivers/regmap/.
|
||||
|
||||
Regmap Header files
|
||||
===================
|
||||
|
||||
- ``include/nuttx/regmap/regmap.h``
|
||||
|
||||
The structures and APIS used in regimap are in this header file.
|
||||
|
||||
- ``struct regmap_bus_s``
|
||||
|
||||
Each bus must implement an instance of struct regmap_bus_s. That structure
|
||||
defines a call table with the following methods:
|
||||
|
||||
- Single byte reading of the register (8bits)
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
typedef CODE int (*reg_read_t)(FAR struct regmap_bus_s *bus,
|
||||
unsigned int reg,
|
||||
FAR void *val);
|
||||
|
||||
- Single byte writing of the register (8bits)
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
typedef CODE int (*reg_write_t)(FAR struct regmap_bus_s *bus,
|
||||
unsigned int reg,
|
||||
unsigned int val);
|
||||
|
||||
- Bulk register data reading.
|
||||
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
typedef CODE int (*read_t)(FAR struct regmap_bus_s *bus,
|
||||
FAR const void *reg_buf, unsigned int reg_size,
|
||||
FAR void *val_buf, unsigned int val_size);
|
||||
|
||||
- Bulk register data writing.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
typedef CODE int (*write_t)(FAR struct regmap_bus_s *bus,
|
||||
FAR const void *data,
|
||||
unsigned int count);
|
||||
|
||||
- Initialize the internal configuration of regmap. The first parameter must
|
||||
be the handle of the bus, and the second parameter is the configuration
|
||||
parameter of the bus. Finally, these two parameters will be transparent
|
||||
to the corresponding bus. If you want to implement the bus interface by
|
||||
yourself, you need to realize the corresponding bus initialization function,
|
||||
refer to regimap_i2c.c and regmap_spi.c.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
FAR struct regmap_s *regmap_init(FAR struct regmap_bus_s *bus,
|
||||
FAR const struct regmap_config_s *config);
|
||||
|
||||
- Regmap init i2c bus.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
FAR struct regmap_s *regmap_init_i2c(FAR struct i2c_master_s *i2c,
|
||||
FAR struct i2c_config_s *i2c_config,
|
||||
FAR const struct regmap_config_s *config);
|
||||
|
||||
- regmap init spi bus.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
FAR struct regmap_s *regmap_init_spi(FAR struct spi_dev_s *spi, uint32_t freq,
|
||||
uint32_t devid, enum spi_mode_e mode,
|
||||
FAR const struct regmap_config_s *config);
|
||||
|
||||
- Exit and destroy regmap
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void regmap_exit(FAR struct regmap_s *map);
|
||||
|
||||
- Regmap write() bulk_write() read() bulk_read(), called after initializing
|
||||
the regmap bus device. the first parameter is regmap_s pointer.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
int regmap_write(FAR struct regmap_s *map, unsigned int reg,
|
||||
unsigned int val);
|
||||
int regmap_bulk_write(FAR struct regmap_s *map, unsigned int reg,
|
||||
FAR const void *val, unsigned int val_count);
|
||||
int regmap_read(FAR struct regmap_s *map, unsigned int reg,
|
||||
FAR void *val);
|
||||
int regmap_bulk_read(FAR struct regmap_s *map, unsigned int reg,
|
||||
FAR void *val, unsigned int val_count);
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
BMI160 sensor as an example:
|
||||
- Head file
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/bmi160.h>
|
||||
#include <nuttx/regmap/regmap.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
- Define the regmap_s handle in the driver's life cycle
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
struct bmi160_dev_s
|
||||
{
|
||||
#ifdef CONFIG_SENSORS_BMI160_I2C
|
||||
FAR struct regmap_s * regmap; /* Regmap interface */
|
||||
#else /* CONFIG_SENSORS_BMI160_SPI */
|
||||
FAR struct spi_dev_s *spi; /* SPI interface */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
- Initialize regmap
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
int bmi160_i2c_regmap_init(FAR struct bmi160_dev_s *priv,
|
||||
FAR struct i2c_master_s *i2c)
|
||||
{
|
||||
struct regmap_config_s config;
|
||||
struct i2c_config_s dev_config;
|
||||
|
||||
config.reg_bits = 8;
|
||||
config.val_bits = 8;
|
||||
config.disable_locking = true;
|
||||
|
||||
dev_config.frequency = BMI160_I2C_FREQ;
|
||||
dev_config.address = BMI160_I2C_ADDR;
|
||||
dev_config.addrlen = 7;
|
||||
|
||||
priv->regmap = regmap_init_i2c(i2c, &dev_config, &config);
|
||||
if (priv->regmap == NULL)
|
||||
{
|
||||
snerr("bmi160 Initialize regmap configuration failed!");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
- Use:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(priv->regmap, regaddr, ®val);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("regmap read address[%2X] failed: %d!\n", regaddr, ret);
|
||||
}
|
||||
|
||||
|
||||
ret = regmap_write(priv->regmap, regaddr, regval);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("regmap write address[%2X] failed: %d!\n", regaddr, ret);
|
||||
}
|
||||
|
||||
ret = regmap_bulk_read(priv->regmap, regaddr, regval, len);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("regmap read bulk address[%2X] failed: %d!\n", regaddr, ret);
|
||||
}
|
||||
6
Documentation/components/drivers/special/rwbuffer.rst
Normal file
6
Documentation/components/drivers/special/rwbuffer.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
==============
|
||||
``rwbuffer.c``
|
||||
==============
|
||||
|
||||
A facility that can be used by any block driver in-order to add
|
||||
writing buffering and read-ahead buffering.
|
||||
Loading…
Add table
Reference in a new issue