1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-05-13 19:29:10 +08:00

Merge pull request #342 from hybridgroup/feature/beaglebone-4

Support for newer Beaglebone 4.x kernels
This commit is contained in:
Ron Evans 2016-12-03 14:33:40 +01:00 committed by GitHub
commit 8bb0fbfbad
5 changed files with 221 additions and 157 deletions

View File

@ -10,7 +10,7 @@ import (
func main() {
beagleboneAdaptor := beaglebone.NewAdaptor()
led := gpio.NewLedDriver(beagleboneAdaptor, "usr0")
led := gpio.NewLedDriver(beagleboneAdaptor, "usr1")
work := func() {
gobot.Every(1*time.Second, func() {

View File

@ -5,31 +5,11 @@ The BeagleBone is an ARM based single board computer, with many different GPIO i
For more info about the BeagleBone platform click [here](http://beagleboard.org/Products/BeagleBone+Black).
## How to Install
```
go get -d -u github.com/hybridgroup/gobot/... && go install github.com/hybridgroup/gobot/platforms/beaglebone
```
## Cross compiling for the Beaglebone Black
You must first configure your Go environment for arm linux cross compiling
```bash
$ cd $GOROOT/src
$ GOOS=linux GOARCH=arm ./make.bash --no-clean
```
Then compile your Gobot program with
```bash
$ GOARM=7 GOARCH=arm GOOS=linux go build examples/beaglebone_blink.go
```
If you are running the official Angstrom or Debian linux through the usb->ethernet connection, you can simply upload your program and execute it with
```bash
$ scp beaglebone_blink root@192.168.7.2:/home/root/
$ ssh -t root@192.168.7.2 "./beaglebone_blink"
```
## How to Use
```go
@ -62,3 +42,40 @@ func main() {
robot.Start()
}
```
## How to Connect
### Compiling
Simply compile your Gobot program like this:
```bash
$ GOARCH=arm GOOS=linux go build examples/beaglebone_blink.go
```
If you are running the official Debian Linux through the usb->ethernet connection, or are connected to the board using WiFi, you can simply upload your program and execute it with the `scp` command like this:
```bash
$ scp beaglebone_blink root@192.168.7.2:/home/root/
$ ssh -t root@192.168.7.2 "./beaglebone_blink"
```
### Updating your board to the latest OS
We recommend updating your BeagleBone to the latest Debian OS. It is very easy to do this using the Etcher (https://etcher.io/) utility program.
First, download the latest BeagleBone OS from http://beagleboard.org/latest-images
Now, use Etcher to create an SD card with the OS image you have downloaded.
Once you have created the SD card, boot your BeagleBone using the new image as follows:
- Insert SD card into your (powered-down) board, hold down the USER/BOOT button (if using Black) and apply power, either by the USB cable or 5V adapter.
- If all you want to do it boot once from the SD card, it should now be booting.
- If using BeagleBone Black and desire to write the image to your on-board eMMC, you'll need to follow the instructions at http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC. When the flashing is complete, all 4 USRx LEDs will be steady on or off. The latest Debian flasher images automatically power down the board upon completion. This can take up to 45 minutes. Power-down your board, remove the SD card and apply power again to be complete.
These instructions come from the Beagleboard web site's "Getting Started" page located here:
http://beagleboard.org/getting-started

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
@ -14,113 +15,22 @@ import (
"github.com/hybridgroup/gobot/sysfs"
)
var slots = "/sys/devices/bone_capemgr.*"
var ocp = "/sys/devices/ocp.*"
var usrLed = "/sys/devices/ocp.3/gpio-leds.8/leds/beaglebone:green:"
var glob = func(pattern string) (matches []string, err error) {
return filepath.Glob(pattern)
}
var pins = map[string]int{
"P8_3": 38,
"P8_4": 39,
"P8_5": 34,
"P8_6": 35,
"P8_7": 66,
"P8_8": 67,
"P8_9": 69,
"P8_10": 68,
"P8_11": 45,
"P8_12": 44,
"P8_13": 23,
"P8_14": 26,
"P8_15": 47,
"P8_16": 46,
"P8_17": 27,
"P8_18": 65,
"P8_19": 22,
"P8_20": 63,
"P8_21": 62,
"P8_22": 37,
"P8_23": 36,
"P8_24": 33,
"P8_25": 32,
"P8_26": 61,
"P8_27": 86,
"P8_28": 88,
"P8_29": 87,
"P8_30": 89,
"P8_31": 10,
"P8_32": 11,
"P8_33": 9,
"P8_34": 81,
"P8_35": 8,
"P8_36": 80,
"P8_37": 78,
"P8_38": 79,
"P8_39": 76,
"P8_40": 77,
"P8_41": 74,
"P8_42": 75,
"P8_43": 72,
"P8_44": 73,
"P8_45": 70,
"P8_46": 71,
"P9_11": 30,
"P9_12": 60,
"P9_13": 31,
"P9_14": 50,
"P9_15": 48,
"P9_16": 51,
"P9_17": 5,
"P9_18": 4,
"P9_19": 13,
"P9_20": 12,
"P9_21": 3,
"P9_22": 2,
"P9_23": 49,
"P9_24": 15,
"P9_25": 117,
"P9_26": 14,
"P9_27": 115,
"P9_28": 113,
"P9_29": 111,
"P9_30": 112,
"P9_31": 110,
}
var pwmPins = map[string]string{
"P9_14": "P9_14",
"P9_21": "P9_21",
"P9_22": "P9_22",
"P9_29": "P9_29",
"P9_42": "P9_42",
"P8_13": "P8_13",
"P8_34": "P8_34",
"P8_45": "P8_45",
"P8_46": "P8_46",
}
var analogPins = map[string]string{
"P9_39": "AIN0",
"P9_40": "AIN1",
"P9_37": "AIN2",
"P9_38": "AIN3",
"P9_33": "AIN4",
"P9_36": "AIN5",
"P9_35": "AIN6",
}
// Adaptor is the gobot.Adaptor representation for the Beaglebone
type Adaptor struct {
name string
digitalPins []sysfs.DigitalPin
pwmPins map[string]*pwmPin
i2cDevice sysfs.I2cDevice
ocp string
helper string
slots string
name string
kernel string
digitalPins []sysfs.DigitalPin
pwmPins map[string]*pwmPin
i2cDevice sysfs.I2cDevice
usrLed string
ocp string
analogPath string
analogPinMap map[string]string
slots string
}
// NewAdaptor returns a new Beaglebone Adaptor
@ -131,12 +41,27 @@ func NewAdaptor() *Adaptor {
pwmPins: make(map[string]*pwmPin),
}
b.setSlots()
return b
}
func (b *Adaptor) setSlots() {
ocp := "/sys/devices/ocp.*"
slots := "/sys/devices/bone_capemgr.*"
b.kernel = getKernel()
if b.kernel[:1] == "4" {
ocp = "/sys/devices/platform/ocp/ocp*"
slots = "/sys/devices/platform/bone_capemgr"
}
b.usrLed = "/sys/class/leds/beaglebone:green:"
g, _ := glob(ocp)
b.ocp = g[0]
g, _ = glob(slots)
b.slots = fmt.Sprintf("%v/slots", g[0])
return b
}
// Name returns the Adaptor name
@ -145,22 +70,37 @@ func (b *Adaptor) Name() string { return b.name }
// SetName sets the Adaptor name
func (b *Adaptor) SetName(n string) { b.name = n }
// Kernel returns the Linux kernel version for the BeagleBone
func (b *Adaptor) Kernel() string { return b.kernel }
// Connect initializes the pwm and analog dts.
func (b *Adaptor) Connect() error {
if err := ensureSlot(b.slots, "cape-bone-iio"); err != nil {
return err
// enable analog
if b.kernel[:1] == "4" {
if err := ensureSlot(b.slots, "BB-ADC"); err != nil {
return err
}
b.analogPath = "/sys/bus/iio/devices/iio:device0"
b.analogPinMap = analogPins44
} else {
if err := ensureSlot(b.slots, "cape-bone-iio"); err != nil {
return err
}
g, err := glob(fmt.Sprintf("%v/helper.*", b.ocp))
if err != nil {
return err
}
b.analogPath = g[0]
b.analogPinMap = analogPins3
}
// enable pwm
if err := ensureSlot(b.slots, "am33xx_pwm"); err != nil {
return err
}
g, err := glob(fmt.Sprintf("%v/helper.*", b.ocp))
if err != nil {
return err
}
b.helper = g[0]
return nil
}
@ -217,7 +157,7 @@ func (b *Adaptor) DigitalRead(pin string) (val int, err error) {
// valid usr pin values are usr0, usr1, usr2 and usr3
func (b *Adaptor) DigitalWrite(pin string, val byte) (err error) {
if strings.Contains(pin, "usr") {
fi, err := sysfs.OpenFile(usrLed+pin+"/brightness", os.O_WRONLY|os.O_APPEND, 0666)
fi, err := sysfs.OpenFile(b.usrLed+pin+"/brightness", os.O_WRONLY|os.O_APPEND, 0666)
defer fi.Close()
if err != nil {
return err
@ -238,7 +178,7 @@ func (b *Adaptor) AnalogRead(pin string) (val int, err error) {
if err != nil {
return
}
fi, err := sysfs.OpenFile(fmt.Sprintf("%v/%v", b.helper, analogPin), os.O_RDONLY, 0644)
fi, err := sysfs.OpenFile(fmt.Sprintf("%v/%v", b.analogPath, analogPin), os.O_RDONLY, 0644)
defer fi.Close()
if err != nil {
@ -306,7 +246,7 @@ func (b *Adaptor) translatePwmPin(pin string) (value string, err error) {
// translateAnalogPin converts analog pin name to pin position
func (b *Adaptor) translateAnalogPin(pin string) (value string, err error) {
for key, value := range analogPins {
for key, value := range b.analogPinMap {
if key == pin {
return value, nil
}
@ -396,3 +336,9 @@ func ensureSlot(slots, item string) (err error) {
}
return
}
func getKernel() string {
result, _ := exec.Command("uname", "-r").Output()
return strings.TrimSpace(string(result))
}

View File

@ -42,7 +42,7 @@ func (n *NullReadWriteCloser) Read(b []byte) (int, error) {
return len(b), nil
}
var closeErr error = nil
var closeErr error
func (n *NullReadWriteCloser) Close() error {
return closeErr
@ -54,16 +54,15 @@ func TestBeagleboneAdaptor(t *testing.T) {
}
fs := sysfs.NewMockFilesystem([]string{
"/dev/i2c-1",
"/sys/devices/bone_capemgr.4",
"/sys/devices/ocp.3",
"/sys/devices/ocp.3/gpio-leds.8/leds/beaglebone:green:usr1/brightness",
"/sys/devices/ocp.3/helper.5",
"/sys/devices/ocp.3/helper.5/AIN1",
"/sys/devices/ocp.3/pwm_test_P9_14.5",
"/sys/devices/ocp.3/pwm_test_P9_14.5/run",
"/sys/devices/ocp.3/pwm_test_P9_14.5/period",
"/sys/devices/ocp.3/pwm_test_P9_14.5/polarity",
"/sys/devices/ocp.3/pwm_test_P9_14.5/duty",
"/sys/devices/platform/bone_capemgr",
"/sys/devices/platform/ocp/ocp4",
"/sys/class/leds/beaglebone:green:usr1/brightness",
"/sys/bus/iio/devices/iio:device0/in_voltage1_raw",
"/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5",
"/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/run",
"/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/period",
"/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/polarity",
"/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/duty",
"/sys/class/gpio/export",
"/sys/class/gpio/unexport",
"/sys/class/gpio/gpio60/value",
@ -74,12 +73,13 @@ func TestBeagleboneAdaptor(t *testing.T) {
sysfs.SetFilesystem(fs)
a := NewAdaptor()
a.slots = "/sys/devices/bone_capemgr.4"
a.ocp = "/sys/devices/ocp.3"
a.slots = "/sys/devices/platform/bone_capemgr"
a.ocp = "/sys/devices/platform/ocp/ocp4"
a.kernel = "4.4"
a.Connect()
a.helper = "/sys/devices/ocp.3/helper.5"
a.analogPath = "/sys/bus/iio/devices/iio:device0"
// PWM
glob = func(pattern string) (matches []string, err error) {
@ -91,39 +91,39 @@ func TestBeagleboneAdaptor(t *testing.T) {
a.PwmWrite("P9_14", 175)
gobottest.Assert(
t,
fs.Files["/sys/devices/ocp.3/pwm_test_P9_14.5/period"].Contents,
fs.Files["/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/period"].Contents,
"500000",
)
gobottest.Assert(
t,
fs.Files["/sys/devices/ocp.3/pwm_test_P9_14.5/duty"].Contents,
fs.Files["/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/duty"].Contents,
"343137",
)
a.ServoWrite("P9_14", 100)
gobottest.Assert(
t,
fs.Files["/sys/devices/ocp.3/pwm_test_P9_14.5/period"].Contents,
fs.Files["/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/period"].Contents,
"16666666",
)
gobottest.Assert(
t,
fs.Files["/sys/devices/ocp.3/pwm_test_P9_14.5/duty"].Contents,
fs.Files["/sys/devices/platform/ocp/ocp4/pwm_test_P9_14.5/duty"].Contents,
"1898148",
)
// Analog
fs.Files["/sys/devices/ocp.3/helper.5/AIN1"].Contents = "567\n"
fs.Files["/sys/bus/iio/devices/iio:device0/in_voltage1_raw"].Contents = "567\n"
i, _ := a.AnalogRead("P9_40")
gobottest.Assert(t, i, 567)
i, err := a.AnalogRead("P9_99")
_, err := a.AnalogRead("P9_99")
gobottest.Assert(t, err, errors.New("Not a valid pin"))
// DigitalIO
a.DigitalWrite("usr1", 1)
gobottest.Assert(t,
fs.Files["/sys/devices/ocp.3/gpio-leds.8/leds/beaglebone:green:usr1/brightness"].Contents,
fs.Files["/sys/class/leds/beaglebone:green:usr1/brightness"].Contents,
"1",
)

View File

@ -0,0 +1,101 @@
package beaglebone
var pins = map[string]int{
"P8_3": 38,
"P8_4": 39,
"P8_5": 34,
"P8_6": 35,
"P8_7": 66,
"P8_8": 67,
"P8_9": 69,
"P8_10": 68,
"P8_11": 45,
"P8_12": 44,
"P8_13": 23,
"P8_14": 26,
"P8_15": 47,
"P8_16": 46,
"P8_17": 27,
"P8_18": 65,
"P8_19": 22,
"P8_20": 63,
"P8_21": 62,
"P8_22": 37,
"P8_23": 36,
"P8_24": 33,
"P8_25": 32,
"P8_26": 61,
"P8_27": 86,
"P8_28": 88,
"P8_29": 87,
"P8_30": 89,
"P8_31": 10,
"P8_32": 11,
"P8_33": 9,
"P8_34": 81,
"P8_35": 8,
"P8_36": 80,
"P8_37": 78,
"P8_38": 79,
"P8_39": 76,
"P8_40": 77,
"P8_41": 74,
"P8_42": 75,
"P8_43": 72,
"P8_44": 73,
"P8_45": 70,
"P8_46": 71,
"P9_11": 30,
"P9_12": 60,
"P9_13": 31,
"P9_14": 50,
"P9_15": 48,
"P9_16": 51,
"P9_17": 5,
"P9_18": 4,
"P9_19": 13,
"P9_20": 12,
"P9_21": 3,
"P9_22": 2,
"P9_23": 49,
"P9_24": 15,
"P9_25": 117,
"P9_26": 14,
"P9_27": 115,
"P9_28": 113,
"P9_29": 111,
"P9_30": 112,
"P9_31": 110,
}
var pwmPins = map[string]string{
"P9_14": "P9_14",
"P9_21": "P9_21",
"P9_22": "P9_22",
"P9_29": "P9_29",
"P9_42": "P9_42",
"P8_13": "P8_13",
"P8_34": "P8_34",
"P8_45": "P8_45",
"P8_46": "P8_46",
}
var analogPins3 = map[string]string{
"P9_39": "AIN0",
"P9_40": "AIN1",
"P9_37": "AIN2",
"P9_38": "AIN3",
"P9_33": "AIN4",
"P9_36": "AIN5",
"P9_35": "AIN6",
}
var analogPins44 = map[string]string{
"P9_39": "in_voltage0_raw",
"P9_40": "in_voltage1_raw",
"P9_37": "in_voltage2_raw",
"P9_38": "in_voltage3_raw",
"P9_33": "in_voltage4_raw",
"P9_36": "in_voltage5_raw",
"P9_35": "in_voltage6_raw",
}