linux tft lcd driver hdmi brands

Compatible and Direct-connect with any revision of Raspberry Pi. (If you are using a Raspberry Pi Zero / Zero 2 W, an additional HDMI cable is required).

linux tft lcd driver hdmi brands

I just finished two solid days of work trying to get an HDMI LCD panel working with one of the inexpensive older model TFT LCD displays in a "Dual mode" configuration. There was a tremendous amount of help from this post, which got me most of the way there, but the infamous "last mile" still took me a while. I"m leaving some breadcrumbs here, as well as asking the group if anyone knows of a better way.

I am working on a device that uses a Raspberry Pi 4 as an embedded controller. For output, I need an 2K DSI LCD w/ its own HDMI adapter (Sharp LS055R1SX04, about $65 USD), as well as an inexpensive TFT LCD used for a basic touch user interface. The TFT LCD, which uses an ILI9341 LCD controller and an ads7846 touchscreen controller, can be had for about $10 USD. The Pi was flashed with the latest Raspberry Pi OS 32 bit then updated, so everything is current as of this writing (March 2021).

Initial configuration of the display worked with little issue. The HDMI adapter for the Sharp LCD works at 50 Hz only, so it requires custom timings. The TFT LCD uses the same controller chips as the original 3.5" Raspberry Pi LCD, so I was able to activate it with the rpi-display dtoverlay.

Booting with the above correctly revealed two framebuffer devices listed with ls -l /dev/fb*. The display initially showed as all white, then went all black, indicating correct initialization. However, when starting the desktop GUI, only the Sharp LCD showed any contents, and only it was listed as a device by xrandr.

Based on claims of the above not being "ideal", I experimented with various settings. If the above file is deleted entirely, xrandr reports the Sharp LCD as the sole display. If you put the above file in place, and remove all references to the Sharp LCD (including the Device, Monitor, Screen, and ServerLayouts), xrandr correctly reports the TFT LCD, but not the Sharp LCD. I left JUST the Device sections in, but xrandr failed to correctly report one of the other.

No matter what combinations I tried, I was unable to get xrandr to list both the HDMI display and the SPI display at the same time. If all parts above ARE explicitly listed in the configuration, running xrandr reports an error that the RandR extension is not loaded. Thus I was unable to use the more advanced built in layout management of X11 using the RandR extension.

Since xrandr was INOP in this configuration, I could not use xinput --map-to-output to limit touchscreen coordinates to the TFT LCD. Instead, I settled on using a combination of touch screen rotation, and input coordinate translation:

Note that the TransformationMatrix is very specific to a 1440x2560 in portrait mode with 320x240 in landscape mode to the right of the Sharp LCD. The numbers are basically:

You may be tempted to try to hack a dtoverlay that uses the ads7846 driver and specifies the x-min, x-max, etc. parameters. Don"t. I wasted a huge amount of time on this. While you can specify min/max, they apparently do NOT affect the output of that driver. The raw numbers are still reported when watching X11 input events via sudo DISPLAY=:0.0 evtest /dev/input/event0 no matter what the min/max parameters to that driver are.

My question to the group, if anyone knows, is simple: is it possible to configure a Pi4 so an SPI connected LCD can co-exist without disabling the RandR extension in X11?

My question to the group, if anyone knows, is simple: is it possible to configure a Pi4 so an SPI connected LCD can co-exist without disabling the RandR extension in X11?

With DRM/KMS X will render one "super desktop" covering all displays in their correct positions, and then tell each DRM/KMS device to display the correct bit of it. That"s how it works with dual HDMI on Pi4.

Now these SPI displays used to be driven by a driver that only exposed them as /dev/fbX nodes. They now appear to be under the tinydrm driver, so I would have expected them to show up as DRM/KMS devices. The output from modetest would be interesting to see (X can not be running when you run modetest). "xrandr --verbose" may tell you if you have vc4-(f)kms-v3d enabled. (Sorry, I don"t have one of these displays to test with)

I"m not real familiar with this stuff (I stumbled across it while I was stuck in the mud), but I assume by these results that there are two different drivers possible: fb_ili9341 which is the framebuffer version, and ili9341 which I assume is the DRM version. If I understand how this all fits together, it appears that when I select the "rpi-display" overlay, its picking the framebuffer version due to the last line in modules.alias?

which is of course a different driver. I already had a customized overlay source, so I changed it to use the mentioned "mi0283qt" driver. It did not work (my screen remains blank white). I also tried the straight ili9341 driver (with no "fb_" prefix). Both showed results from modetest, but the screen remained white.

I suspect that perhaps my pins may not be set up correctly for those drivers? The overlay sources seemed to indicate they were the same, but I don"t know if that is true.

I"m not sure if I uncovered an inconsistency in what is supposed to be in the distribution, or if in order to get this to work, I need to download and compile the drivers? I"ll keep experimenting, but I wanted to report what I found thus far.

I do note that the mi0283qt driver also appears to be a 320x240 ILI934 based panel from looking at the source. That"s also the compatible ("multi-inno,mi0283qt") referenced by notro in https://github.com/notro/tinydrm/issues/14 (different vendor prefix though). It"d be nice to know the differences.

Is it fair to say that there is more to a board than just saying it"s controlled by a an ILS9341? That seems to be the case with these multiple initialization sequences. I believe my board to be one from HiLetgo. Is it possible to create a DRM driver that functions EXACTLY like the fb_ili9341? Another possibility: for $10 USD, I could just get another board. That certainly might be easier. I"d just like to know the best way to match a board to a driver. The "brand name" ADAfruit board is $27 - almost 3 x the cost of the Hiletgo. Not super significant for a one-off, but a significant increase in unit cost.

Switching to the "multi-inno,mi0283qt" compatible and I get nothing. Reading the DT bindings, the backlight has been moved from being a GPIO property of the display to being a link to the backlight device driver, so it"s understandable that the backlight stays off.

Next, I removed my previous 99-multihead-conf file from my "/usr/share/X11/xorg.conf.d/" and restarted the desktop manager. I opened a terminal window, entered "xrandr", and both displays listed! I thought it was solved, but at that point, my poor little Pi completely locked up. I had this same problem in the past when I was trying the various DRM driver overlays. The desktop just became very unstable.

I"ll keep the "the legacy driver is being deprecated" in the back of my head for future purposes. Maybe by the time that happens, if this configuration is still needed, someone will have taken the information in this thread and figured out the problem.

is needed for xrandr to see the display (listed as Unknown19-1 for me, presumably as X hasn"t been built with any knowledge of DRM_MODE_CONNECTOR_SPI being 19. https://elixir.bootlin.com/linux/latest ... ode.h#L390

However it is as I suspected - we have no mouse pointer on the TFT screen, presumably as X can"t cope with one display having a cursor plane and the other not. I don"t know the best way to overcome that.

*edit*: Minor correction there. If the two displays overlap, then the mouse cursor disappears on the SPI screen. If you set them to be independent (eg "xrandr --output Unknown19-1 --right-of HDMI-1"), then X switches mode and renders the mouse cursor.

Which sounds like yours (i.e the "Unknown19-1). I got the "lock up" again, but it turns out that lock-up was actually VNC (I"ve been using that to develop, as the text on a Sharp LCD is VERY tiny to look at in desktop mode). My console was still alive, so I hooked up an actual keyboard and mouse to the Pi, and the desktop on my Sharp LCD came alive. With the above two commands you"ve discovered, I now have two desktops. Sort of...

It appears as if the upper left hand corner of my Sharp LCD desktop is mirrored on the small LCD. It"s not two independent desktops. Instead, it"s the same desktop duplicated. I suspect that is probably more X configuration than driver stuff, however.

It appears as if the upper left hand corner of my Sharp LCD desktop is mirrored on the small LCD. It"s not two independent desktops. Instead, it"s the same desktop duplicated. I suspect that is probably more X configuration than driver stuff, however.

linux tft lcd driver hdmi brands

Thanks for bringing this to my attention. It appears that the upgrade package overwrites the FBTFT drivers, in particular, the Raspberry Pi bootloader. This seems to solve the problem:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait fbtft_device.custom fbtft_device.name=waveshare32b fbtft_device.gpios=dc:22,reset:27 fbtft_device.bgr=1 fbtft_device.speed=48000000 fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo dma.dmachans=0x7f35 console=tty1 consoleblank=0 fbtft_device.fps=50 fbtft_device.rotate=0

Unfortunately, their “driver” is an SD card image containing a complete installation of Raspbian which has been preconfigured to use their display. Which is fine if you’re setting up a brand new system that doesn’t need to be a specific distro, but if you’re trying to add the display to an existing Raspberry Pi, already configured the way you want it, with software installed and data present, or if you want to use a specific distro such as Octopi, then it’s not terribly helpful.

Hello..I tired to interface this lcd “https://www.crazypi.com/raspberry-pi-products/Raspberry-Pi-Accessories/32-TOUCH-DISPLAY-RASPBERRY-PI” to my Raspberry pi model B+.I got a DVD containing image for LCD in the package.I burned it to the SD card and plugged in the display.But my lcd is completly blank.But green inidcation led (ACT LED) in board is blinking.Why my LCD is Blank ?

Yes, it may be that the screen isn’t supported. Newer screens might not have drivers yet. I do know it is possible to make your own driver but that’s above my level of knowledge :)

My Touchscreen is now working fine.The problem was for the ribbon cable on the back side of LCD.It was not connected properly.I just tighted the cable and it worked fine.Hope it will be useful tip.

Just got my Pi2 running Wheezy, working with the Eleduino 3.5 LCD without running the OEMs image… kinda. I didn’t want to rebuild the application environment again, so was avoiding flashing the SD.

[ 0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2709.boardrev=0xa21041 bcm2709.serial=0x631a4eae smsc95xx.macaddr=B8:27:EB:1A:4E:AE bcm2708_fb.fbswap=1 bcm2709.disk_led_gpio=47 bcm2709.disk_led_active_low=0 sdhci-bcm2708.emmc_clock_freq=250000000 vc_mem.mem_base=0x3dc00000 vc_mem.mem_size=0x3f000000 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait fbtft_device.custom fbtft_device.name=flexfb fbtft_device.gpios=dc:22,reset:27 fbtft_device.bgr=1 fbtft_device.speed=48000000 fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo dma.dmachans=0x7f35 console=tty1 consoleblank=0 fbtft_device.fps=50 fbtft_device.rotate=0

thank you for your great tutorial, it got me on the right way. unfortunataly i only see some boot messages on the lcd and then it turns black. maybe you could give me a hint on how to get it working entirely.

Did you check to see if your device is supported yet? The device name should be specific for your screen, as listed in the fbtft file linked to in the beginning of the post

I too have a raspberry pi 2, and a waveshare spotpear 3.2 RPi lcd (v3) and I just can’t get it to work! I suspect I have a faulty LCD, but thought I’ll try this forum for help before I sent it back.

Soon as the pi is powered, the LCD lights up all white, with a few vertical pixels coloured at one of the edges, and nothing else. I don’t think that should happen – not at least before the BOIS has started up.

[ 0.000000] Linux version 3.18.5-v7+ (pi@raspi2) (gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.01 – Linaro GCC 2013.11) ) #1 SMP PREEMPT Fri Feb 6 23:06:57 CET 2015

It seems all appears to be working – just the LCD is still all white with a single line of coloured pixels on edge) and nothing else. Is there a way to output, like jeff G script, of touch points?

I had the same one, I finally found a driver for it here: http://www.waveshare.net/wiki/3.2inch_RPi_LCD_(B) you will need to translate the page, but unpack the driver then run sudo ./LCD-show/LCD32-show. It should reboot and all will be good with the screen :)

My system: Raspberry Pi 2 Model B with Raspian Wheezy from Febuary 2015. LCD display of Sainsmart 3.2 http://www.conrad.de/ce/de/product/1283498/Raspberry-Pi-Display-Modul-Touch-Display-81-cm-32/?ref=home&rt=home&rb=1

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 cgroup_enable=memory elevator=deadline rootwait fbtft_device.custom fbtft_device.name=sainsmart32_spi fbtft_device.gpios=dc:24,reset:25 fbtft_device.bgr=1 fbtft_device.speed=48000000 fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo dma.dmachans=0x7f35 console=tty1 consoleblank=0 fbtft_device.fps=50 fbtft_device.rotate=90

The LCD display shows the raspberry correctly. However, the touch screen input does not work. The mouse pointer can I move correctly with your finger, but I can not select things (function of the left mouse button).

Can someone upload SD card image that works with RBP2 ? My idea is to use Eleduino TFT as additional screen and play movies via HDMI.. is it possible?

Do not follow this article when you don’t know what kind of LCD module. In my case, I follow all of this and my raspberry pi cannot boot anymore. I will try to recover, but I think I should format my SD card and reinstall OS.

Expecting this would builtin driver module within kernel and help with avoiding mistakenly overwriting anything. But with this is cause LCD screen to go blank white and no boot activity. Also noticed on HDMI it get stuck on Initial rainbow screen and stuck on that.

Does anyone tried splash boot screen with waveshare v4 LCD and Rpi2? I tried to follow some example from https://github.com/notro/fbtft/wiki/Bootsplash but no success.

Great tutorial thanks; got an X session working great 1st time. Has anybody managed to get Kodi/XMBC working on the LCD either Kodi standalone, Raspbmc or Xbian?

fbtft_device name=waveshare32b gpios=dc:22,reset:27 speed=48000000 width=320 height=240 buswidth=8 init=-1,0xCB,0x39,0x2C,0x00,0x34,0x02,-1,0xCF,0x00,0XC1,0X30,-1,0xE8,0x85,0x00,0x78,-1,0xEA,0x00,0x00,-1,0xED,0x64,0x03,0X12,0X81,-1,0xF7,0x20,-1,0xC0,0x23,-1,0xC1,0x10,-1,0xC5,0x3e,0x28,-1,0xC7,0x86,-1,0×36,0x28,-1,0x3A,0x55,-1,0xB1,0x00,0x18,-1,0xB6,0x08,0x82,0x27,-1,0xF2,0x00,-1,0×26,0x01,-1,0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,0x0E,0x09,0x00,-1,0XE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,0x08,0x0F,0x0C,0x31,0x36,0x0F,-1,0×11,-2,120,-1,0×29,-1,0x2c,-3

After following this tut to the letter on a brand new image of Raspian, I find that the touch driver does not function. Anyone experience the same? Basically all I did was image a current copy of rasping, did a apt-get upgrade, and then did this tutorial. Then the touch driver does not work, meaning the pointer does not respond.

The reason I did this was because on a production version of my system I added the 3.2 screen and it worked great except for the x-axis. So I wanted to see if there was something in my system that was interfering or if this is another error. Now with a raw rasping the driver does not work at all. I wonder if the touch pin has changed since the kernel is using BCM pins instead of GPIO pin numbers?

I have exactly the same problem. I also installed a new version of Raspbian, and the LCD part works fine (except all the windows are way too large), but the touch part doesn’t work at all… I’m using Waveshare Spotpear 3.2″ V4.

I do not think that has anything to do with it. Other than power pins, the rest are communication. If it still works then you are good. No, there is something else. I do suspect it us related to the BCM pin numbering. The real question is… Why isnt the eeveloper responding? I have since abandoned this TFT because of his lack of response.

Touch actually goes through one of the SPI pins I think. Either the driver is toast with the required kernel update or the driver is using the wrong pin. It is very likely the this works well with previous raspian versions, but not with the new B+ and with the new kernel.

I am trying to use the sainsmart 2.8″ lcd sold through microcenter, using the sainsmart32_spi … seems to have the same pinouts, should I be able to get this to work? I am stuck at the white out screen on the lcd, doesn’t seem to recognize the module either.

The SainSmart 3.2 sold by MicroCenter (20-111-971) is actually the exact same WaveShare SpotPear v3 documented here. So maybe your 2.8 would work if you tried a WaveShare driver?

Unfortunately I’ve tried that ( a few times actually) but the file still doesn’t exist. Thanks very much for the assistance anyway. I must be doing something wrong. My Raspian came from a Noobs installation, I’m wondering if I should try installing the OS from somewhere else. My LCD screen didn’t come with a CD or any docs so I’m completely in the dark here.

I have just found a way to get this file on my system! Apparently its part of the fbturbo installation. I found it here http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=45746&start=75 (under experimental enhanced x driver (rpifb).. Sorry if this is obvious to everyone but I am SUCH a noob at this!!

Well figured out that step 1 was causing my problems. I’m guessing it is shutting off my hdmi feed and trying to switch it over to the SPI, am I guessing right? If so, not sure how I’m suppose to complete the rest of the steps if my hdmi output gets turned off before the LCD is actually set up to work…that sounds kind of smartass-like, which is not my intention, just looking for some clarification on what is going on in that first step as I am fairly new to this stuff. Thanks.

Anyway, I was able to do the rest of the steps with no problem. LCD didn’t work, but I am using a Waveshare 3.5, which doesn’t look to be supported yet. Mostly I am trying to play around and see if I can get it working somehow. Anyone found a way to do this yet?

I am having an issue with getting the GUI back. Every time I use startx my pi just sits there for about two minutes saying “No protocol specified”, and then it just gives up. I went through this tutorial about four times now and am not certain why it is doing this. I have the exact same LCD as is in the tutotial (WaveShare 3.2b). any help would be great.

Thanks for the tutorial. It works, but I get the boot/command line stuff on the HDMI monitor and the LCD only comes on when I do startx. Is there a way to get everything to appear on the LCD screen?

Now the OS freezes at the emulation station loading screen, and if I connect my lcd it gives me a lot of error messages which I can only see on the 3.2 inch screen.

This was an excellent tutorial. I have gotten an output to the screen, but no touchscreen usage . I have the Waveshare SpotPear 3.2 Inch LCD V4 screen, but using Raspberry PI 2 with wheezy. Any ideas?

I filed the steps to calibrate the screen but it did not work.I think because it did not find the TFT pin, because I think the touch problem is the assigned pin to control it changed.

I actually used the driver from here http://www.waveshare.com/wiki/3.2inch_RPi_LCD_(B) , from a new wheezy build, did nothing except enable SPI in config, install driver, and change mmcblk0p2 to mmcblk0p6 in cmdline.txt and it all worked, no drama.

Advice to all who have the drivers from the (touch)screen manufacturer and cannot obtain those otherwise: you can skip everything and go to the update steps skipping the kernel and kernel modules update (as mentioned by the author) so that you don’t override the preinstalled drivers. I have a Waveshare 3.5″ RPi v3 (not the 3.2″ supported by notro’s drivers) and actually managed without any problems to get notro’s drivers make it work. However I am still reading about the xinput and xinput-calibrator to figure out how to include it as a kernel module so that I can compile my own kernel and add it there.

i have raspberry pi 2 with 3.2 inch rpi lcd v4 waveshare spotpear.i have done as per your instructions.the display is working but touch screen not working.error shows waveshare32b module not found as well as touch screen module not found messages.

Unfortunately I have lost the Touch facility on my Waveshare 3.5″ LCD Touchscreen? Can you offer any reasons as to why? I copied the Raspbian image to my Raspberry Pi from the Waveshare website first of all. The Touchscreen displays but is not reactive with any touch

I have purchased a raspberry pi B+ total kit and waveshare 3.2 TFT display online. In the package i have been given a pre-loaded NOOBS installed SD card. I did not even start anything yet. What should i do what r the things needed and how to connect the display i really want to know. I need help as i don’t know anything. Does the above solution help or will u suggest something………………..

Hi great article thanks. I am trying to get a waveshare 7 inch LCD with capacitive touch running it works with the suppled image but if you upgrade it breaks the capacitive touch. I have a sense-hat and GPS which require the latest kernel and RASPIAN image and the install program for the screen replaces the /lib/modules directory and the kernel with older ones. I need to be able to install the touch drivers into a new clean OS can anyone give me some pointers? Thanks

I should add that the screen is plugged into the HDMI port and always works. The capacitive touch is driven from the USB port which also supplies power.

For anyone who have those unbranded cheap TFT touch modules and cannot get it to work with this guide, I had success on my 3.5″ with the following steps: http://pastebin.com/89qmFbPB

I have the WaveShare 3.5 (A) and cannot get it to work with the Kali Linux with TFT for Raspberry Pi. Have anybody gotten the A to work? (Not the B, theres instructions for the B already and dont work with A)

So I have the original image that came with my screen and it works fine with the LCD but my problem is that I want to use my LCD screen with other distros (at this time I am trying to use it with Kali Linux with TFT support by default https://www.offensive-security.com/kali-linux-vmware-arm-image-download/) What do I have to do to transfer the needed files from the original image that WORKS with the screen and use them with another image?

I originally bought this bundle http://www.amazon.com/gp/product/B013E0IJUK?psc=1&redirect=true&ref_=oh_aui_detailpage_o02_s00 with an RPi LCD V3 and no extra documentation on the specifics on the chipset. I tried with the bftft drivers but since I have no idea what to call this screen I just suppose it isn’t supported.

I’m not sure if the Jessie kernel is compatible – can anyone please confirm or not ?? Adafruit states that their setup for TFT screens are Wheezy only ; is this a different setup ??

I am using the same LCD and followed your tutorial. Have your tested the guide lately? Are you certain that it works? I see the boot messages on console but I get white screen as GUI starts.

I have tried to set up waveshare 32b on my Pi B using the latest Raspian download. I learned a lot in the process using Windows Putty, Nano etc. I have repeated the setup process several times from scratch and included the corrections for possible overwriting. My Waveshare SpotPear 3.2 inch RPi LCD V4 just shows a white screen. Any suggestions?

There was no disk included. I asked for drivers and was given a download link to the image file. After down loading this I tried it and still got just a white screen. The HDMI monitor locks partway though the boot. I can still log in to pi using putty from my PC.

Hi, I am using raspberry pi 2 with raspbian jessie installed. I the waveshare spotpear 3.2 v4. The above instructions are not working. and after completing the steps there was no display from hdmi or lcd. One things to notify is.: the etc/modules files only had i2c-dev and not snd-bcm2835.

I am trying to get this to work with Retro Pie 3.3.1 and the Waveshare3.2″ v4 but I only get the terminal on the lcd and emulation station starts on hdmi. to get it working with retro pie i just replaced startx with emulationstation. how do i get this to work?

Sir, Your post has very useful to me. i am using Tinylcd. but i cant get display. i am performing all the steps in your post. i cant get touch controller information from the product website and also i am using RASPberryPi B+ model. could u please give me best solution to my work. Than you.

what if OS is not Raspbian, any other distro like Yocto project, etc.? Could you please specify process without “rpi-update” that makes driver installation process more generic, not dedicated to Raspbian.

i installed android OS in raspberry pi 2. can i use same LCD touch screen set up for android installed raspberry pi 2 which you are used for raspbian.

Is it normal the white back light during the whole process of initializing (I suspect that during the transportation trere is a deffect)? The problem is that I missed the step #1 and I performed it at the end. Unfortunately I don’t have any monitor available right now – neither “normal”, neither LCD :))))). Is it possible turning back the system or the only option is reinstallation of the Raspbian?

I have KeDei 3.5 inch TFT version 4.0 by Osoyoo. (released after January 1 2016) how do i get it working with vanilla Raspbian Jessie (do not want to install the image sent by the seller)

I’m trying to use an original Raspberry Pi model B with a cheap 3.5 inch 320×480 LCD which allegedly was manufactured to work with the Pi and has the correct fittings to fit over the GPIO pins. The operating system is the latest, downloaded yesterday and installed with NOOBS. I can’t get past step 2 of this guidance. When I reboot after using raspi-config I can see text generated as the Pi boots, then the HDMI fed screen goes blank apart from a flashing cursor in the top left hand corner. The LCD just remains white with nothing else on it. I have missed out step 1 and rebooted after step 2 and the screen functions as I would expect. Does anyone have any ideas please?

Thanks for the great tutorial. I do have a question. Once you install the drivers for the lcd are you effectively disabiling the hdmi port or is it still available to use and will the pi function with both displays. I have a pi 3

once you install the drivers it replaces the kernel by disabling hdmi output and enables it for LCD. i don’t think we have a solution to get em both working at the same time. ( you are encouraged to search for it )

I’d like to find the driver software for my 7″ LCD with touch (official Pi unit) so that I can use it in buildroot. I wanted to make sure this kernel is the one before I started digging further.

I started through your tutorial and completed step 3 and rebooted. After the Raspberry screen and some of the boot text on my HDMI monitor, I now have a black HDMI monitor and a white screen on my LCD. Does this mean that the bootloader was overwritten or something else is wrong? How am I supposed to enter in the proposed fixes to the bootloader, when I can’t get the RPi to boot? Do I have to interrupt the boot process at some point to reinstall the bootloader or what?

Its a script. Download and instead of running sudo ./LCD4-show run cat ./LCD4-show to simply display what it does without actually running it. The commands are fairly simple modifying a few files. I actually saved the LCD-show.tar.gz on my own server for faster future download but also for backup as it saved me tons of hours (if that’s a measuring unit for time :) )

I used this link though (smaller file ~ 50 KB, fast download) http://www.waveshare.com/w/upload/4/4b/LCD-show-161112.tar.gz and replaced LCD4-show with LCD32-show in the last line.

i bought a 3.5 inch tft lcd screen from banggood. and i have installed raspian jessie, the latest version, in my sd card. but when i power on my Pi, only a white backlit screen comes. there are no images or graphics whatsoever.

Of course. Raspbian Jessie does not come with the drivers needed to talk to the screen. See my previous comment (September 22, 2016 at 11:54 am) and follow it.

The owner of this article should including a WARNING in the header that if someone follows the steps, they will install a deprecated driver (which is only visible as tiny text on its gethub page here https://github.com/notro/rpi-firmware). This driver after install will break Raspberry Pi and the SD card will need to be reimaged, for some less experienced users, this could also mean lost work if they failed to backup their code or resources. On windows, it requires installing Linux reader software and it takes a long time to fix this f**kup which could easily have been avoided if the author had and sense of responsibility.

Will your system work with my SainSmart 2.8″ 2.8 inch TFT LCD 240×320 Arduino DUE MEGA2560 R3 Raspberry Pi ? I would like to know before not be able to back out. Thanks, Lee

hello. I really appreciate your blog post. I have a raspberry pi 3 B. I have been unable to get my waveshare 3.2 screen to work.I am at a complete loss for what to do. I do step 2 I change fb0 to fb1 and then follow your directions I don’t get the prompt to reboot; however, I do it manually with sudo reboot. that works fine then I complete step three and that works just fine; however once I reboot from getting those drivers and when I attempt to reboot it is unsuccessful and then my whole raspberry pi will not restart. then when I power it back on it will just shut back off. I then have to redo noobs onto a new SD card I would GREATLY appreciate anyones help

I ‘m actually using a LCD Waveshare3.2” , I followed your steps to setup the lcd touchscreen for my rpi and it work but I have a problem with the resolution because if I open a repertory I do not see the whole contents on the screen .

I did a 5inch LCD for my raspberry pi. I dont use the touchscreen so i didnt have to install any drivers. It works out of the box but doesnt cover the whole screen unless you open the terminal and do:

In the case of the WaveShare driver, their setup script from their “LCD_show” repository will copy a device-tree overlay to /boot/overlays/ that provides most of the module config etc via boot-time device-tree patch.

After I did the step that “INSTALL THE FBTFT DRIVERS” and then reboot, my raspberry pi couldn’t boot successfully and the green light is always on, could you help me solve this problem? Thank you.

linux tft lcd driver hdmi brands

After execution, the driver will be installed. The system will automatically restart, and the display screen will rotate 90 degrees to display and touch normally.

( " XXX-show " can be changed to the corresponding driver, and " 90 " can be changed to 0, 90, 180 and 270, respectively representing rotation angles of 0 degrees, 90 degrees, 180 degrees, 270 degrees)

linux tft lcd driver hdmi brands

7inch HDMI LCD(C) supports various systems like Raspberry Pi, Banana Pi, Banana Pro, and BB Black to provide Lubuntu, Raspbian, and Angstrom images with a high resolution of 1024×600 and a Capacitive Touch Screen. Besides, it upgrades to an IPS screen with a larger visible angle and more clear display effect. Broadly you can apply it to raspberry pi, HDMI display screen, and other mini PC or even computer displays. If you gonna use it on raspberry pi zero and BB Black, you need to buy HDMI connect wire for the use and for raspberry pi zero you also need to buy A USB type A micro cable. Matched with raspberry pi, it supports raspbian, ubuntu to do single touch without touch, and while as A PC display, it supports Windows 10 / 8.1 / 8 / 7 to do the five-point touch without drive. For the Windows 10/8.1/8 OS, the touch screen supports multi-touch up to 10 points. For some Windows 7 OS, the touch screen supports single touch only. When working with Raspberry Pi, you should set the resolution of the LCD by yourself, or else the LCD screen will not work. When working with Beagle bone, this LCD module is used for display only so you can program the latest Angstrom image file to the board directly without any change. The BeagleBone will read the display parameters of the 7-inch HDMI displayer and set the resolution to 800*480 automatically.

linux tft lcd driver hdmi brands

Rocktech Displays Limited was established in 2002 and had been committed to LCD technology with consistent concentration since then. We have two LCD factories in Shenzhen mainly focusing on TFT-LCD design, manufacture and customized total solution. We offer qualified and competitive TFT-LCD modules from 1.44" to 19", services such as the customization of FPC interface/structure, backlight structure/brightness and open frame/monitor structure, the assembly of assorted size CTP/RTP, and the design/manufacture of A/D board/Android system solution board, TN/STN/FSTN mono LCD and COG/TAB/COB mono LCM.During the past more than 14 years, Our products are very popular in dozens of countries including China, United States, Germany, France, Italy, Japan, South Korea etc., with our own brand name “Rocktech”. Via policy of “qualify first, professional technical solution, competitive price, flexibility, honest service”, Rocktech has gained a very good reputation and set up a stable industr...

linux tft lcd driver hdmi brands

This IPS TFT LCD module has built-in HDMI compatibility for a streamlined connection between devices with fewer cables. Assembled to the display is a custom PCB providing the user an all-in-one, plug-and-play HDMI + USB touch solution. It is attached to a steel mounting bracket for easy, secure installation. There is an on-board Texas Instruments TFP401A HDMI/DVI receiver and TPS61165 high brightness LED driver with PWM. Whether you need a display for your Raspberry Pi, BeagleBone, Windows, or a touchscreen HMI for your Linux or other embedded system, this display offers a solution. The 24-bit true color LCD has a high resolution 1024x600 screen with IPS technology, providing superior image quality, accurate color reproduction, and high contrast ratio at every angle. This Liquid Crystal Display is RoHS compliant and has a USB-HID capacitive touch panel with no external driver installation required.

Choose from a wide selection of interface options or talk to our experts to select the best one for your project. We can incorporate HDMI, USB, SPI, VGA and more into your display to achieve your design goals.

linux tft lcd driver hdmi brands

7 Inch Touch Screen + Acylic Stand Tft Lcd Display Hdmi 1024X600 Driver Free For Raspberry Pi,Computer,Tv Box,Dvr,Game Device (7"" Touch Screen And Stand)

Product InformationPlug And Play No Driver Needed.You Don"T Need To Install Any Driver And Just Connect The Hdmi Port And Micro Usb Port From Display To Your Device.Backlight Can Be Turned Off To Lower Power Consumption.

Strong System Compatiblesupport Windows Operating Systems,Mas Os And Other Systems.When Works With Raspberry Pi, Supports Raspbian/Ubuntu Mate/Lubuntu/Snappy Ubuntu Core/Kali/Osmc/Retropie/Win10 Iot, Driver Free; When Work As A Computer Monitor, Supports Windows Xp/10/8/7 And Mas Os.

Five-Points Touchcapacitive Touch Control And Five-Points Touch.It Has Vertical And Horizontal Image Flip Function.Equipping With Hdmi & Earphone Jack & 2X Micro Usb Port Support.Connect The Screen To Other Device Via Hdmi Interface And Power It Via Micro Usb.

7 Inch Touch Display Screen Support System: Win7, Win8, Win10,Win Xp, Linux System, Mas Os, Raspbian, Ubuntu Mate, Lubuntu, Snappy Ubuntu Core, Osmc, Windows 10 Iot Core,Camera,Dvr,Tv Box Parameters Power: 5V Via Usb Micro Current: Max 500Ma Physical Resolution: 1024*600 Size: 16.5 X 12.2 Cm Display Size: 7 Inch Tft Lcd (15.3*8.5 Cm) Touch Type: Usb Capacitive Touch Plug And Play; No Driver Needed. Wide Compatibility Compatible With Computer, Such Desk Computer,Notebook, Laptop. Compatible With Multiple Game Device,Such As Ps4,Xbox,Switch. Compatible With Monitoring System,Such As Cctv System, Network Monitoring System. Compatible With Network Player Boxes,Such As Apple Tv Box, Android Tv Box. Package Included: You Will Receive 1X Display 1X Hdmi Cable 1X Micro Usb Power Cable 1X Manual 1X Acylic Stand

linux tft lcd driver hdmi brands

After I published my $1 MCU write-up, several readers suggested I look at application processors — the MMU-endowed chips necessary to run real operating systems like Linux. Massive shifts over the last few years have seen internet-connected devices become more featureful (and hopefully, more secure), and I’m finding myself putting Linux into more and more places.

This article is targeted at embedded engineers who are familiar with microcontrollers but not with microprocessors or Linux, so I wanted to put together something with a quick primer on why you’d want to run embedded Linux, a broad overview of what’s involved in designing around application processors, and then a dive into some specific parts you should check out — and others you should avoid — for entry-level embedded Linux systems.

If my mantra for the microcontroller article was that you should pick the right part for the job and not be afraid to learn new software ecosystems, my argument for this post is even simpler: once you’re booted into Linux on basically any of these parts, they become identical development environments.

That makes chips running embedded Linux almost a commodity product: as long as your processor checks off the right boxes, your application code won’t know if it’s running on an ST or a Microchip part — even if one of those is a brand-new dual-core Cortex-A7 and the other is an old ARM9. Your I2C drivers, your GPIO calls — even your V4L-based image processing code — will all work seamlessly.

As a result, the boards I built for this review are akin to the notes from your high school history class or a recording you made of yourself practicing a piece of music to study later. So while I’ll post pictures of the boards and screenshots of layouts to illustrate specific points, these aren’t intended to serve as reference designs or anything; the whole point of the review is to get you to a spot where you’ll want to go off and design your own little Linux boards. Teach a person to fish, you know?

Coming from microcontrollers, the first thing you’ll notice is that Linux doesn’t usually run on Cortex-M, 8051, AVR, or other popular microcontroller architectures. Instead, we use application processors — popular ones are the Arm Cortex-A, ARM926EJ-S, and several MIPS iterations.

The biggest difference between these application processors and a microcontroller is quite simple: microprocessors have a memory management unit (MMU), and microcontrollers don’t. Yes, you can run Linux without an MMU, but you usually shouldn’t: Cortex-M7 parts that can barely hit 500 MHz routinely go for double or quadruple the price of faster Cortex-A7s. They’re power-hungry: microcontrollers are built on larger processes than application processors to reduce their leakage current. And without an MMU and generally-low clock speeds, they’re downright slow.

When your microcontroller project outgrows its super loop and the random ISRs you’ve sprinkled throughout your code with care, there are many bare-metal tasking kernels to turn to — FreeRTOS, ThreadX (now Azure RTOS), RT-Thread, μC/OS, etc. By an academic definition, these are operating systems. However, compared to Linux, it’s more useful to think of these as a framework you use to write your bare-metal application inside. They provide the core components of an operating system: threads (and obviously a scheduler), semaphores, message-passing, and events. Some of these also have networking, filesystems, and other libraries.

Comparing bare-metal RTOSs to Linux simply comes down to the fundamental difference betweenthese and Linux: memory management and protection. This one technical difference makes Linux running on an application processor behave quite differently from your microcontroller running an RTOS.((Before the RTOS snobs attack with pitchforks, yes, there are large-scale, well-tested RTOSes that are usually run on application processors with memory management units. Look at RTEMS as an example. They don’t have some of the limitations discussed below, and have many advantages over Linux for safety-critical real-time applications.))

Because Linux-capable application processors have a memory management unit, *alloc() calls execute swiftly and reliably. Physical memory is only reserved (faulted in) when you actually access a memory location. Memory fragmentation is much less an issue since Linux frees and reorganizes pages behind the scenes. Plus, switching to Linux provides easier-to-use diagnostic tools (like valgrind) to catch bugs in your application code in the first place. And finally, because applications run in virtual memory, if your app does have memory bugs in it, Linux will kill it — leaving the rest of your system running. ((As a last-ditch kludge, it’s not uncommon to call your app in a superloop shell script to automatically restart it if it crashes without having to restart the entire system.))

Running something like lwIP under FreeRTOS on a bare-metal microcontroller is acceptable for a lot of simple applications, but application-level network services like HTTP can burden you to implement in a reliable fashion. Stuff that seems simple to a desktop programmer — like a WebSockets server that can accept multiple simultaneous connections — can be tricky to implement in bare-metal network stacks. Because C doesn’t have good programming constructs for asynchronous calls or exceptions, code tends to contain either a lot of weird state machines or tons of nested branches. It’s horrible to debug problems that occur. In Linux, you get a first-class network stack, plus tons of rock-solid userspace libraries that sit on top of that stack and provide application-level network connectivity. Plus, you can use a variety of high-level programming languages that are easier to handle the asynchronous nature of networking.

Somewhat related is the rest of the standards-based communication / interface frameworks built into the kernel. I2S, parallel camera interfaces, RGB LCDs, SDIO, and basically all those other scary high-bandwidth interfaces seem to come together much faster when you’re in Linux. But the big one is USB host capabilities. On Linux, USB devices just work. If your touchscreen drivers are glitching out and you have a client demo to show off in a half-hour, just plug in a USB mouse until you can fix it (I’ve been there before). Product requirements change and now you need audio? Grab a $20 USB dongle until you can respin the board with a proper audio codec. On many boards without Ethernet, I just use a USB-to-Ethernet adapter to allow remote file transfer and GDB debugging. Don’t forget that, at the end of the day, an embedded Linux system is shockingly similar to your computer.

Secure boot isn’t available on every application processor reviewed here, it’s much more common. While there are still vulnerabilities that get disclosed from time to time, my non-expert opinion is that the implementations seem much more robust than on Cortex-M parts: boot configuration data and keys are stored in one-time-programmable memory that is not accessible from non-privileged code. Network security is also more mature and easier to implement using Linux network stack and cryptography support, and OP-TEE provides a ready-to-roll secure environment for many parts reviewed here.

Imagine that you needed to persist some configuration data across reboot cycles. Sure, you can use structs and low-level flash programming code, but if this data needs to be appended to or changed in an arbitrary fashion, your code would start to get ridiculous. That’s why filesystems (and databases) exist. Yes, there are embedded libraries for filesystems, but these are way clunkier and more fragile than the capabilities you can get in Linux with nothing other than ticking a box in menuconfig. And databases? I’m not sure I’ve ever seen an honest attempt to run one on a microcontroller, while there’s a limitless number available on Linux.

In a bare-metal environment, you are limited to a single application image. As you build out the application, you’ll notice things get kind of clunky if your system has to do a few totally different things simultaneously. If you’re developing for Linux, you can break this functionality into separate processes, where you can develop, debug, and deploy separately as separate binary images.

Bare-metal MCU development is primarily done in C and C++. Yes, there are interesting projects to run Python, Javascript, C#/.NET, and other languages on bare metal, but they’re usually focused on implementing the core language only; they don’t provide a runtime that is the same as a PC. And even their language implementation is often incompatible. That means your code (and the libraries you use) have to be written specifically for these micro-implementations. As a result, just because you can run MicroPython on an ESP32 doesn’t mean you can drop Flask on it and build up a web application server. By switching to embedded Linux, you can use the same programming languages and software libraries you’d use on your PC.

In Linux, there is a hard separation between userspace calls and the underlying hardware driver code. One key advantage of this is how easy it is to move from one hardware platform to another; it’s not uncommon to only have to change a couple of lines of code to specify the new device names when porting your code.

Yes, you can poke GPIO pins, perform I2C transactions, and fire off SPI messages from userspace in Linux, and there are some good reasons to use these tools during diagnosing and debugging. Plus, if you’re implementing a custom I2C peripheral device on a microcontroller, and there’s very little configuration to be done, it may seem silly to write a kernel driver whose only job is to expose a character device that basically passes on whatever data directly to the I2C device you’ve built.

But if you’re interfacing with off-the-shelf displays, accelerometers, IMUs, light sensors, pressure sensors, temperature sensors, ADCs, DACs, and basically anything else you’d toss on an I2C or SPI bus, Linux already has built-in support for this hardware that you can flip on when building your kernel and configure in your DTS file.

Sleep-mode power consumption. First, the good news: active mode power consumption of application processors is quite good when compared to microcontrollers. These parts tend to be built on smaller process nodes, so you get more megahertz for your ampere than the larger processes used for Cortex-M devices. Unfortunately, embedded Linux devices have a battery life that’s measured in hours or days, not months or years.

Boot time. Embedded Linux systems can take several seconds to boot up, which is orders of magnitude longer than a microcontroller’s start-up time. Alright, to be fair, this is a bit of an apples-to-oranges comparison: if you were to start initializing tons of external peripherals, mount a filesystem, and initialize a large application in an RTOS on a microcontroller, it could take several seconds to boot up as well. While boot time is a culmination of tons of different components that can all be tweaked and tuned, the fundamental limit is caused by application processors’ inability to execute code from external flash memory; they must copy it into RAM first ((unless you’re running an XIP kernel)).

Responsiveness. By default, Linux’s scheduler and resource system are full of unbounded latencies that under weird and improbable scenarios may take a long time to resolve (or may actually never resolve). Have you ever seen your mouse lock up for 3 seconds randomly? There you go. If you’re building a ventilator with Linux, think carefully about that. To combat this, there’s been a PREEMPT_RT patch for some time that turns Linux into a real-time operating system with a scheduler that can basically preempt anything to make sure a hard-real-time task gets a chance to run.

Also, when many people think they need a hard-real-time kernel, they really just want their code to be low-jitter. Coming from Microcontrollerland, it feels like a 1000 MHz processor should be able to bit-bang something like a 50 kHz square wave consistently, but you would be wrong. The Linux scheduler is going to give you something on the order of ±10 µs of jitter for interrupts, not the ±10 ns jitter you’re used to on microcontrollers. This can be remedied too, though: while Linux gobbles up all the normal ARM interrupt vectors, it doesn’t touch FIQ, so you can write custom FIQ handlers that execute completely outside of kernel space.

Figuring out system requirements for your software frameworks can be rather unintuitive. For example, doing a multi-touch-capable finger-painting app in Qt 5 is actually much less of a resource hog than running a simple backend server for a web app written in a modern stack using a JIT-compiled language. Many developers familiar with traditional Linux server/desktop development assume they’ll just throw a .NET Core web app on their rootfs and call it a day — only to discover that they’ve completely run out of RAM, or their app takes more than five minutes to launch, or they discover that Node.js can’t even be compiled for the ARM9 processor they’ve been designing around.

Slower ARM9 cores are for simple headless gadgets written in C/C++.Yes, you can run basic, animation-free low-resolution touch linuxfb apps with these, but blending and other advanced 2D graphics technology can really bog things down. And yes, you can run very simple Python scripts, but in my testing, even a “Hello, World!” Flask app took 38 seconds from launch to actually spitting out a web page to my browser on a 300 MHz ARM9. Yes, obviously once the Python file was compiled, it was much faster, but you should primarily be serving up static content using lightweight HTTP servers whenever possible. And, no, you can’t even compile Node.JS or .NET Core for these architectures. These also tend to boot from small-capacity SPI flash chips, which limits your framework choices.

I know that there are lots of people — especially hobbyists but even professional engineers — who have gotten to this point in the article and are thinking, “I do all my embedded Linux development with Raspberry Pi boards — why do I need to read this?” Yes, Raspberry Pi single-board computers, on the surface, look similar to some of these parts: they run Linux, you can attach displays to them, do networking, and they have USB, GPIO, I2C, and SPI signals available.

And for what it’s worth, the BCM2711 mounted on the Pi 4 is a beast of a processor and would easily best any part in this review on that measure. Dig a bit deeper, though: this processor has video decoding and graphics acceleration, but not even a single ADC input. It has built-in HDMI transmitters that can drive dual 4k displays, but just two PWM channels. This is a processor that was custom-made, from the ground up, to go into smart TVs and set-top boxes — it’s not a general-purpose embedded Linux application processor, so it isn’t generally suited for embedded Linux work.

It might be the perfect processor for your particular project, but it probably isn’t; forcing yourself to use a Pi early in the design process will over-constrain things. Yes, there are always workarounds to the aforementioned shortcomings — like I2C-interfaced PWM chips, SPI-interfaced ADCs, or LCD modules with HDMI receivers — but they involve external hardware that adds power, bulk, and cost. If you’re building a quantity-of-one project and you don’t care about these things, then maybe the Pi is the right choice for the job, but if you’re prototyping a real product that’s going to go into production someday, you’ll want to look at the entire landscape before deciding what’s best.

This article is all about getting an embedded application processor booting Linux — not building an entire embedded system. If you’re considering running Linux in an embedded design, you likely have some combination of Bluetooth, WiFi, Ethernet, TFT touch screen, audio, camera, or low-power RF transceiver work going on.

If you’re coming from the MCU world, you’ll have a lot of catching up to do in these areas, since the interfaces (and even architectural strategies) are quite different. For example, while single-chip WiFi/BT MCUs are common, very few application processors have integrated WiFi/BT, so you’ll typically use external SDIO- or USB-interfaced chipsets. Your SPI-interfaced ILI9341 TFTs will often be replaced with parallel RGB or MIPI models. And instead of burping out tones with your MCU’s 12-bit DAC, you’ll be wiring up I2S audio CODECs to your processor.

Processor vendors vigorously encourage reference design modification and reuse for customer designs. I think most professional engineers are most concerned with getting Rev A hardware that boots up than playing around with optimization, so many custom Linux boards I see are spitting images of off-the-shelf EVKs.

Most MPUs can boot from SPI NOR flash, SPI NAND flash, parallel, or MMC (for use with eMMC or MicroSD cards). Because of its organization, NOR flash memory has better read speeds but worse write speeds than NAND flash. SPI NOR flash memory is widely used for tiny systems with up to 16 MB of storage, but above that, SPI NAND and parallel-interfaced NOR and NAND flash become cheaper. Parallel-interfaced NOR flash used to be the ubiquitous boot media for embedded Linux devices, but I don’t see it deployed as much anymore — even though it can be found at sometimes half the price of SPI flash. My only explanation for its unpopularity is that no one likes wasting lots of I/O pins on parallel memory.

Unlike MCU-based designs, on an embedded Linux system, you absolutely, positively, must have a console UART available. Linux’s entire tracing architecture is built around logging messages to a console, as is the U-Boot bootloader.

That doesn’t mean you shouldn’t also have JTAG/SWD access, especially in the early stage of development when you’re bringing up your bootloader (otherwise you’ll be stuck with printf() calls). Having said that, if you actually have to break out your J-Link on your embedded Linux board, it probably means you’re having a really bad day. While you can attach a debugger to an MPU, getting everything set up correctly is extremely clunky when compared to debugging an MCU. Prepare to relocate symbol tables as your code transitions from SRAM to main DRAM memory. It’s not uncommon to have to muck around with other registers, too (like forcing your CPU out of Thumb mode). And on top of that, I’ve found that some U-Boot ports remux the JTAG pins (either due to alternate functionality or to save power), and the JTAG chains on some parts are quite complex and require using less-commonly used pins and features of the interface. Oh, and since you have an underlying Boot ROM that executes first, JTAG adapters can screw that up, too.

When most people think of DDR routing, length-tuning is the first thing that comes to mind. If you use a decent PCB design package, setting up length-tuning rules and laying down meandered routes is so trivial to do that most designers don’t think anything of it — they just go ahead and length-match everything that’s relatively high-speed — SDRAM, SDIO, parallel CSI / LCD, etc. Other than adding a bit of design time, there’s no reason not to maximize your timing margins, so this makes sense.

For the data groups, DDR3 uses on-die termination (ODT), configurable for 40, 60, or 120 ohm on memory chips (and usually the same or similar on the CPU) along with adjustable output impedance drivers. ODT is only enabled on the receiver’s end, so depending on whether you’re writing data or reading data, ODT will either be enabled on the memory chip, or on the CPU.

When building embedded Linux systems, we need to start by compiling all the off-the-shelf software we plan on running — the bootloader, kernel, and userspace libraries and applications. We’ll have to write and customize shell scripts and configuration files, and we’ll also often write applications from scratch. It’s really a totally different development process, so let’s talk about some prerequisites.

If you want to build a software image for a Linux system, you’ll need a Linux system. If you’re also the person designing the hardware, this is a bit of a catch-22 since most PCB designers work in Windows. While Windows Subsystem for Linux will run all the software you need to build an image for your board, WSL currently has no ability to pass through USB devices, so you won’t be able to use hardware debuggers (or even a USB microSD card reader) from within your Linux system. And since WSL2 is Hyper-V-based, once it’s enabled, you won’t be able to launch VMware, which uses its own hypervisor((Though a beta versions of VMWare will address this)).

Consequently, I recommend users skip over all the newfangled tech until it matures a bit more, and instead just spin up an old-school VMWare virtual machine and install Linux on it. In VMWare you can pass through your MicroSD card reader, debug probe, and even the device itself (which usually has a USB bootloader).

Building images is a computationally heavy and highly-parallel workload, so it benefits from large, high-wattage HEDT/server-grade multicore CPUs in your computer — make sure to pass as many cores through to your VM as possible. Compiling all the software for your target will also eat through storage quickly: I would allocate an absolute minimum of 200 GB if you anticipate juggling between a few large embedded Linux projects simultaneously.

While your specific project will likely call for much more software than this, these are the five components that go into every modern embedded Linux system((Yes, there are alternatives to these components, but the further you move away from the embedded Linux canon, the more you’ll find yourself on your own island, scratching your head trying to get things to work.)):

A cross toolchain, usually GCC + glibc, which contains your compiler, binutils, and C library. This doesn’t actually go into your embedded Linux system, but rather is used to build the other components.

As you’re reading through this, don’t get overwhelmed: if your hardware is reasonably close to an existing reference design or evaluation kit, someone has already gone to the trouble of creating default configurations for you for all of these components, and you can simply find and modify them. As an embedded Linux developer doing BSP work, you’ll spend way more time reading other people’s code and modifying it than you will be writing new software from scratch.

Just like with microcontroller development, when working on embedded Linux projects, you’ll write and compile the software on your computer, then remotely test it on your target. When programming microcontrollers, you’d probably just use your vendor’s IDE, which comes with a cross toolchain — a toolchain designed to build software for one CPU architecture on a system running a different architecture. As an example, when programming an ATTiny1616, you’d use a version of GCC built to run on your x64 computer but designed to emit AVR code. With embedded Linux development, you’ll need a cross toolchain here, too (unless you’re one of the rare types coding on an ARM-based laptop or building an x64-powered embedded system).

Unfortunately, our CPU’s boot ROM can’t directly load our kernel. Linux has to be invoked in a specific way to obtain boot arguments and a pointer to the device tree and initrd, and it also expects that main memory has already been initialized. Boot ROMs also don’t know how to initialize main memory, so we would have nowhere to store Linux. Also, boot ROMs tend to just load a few KB from flash at the most — not enough to house an entire kernel. So, we need a small program that the boot ROM can load that will initialize our main memory and then load the entire (usually-multi-megabyte) Linux kernel and then execute it.

U-Boot has to know a lotof technical details about your system. There’s a dedicated board.c port for each supported platform that initializes clocks, DRAM, and relevant memory peripherals, along with initializing any important peripherals, like your UART console or a PMIC that might need to be configured properly before bringing the CPU up to full speed. Newer board ports often store at least some of this configuration information inside a Device Tree, which we’ll talk about later. Some of the DRAM configuration data is often autodetected, allowing you to change DRAM size and layout without altering the U-Boot port’s code for your processor ((If you have a DRAM layout on the margins of working, or you’re using a memory chip with very different timings than the one the port was built for, you may have to tune these values)). You configure what you want U-Boot to do by writing a script that tells it which device to initialize, which file/address to load into which memory address, and what boot arguments to pass along to Linux. While these can be hard-coded, you’ll often store these names and addresses as environmental variables (the boot script itself can be stored as a bootcmd environmental variable). So a large part of getting U-Boot working on a new board is working out the environment.