BeagleBone Black, FreeBSD and GPIOs
October 2013.
Introduction
The BeagleBone black, using its AM335X CPU, provides a number of GPIOs. Let's try to make them work.
Trying to find the device
dmesg indicates that the kernel found a GPIO device.
gpio0:mem 0x44e07000-0x44e07fff,0x4804c000-0x4804cfff,0x481ac000-0x481acfff,0x481ae000-0x481aefff irq 96,97,98,99,32,33,62,63 on simplebus0
gpioc0:on gpio0
gpiobus0:on gpio0
devinfo and ofwdump confirm that the corresponding nodes exist.
# devinfo
nexus0
fdtbus0
simplebus0
aintc0
ti_scm0
am335x_prcm0
am335x_dmtimer0
gpio0
gpioc0
gpiobus0
uart0
ti_edma30
sdhci_ti0
mmc0
mmcsd0
sdhci_ti1
mmc1
mmcsd1
cpsw0
miibus0
smscphy0
iichb0
iicbus0
iic0
am335x_pmic0
am335x_pwm0
am335x_pwm1
am335x_pwm2
musbotg0
usbus0
uhub0
ustorage_fs0
usbus1
uhub1
# ofwdump -a
Node 0x38:
Node 0xc4: am335x
Node 0x124: interrupt-controller@48200000
Node 0x1b4: scm@44e10000
Node 0xb24: prcm@44E00000
Node 0xb88: dmtimers@44E05000
Node 0xc6c: gpio
Node 0xd14: serial@44E09000
Node 0xda8: serial@48022000
Node 0xe54: serial@48024000
Node 0xf00: serial@481a6000
Node 0xfac: serial@481a8000
Node 0x1058: serial@481aa000
Node 0x1104: edma3@49000000
Node 0x1188: mmchs0@48060000
Node 0x120c: mmchs1@481D8000
Node 0x12a4: ethernet@4A100000
Node 0x1340: mdio@0
Node 0x1388: ethernet-phy@0
Node 0x13c8: i2c@44e0b000
Node 0x1454: pmic@24
Node 0x1494: pwm@48300000
Node 0x1548: pwm@48302000
Node 0x15fc: pwm@48304000
Node 0x16b0: lcd@4830e000
Node 0x1738: usb@47400000
Node 0x1808: mbox0@480C8000
Node 0x1874: spinlock0@480CA000
Node 0x18c0: pruss@4A300000
Node 0x1944: aliases
Node 0x198c: memory
Node 0x19c4: chosen
# ofwdump -p /am335x/gpio
Node 0xc6c: gpio
#gpio-cells:
00 00 00 03
compatible:
74 69 2c 67 70 69 6f 00
'ti,gpio'
gpio-controller:
reg:
44 e0 70 00 00 00 10 00 48 04 c0 00 00 00 10 00 48 1a c0 00
00 00 10 00 48 1a e0 00 00 00 10 00
interrupts:
00 00 00 60 00 00 00 61 00 00 00 62 00 00 00 63 00 00 00 20
00 00 00 21 00 00 00 3e 00 00 00 3f
interrupt-parent:
00 00 00 01
Using the device
Reading the kernel source code indicates that the GPIOs are used with a tool called gpioctl.
Listing the available IOs shows that some of them are already configured.
# gpioctl -f /dev/gpioc0 -l
pin 00: 0 gpio_0<>
pin 01: 0 gpio_1<>
pin 02: 0 gpio_2<>
pin 03: 0 gpio_3<>
pin 04: 0 gpio_4<>
pin 05: 0 gpio_5<>
pin 06: 0 gpio_6<>
pin 07: 0 gpio_7
pin 08: 0 gpio_8
pin 09: 0 gpio_9
pin 10: 0 gpio_10
pin 11: 0 gpio_11
pin 12: 0 gpio_12
pin 13: 0 gpio_13
pin 14: 0 gpio_14
pin 15: 0 gpio_15
pin 16: 0 gpio_16<>
pin 17: 0 gpio_17<>
pin 18: 0 gpio_18<>
pin 19: 0 gpio_19<>
pin 20: 0 gpio_20
pin 21: 0 gpio_21<>
pin 22: 0 gpio_22<>
pin 23: 0 gpio_23<>
pin 24: 0 gpio_24<>
pin 25: 0 gpio_25<>
pin 26: 0 gpio_26
pin 27: 0 gpio_27
pin 28: 0 gpio_28<>
pin 29: 0 gpio_29
pin 30: 0 gpio_30
pin 31: 0 gpio_31
pin 32: 0 gpio_32<>
pin 33: 0 gpio_33<>
pin 34: 0 gpio_34<>
pin 35: 0 gpio_35<>
pin 36: 0 gpio_36<>
pin 37: 0 gpio_37<>
pin 38: 0 gpio_38<>
pin 39: 0 gpio_39<>
pin 40: 0 gpio_40
pin 41: 0 gpio_41
pin 42: 0 gpio_42<>
pin 43: 0 gpio_43<>
pin 44: 0 gpio_44
pin 45: 0 gpio_45
pin 46: 0 gpio_46
pin 47: 0 gpio_47
pin 48: 0 gpio_48
pin 49: 0 gpio_49
pin 50: 0 gpio_50<>
pin 51: 0 gpio_51<>
pin 52: 0 gpio_52
pin 53: 0 gpio_53
pin 54: 0 gpio_54
pin 55: 0 gpio_55
pin 56: 0 gpio_56
pin 57: 0 gpio_57
pin 58: 0 gpio_58
pin 59: 0 gpio_59
pin 60: 0 gpio_60
pin 61: 0 gpio_61
pin 62: 0 gpio_62<>
pin 63: 0 gpio_63<>
pin 64: 0 gpio_64
pin 65: 0 gpio_65
pin 66: 0 gpio_66<>
pin 67: 0 gpio_67<>
pin 68: 0 gpio_68<>
pin 69: 0 gpio_69
pin 70: 0 gpio_70
pin 71: 0 gpio_71
pin 72: 0 gpio_72
pin 73: 0 gpio_73
pin 74: 0 gpio_74
pin 75: 0 gpio_75
pin 76: 0 gpio_76
pin 77: 0 gpio_77
pin 78: 0 gpio_78
pin 79: 0 gpio_79<>
pin 80: 0 gpio_80<>
pin 81: 0 gpio_81<>
pin 82: 0 gpio_82<>
pin 83: 0 gpio_83<>
pin 84: 0 gpio_84<>
pin 85: 0 gpio_85<>
pin 86: 0 gpio_86
pin 87: 0 gpio_87
pin 88: 0 gpio_88
pin 89: 0 gpio_89
pin 90: 0 gpio_90<>
pin 91: 0 gpio_91<>
pin 92: 0 gpio_92<>
pin 93: 0 gpio_93<>
pin 94: 0 gpio_94<>
pin 95: 0 gpio_95<>
pin 96: 0 gpio_96
pin 97: 0 gpio_97
pin 98: 0 gpio_98<>
pin 99: 0 gpio_99<>
pin 100: 0 gpio_100<>
pin 101: 0 gpio_101<>
pin 102: 0 gpio_102<>
pin 103: 0 gpio_103<>
pin 104: 0 gpio_104
pin 105: 0 gpio_105<>
pin 106: 0 gpio_106<>
pin 107: 0 gpio_107<>
pin 108: 0 gpio_108<>
pin 109: 0 gpio_109<>
pin 110: 0 gpio_110
pin 111: 0 gpio_111
pin 112: 0 gpio_112
pin 113: 0 gpio_113
pin 114: 0 gpio_114<>
pin 115: 0 gpio_115
pin 116: 0 gpio_116
pin 117: 0 gpio_117
pin 118: 0 gpio_118<>
pin 119: 0 gpio_119<>
pin 120: 0 gpio_120<>
pin 121: 0 gpio_121<>
pin 122: 0 gpio_122<>
pin 123: 0 gpio_123<>
pin 124: 0 gpio_124<>
pin 125: 0 gpio_125<>
pin 126: 0 gpio_126<>
pin 127: 0 gpio_127<>
Let's try to play with the board's 4 builtin LEDs.
# gpioctl -f /dev/gpioc0 -t 53
# gpioctl -f /dev/gpioc0 -t 54
# gpioctl -f /dev/gpioc0 -t 55
# gpioctl -f /dev/gpioc0 -t 56
Yep, they work.
Let's try configure another random IO.
# gpioctl -f /dev/gpioc0 -c 49 OUT OD
0/OUT
1/OD
GPIO1_17 (P9.23) should be configured as an open-drain output pin. Let's try to change its value.
root@beaglebone:~ # while 1
while? gpioctl -f /dev/gpioc0 -t 49
while? sleep 1
while? end
^C
We created a very slow bit-banged PWM.
Reference and relevant information
- GPIO framework for FreeBSD: https://wiki.freebsd.org/FreeBSD/GPIO
- sys/boot/fdt/dts/beaglebone-black.dts: http://fxr.watson.org/fxr/source/boot/fdt/dts/beaglebone-black.dts?im=10
- Flattened Device Trees for embedded FreeBSD (RafaÅ Jaworowski / BSDCan 2010, Ottawa): http://www.bsdcan.org/2010/schedule/attachments/136_FreeBSD_FDT-slides.pdf