LCD Character Drivers
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: - Hence, it’s an alternative to the Frame Buffer Drivers; 
 
- 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:
- Get an instance of - struct lcd_dev_sfrom the hardware-specific LCD screen driver, and
- Provide that instance to the initialization method of the higher-level character driver. 
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.
- include/nuttx/lcd/lcd.hprovides 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.cis the higher-level device driver. An instance of- struct lcd_dev_swill be provided to it:- include/nuttx/lcd/lcd_dev.hprototypes public structures and functions;
- lcddev_registerregisters the LCD character driver as- /dev/lcdNwhere N is the display number and,
- calls the - board_lcd_getdev, an LCD-specific function usually defined in- boards/<arch>/<chip>/<board>/srcand prototyped in- include/nuttx/board.h;
 
- 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.hprovides structures and APIs needed to work with LCD screens, whether using the framebuffer adapter or the LCD Character Drivers;
 
Examples
Examples apply to specific cases of the Generic LCD Character Driver:
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.
- boards/xtensa/esp32/ttgo_t_display_esp32/src/esp32_bringup.cregisters the LCD character driver:
#ifdef CONFIG_LCD_DEV
 ret = board_lcd_initialize();
 if (ret < 0)
   {
     syslog(LOG_ERR, "ERROR: board_lcd_initialize() failed: %d\n", ret);
   }
 ret = lcddev_register(0);
 if (ret < 0)
   {
     syslog(LOG_ERR, "ERROR: lcddev_register() failed: %d\n", ret);
   }
#endif
- board_lcd_initializeand- board_lcd_getdevare defined at- boards/xtensa/esp32/common/src/esp32_st7789.c;- board_lcd_initializeinitializes the LCD hardware on the board by defining the SPI interface which is connected to the display controller;
 
- lcddev_registerthen calls- board_lcd_getdev:- board_lcd_getdevcalls the- st7789_lcdinitializeand returns a reference to the LCD object for the specified LCD;
- st7789_lcdinitializeis part of the LCD screen driver at- drivers/lcd/st7789.c;
 
- The LVGL demo application ( - lvgldemo) makes use of the- ioctlsystem call to trigger an- LCDDEVIO_PUTAREArequest to the higher-level device driver to refresh the LCD screen with data:
ioctl(state.fd, LCDDEVIO_PUTAREA, (unsigned long)((uintptr_t)&lcd_area));;
NuttX Simulator
NuttX Simulator 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.
- boards/sim/sim/sim/src/sim_bringup.cregisters the lcd driver the same way TTGO T-Display ESP32 board;
- arch/sim/src/sim/up_lcd.cand- arch/sim/src/sim/up_x11framebuffer.cwill be built as- CONFIG_SIM_LCDDRIVER = yand- CONFIG_SIM_X11FB = yare set, respectively;- up_lcd.cprovides- board_lcd_initializeand- board_lcd_getdev:- board_lcd_initializecalls- up_x11initializefrom- up_x11framebuffer.cthat initializes a X11-based window as an LCD character device. This is the underlying “driver”.
 
 
- The LVGL demo application ( - lvgldemo) makes use of the- ioctlsystem call to trigger an- LCDDEVIO_PUTAREArequest to the higher-level device driver to refresh the LCD screen with data as usual;