NULLCape. How to Roll your own BeagleBone Capes (Part I)

We want to learn how to build BegleBone capes and in this series of post we will be writing about our findings and how we built the NULLCape. You are right, that is the very minimum cape which actually does nothing.


Good question. Yes, sure you already now, but just in case you are really, really new to the BeagleBone or you've got yours as a present you had never ever hear of it.

A cape is just an expansion board for the BeagleBone. The BeagleBone provides two headers on its sides with lots of signals and interfaces, however you normally need something else to be able to attach your peripherals to this connectors. In the simpler case some wires and a platform to mechanically keep your peripheral and in the most complex case some support circuitry in order to do whatever you want to do.

So, a cape is an expansion board for your BeagleBone the same than a extension board for your desktop computer (a graphics card or an audio card,...). In the same way that the boards you connect to your desktop computer have to follow some rules (size, connectors, pins they have to use in your motherboard bus), a Beaglebone cape also has to follow some rules, and this is what these articles are about.


For starters we will have to read some documentation. Yes, you can probably follow this tutorial without reading the docs, but it is really an useful exercise as, documentation, is one of the strongest points of the BeagleBone... the official documentation is really high quality and professional. Just great.

So, the starting point is the System Reference Manual (aka SRM). This is the document that described in full detail everything you will ever want to know about the board. There is another document also very interesting that describes the SoC (System On Chip) on the BeagleBone. This one is usually known as Technical Reference Manual (aka TRM).

The most reliable source for the first document is BeagleBone Black circuitco wiki. The TRM is available from the Texas Instruments site. So, go to this link and grab the manual now!

SRM: System Reference Manual and schematics

TRM: Technical Reference Manual

It might also be a good idea to also grab the BeagleBone schematics PDF and keep it nearby.

Once you got the System Reference Manual, you should start reading it from the beginning. If you had not done it before you will learn quite a lot of interesting stuff. If you are a really impatient one, then go to "Chapter 8 - Cape Board Support" (looks like previous versions of the manual had this information on other chapters). Let's skip, for the time being, the eMMC and HDMI incompatibilities and move to Section "8.2 the EEPROM".

That is the first thing we need to sort out. Well, actually it is not, but we think this is a great starting point.

So what is this EEPROM thingy about?. Simple, that EEPROM is there because most of the pins in the expansion header were we are going to plug our cape may have different functions (that is called the pin's mux mode). Depending on what our cape will be designed to do we will need one function or another. However, these pin functions can only be configured from software so we need a way to let the software know which pins do we want to use. That's the main reason for the existence of this EEPROM. Additionally, it can be used to store additional data as calibration tables or any data that may be needed by the cape itself.


The SRM (System Reference Manual) section 8.2 tell us about which EEPROM to use. Basically it has to be a 32Kb I2C serial EEPROM supporting 16bits addressing. We are using one of those standard DIP 24C245. Nothing special

In that very same section (8.2), a reference circuit on how to connect our memory is also shown. Basically we need a bunch of pull-up resistors and a capacitor. The DIP-Switch is optional and we will not need it right now. We will connect our memory address pins to a hard-wired address for our tests.

BeagleBone Cape reference EEPROM circuitryBeagleBone Cape reference EEPROM circuitry

So let's go ahead and mount our circuit. In our case we do not have 5.6K resistors so we also used 4.7K ones. Actually this 5.6K are selected in a way that when 4 capes are stacked the resistance seen by the I2C bus is 5.6 / 4 = 1.4K, so in principle any resistor value between 1.4K and 5.6K should work (as far as you do not stack any extra cape in).

For our very first test we will set all the EEPROM address pins to 0. That configures the chip as an I2C device at address 0x50. This is not a valid address for a cape EEPROM as we will see in a while, but it is convenient for us right now.

So here is our circuit.

NULLCape: BeagleBone Black, I2C Serial EEPROM Test circuit.NULLCape: BeagleBone Black, I2C Serial EEPROM Test circuit.

The memory is being powered from the 3V3 rail on the expansion board and pins 19 and 20 on the P9 connector used for the I2C Bus. Pin assignment is as follows:

BBB 24C256
P9-1 GND 4 GND
  1 AD0 (Address 0)
  2 AD1 (Address 1)
  3 AD2 (Address 2)
P9-3 3V3 8 VCC
P9-19 I2C2-SCL 6 SLK
P9-20 I2C2-SLA 5 SLA

Now we can connect our circuit and power up our BeagleBone.


Once the BeagleBone has booted we can ssh into it:

$ ssh root@
So first thing to do is verify that our memory is properly connected:
$ i2cdetect -y -r 1
The -y and -r flags are required to avoid the command to last for ever. The last 1 in the command indicates that we want to detect devices in the I2C2 bus. As it often happens on this cases, buses are enumerated starting from 1 in the HW side and starting from 0 in the SW side. This command will show something like that, indicating that our device is configured at address 0x50. i2cdetect output
# i2cdetect -y -r 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Now we have to check if we can write in our brand new EEPROM. In principle we should be able to use i2cset and i2cdump for that, but those didn't worked well for us. So what we are going to do is use the EEPROM as it is meant to be used in our cape.


For our test we will use the neat i2c interface provided by the Linux kernel. At this point we just have something connected to our i2c bus at address 0x50. Right now, that's all the kernel knows about that device. So we have to tell the kernel which kind of animal is sitting there. This process is know as i2c instantiation and it can be performed on different ways. Refer to the kernel documentation file /Documentation/i2c/instantiating-devices for more details. For the time being, we only need to know that our device can be managed by the at24 driver that somebody smarter than us had wrote. Before loading the driver let's made a couple of checks to better understand what is going on: All known i2C devices appear under /sys/bus/i2c/devices with a name composed of two numbers. First number is the i2c port, and second number is the i2C address. Whatever is inside those directories will depend on the driver associated to it. The contents of this directory should be something like this:
root@beaglebone:~# ls /sys/bus/i2c/devices/
0-0024	0-0034	0-0050	0-0070	1-0054	1-0055	1-0056	1-0057	i2c-0 i2c-1
As you can see there is no 1-0050 entry which is the number representing our EEPROM. Now we can try to instantiate our i2C device, or in other words, we can try to associate the at24 driver to our i2c device at address 0x50:
# echo 24c256 0x50 > /sys/bus/i2c/devices/i2c-1/new_device 
So we are basically telling our kernel that the device on the i2c bus 1 sitting at address 0x50 is a 24c256 EEPROM. We can now check what has just happened. First we take a look to kernel log. We should see a couple of lines like these.
# dmesg
[  516.474189] at24 1-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[  516.477455] i2c i2c-1: new_device: Instantiated device 24c256 at 0x50
No error there and the lines look OK. So now we have a neat eeprom field on our sys filesystem that, guess what?, can be used to write and read the contents on the EEPROM.
root@beaglebone:~# ls /sys/bus/i2c/devices/                                 
0-0024	0-0034	0-0050	0-0070	1-0050	1-0054	1-0055	1-0056	1-0057	i2c-0  i2c-1
Good, now we have an entry for our device 1-0050, and inside it we can see:
root@beaglebone:~# ls /sys/bus/i2c/devices/1-0050/          
driver	eeprom	modalias  name	power  subsystem  uevent
Yep, an entry named eeprom which is actually the content of our memory chip.


So let's write some data on the memory. We can do that just typing this on the command line:
root@beaglebone:~# echo "This is a text to be stored in out EEPROM" > /sys/bus/i2c/devices/1-0050/eeprom
And we can retrieve the data also from the command line just "catting" the same "file":
root@beaglebone:~# cat /sys/bus/i2c/devices/1-0050/eeprom | hexdump -C 
00000000  54 68 69 73 20 69 73 20  61 20 74 65 78 74 20 74  |This is a text t|
00000010  6f 20 62 65 20 73 74 6f  72 65 64 20 69 6e 20 6f  |o be stored in o|
00000020  75 74 20 45 45 50 52 4f  4d 0a ff ff ff ff ff ff  |ut EEPROM.......|
00000030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
Your output might vary depending on the previous contents of the memory We had used the command hexdump which, as it own name indicates, performs an hexadecimal dump of a binary file. Even when we had write some text in the EEPROM, the memory is 32Kb long and will contain unintialised data which can corrupt our terminal (if that happens, blindly type reset and press enter). The -C flag instructs hexdump to also dump ASCII character for every printable value. So we get this nice output:


We are almost done. To finish with this first step on how to build a BeagleBone Cape we have to change the i2c address of our memory. The System Reference Manual states that capes shall use the range of address 0x54 to 0x57 and we are just using 0x50 right now. That means that our EEPROM, as it is wired now, will never make it into a cape EEPROM. So we shutdown the BeagleBone, wire the A2 (pin 3) signal in our 24C256 chip to VCC and our memory will start using address 0x54. That's the reason why the figure in section 8.2 of the SRM wires the A2 line to 3V3... to ensure the address is in the right range. Now we can reboot the board. Note that in this specific example you will have to re-register the device, so, for now, it is simply easier to reboot


In principle you should be able to change this connections without switching the BBB off, however it is always safe to do that. If you do not want to shutdown the BeagleBone, at least disconnect your test board from the expansion connections and for sure, disconnect the power connections if you are really lazy like me. As usual, the author cannot assume any responsability in case your board is damaged or completely blows away. Everything described in this article worked OK for the author but if you decide to follow it, do it at your own risk. Accidents happens and we had already fried some boards playing with this.
Let's run i2cdetect again and we will see that our device is no longer at address 0x50. If we check the sys filesystem we will see that the eeprom file is already there without running our instantiation code. What had happened? What happened is that the default BBB configuration reserves in advance the addresses 0x54 to 0x57 and pre-loads the at24 driver. Let's run the following command to check when that occurred.
# dmesg | grep at24
[    0.241961] at24 0-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[    0.242038] at24 1-0054: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[    0.242109] at24 1-0055: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[    0.242176] at24 1-0056: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[    0.242244] at24 1-0057: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
Here we can see the 4 instantiations of the at24 driver for the four reserved address, happening at the very beginning of the boot sequence (at second 0.25 aprox.). Now we can read whatever information we previously stored in our EEPROM. It will still be there (that's what an EEPROM is made for), but now at address 0x54.
root@beaglebone:~# cat /sys/bus/i2c/devices/1-0054/eeprom | hexdump -C 
00000000  54 68 69 73 20 69 73 20  61 20 74 65 78 74 20 74  |This is a text t|
00000010  6f 20 62 65 20 73 74 6f  72 65 64 20 69 6e 20 6f  |o be stored in o|
00000020  75 74 20 45 45 50 52 4f  4d 0a ff ff ff ff ff ff  |ut EEPROM.......|
00000030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|


At this point our hardware is ready for the NULLCape. Sure, an original name for a cape that does noting :). Even when this cape will do nothing, there are still some things we have to do to make this minimal circuit into a BBB cape. But we will see that in the next chapter. The picoFlamingo Team


driver and eeprom file

Hi picoflamingo,

i try to built a cape with an integrated EEPROM to load the device tree overlays.

My problem is that, the eeprom file and the driver folder for the device 1-0050 in /sys/bus/i2c/devices/1-0050/ are missing.
They were not created.
I use a 24LC1025 instead a 24C256, can this cause the problem?

Thank you for your advice.

echo 24c1024 0x50 >


It is a long time since I do not play with this. I had quickly checked the first pages of the interfaces and the two memories seems similar. However your model is not included in the list of memories supported by the driver (

So, if we assume that you can see your memory at 0x50 (with i2cdetect) and that when you instantiate your device nothing is mentioned in the log file, then, there are many chances that the memory cannot be used.

Did you try to use a closer size memory on the instantiation?
echo 24c1024 0x50 > /sys/bus/i2c/devices/i2c-1/new_device

Unfortunately I do not have one of those memories to try myself.



Thanks for the tutorial. But what's an SoC? The only meaning I know for that is "State of Charge", which makes no sense here. Maybe you could spell out the meaning of any acronyms the first time you use them, for newbies like me. Thanks.

System On Chip

Good point. SoC Stands for System on Chip (

Build a cape with out eeprom

Thanks for this amazing tutorial
i try to build a LCD7 cape like one in 4D Systems company,but i didn't find there eeprom file contents to download it to my eeprom .
if i had no eeprom in my LCD cape design, and connect my LCD cape to the BBB and open cap manager and echo the compiled device tree of my cap to the cape manager manually .
will my LCD cape work ??

i know that the eeprom function is only to tell the BBB when i connect my cape to load the Overlay of my cape manager ,
so if i load the overlay to the cape manager manually my cape should work with out eeprom in cape design

is the eeprom important for any function of my cape if i load my cape overlay manually to cape manager ?


NO-EEPROM capes should be OK

I'll try to answer what I can and as far as I know...

Generally speaking you do not need to add an EEPROM to connect anything to the BeagleBone. You just need to make sure that the used pins are configured as your board/cape expects.

I had also noticed that there is no EEPROM dump available for any cape out there. That is pretty disappointing. However the content of the EEPROM only depends on you. The only relevant part as for today (and as far as I know) is the part number that is used to determine which device tree overlay needs to be loaded.

In section 7.11 of the SRM (System Reference Manual) where the EEPROMs are discussed, we can read:

"The one exception is proto boards intended for prototyping. They may or may not have an EEPROM on them."

Despite of the interpretation of what a proto board, it can be infer that the EEPROM itself is a convention.

link request

Thanks for the valuable information, i was escaping from eeprom support for my capes. Now everything is clear for me. Esp. Linux tools and driver info was very important for me. Thanks a lot.
It would be better if you place a link for the next chapters, at the bottom

Good Comment

I had added the links. Thanks for the good tip!