Skip to content

Commit

Permalink
X86 support on genericlinux (#2340)
Browse files Browse the repository at this point in the history
  • Loading branch information
susmitaSanyal authored May 10, 2023
1 parent cdc4e60 commit 627dd95
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 9 deletions.
13 changes: 4 additions & 9 deletions components/board/genericlinux/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
"strings"

"github.com/pkg/errors"
"go.viam.com/utils"

rdkutils "go.viam.com/rdk/utils"
)

// adapted from https://github.com/NVIDIA/jetson-gpio (MIT License)
Expand Down Expand Up @@ -96,16 +97,10 @@ func GetGPIOBoardMappings(modelName string, boardInfoMappings map[string]BoardIn
// getCompatiblePinDefs returns a list of pin definitions, from the first BoardInformation struct
// that appears compatible with the machine we're running on.
func getCompatiblePinDefs(modelName string, boardInfoMappings map[string]BoardInformation) ([]PinDefinition, error) {
const compatiblePath = "/proc/device-tree/compatible"

compatiblesRd, err := os.ReadFile(compatiblePath)
compatibles, err := rdkutils.GetDeviceInfo(modelName)
if err != nil {
if os.IsNotExist(err) {
return nil, noBoardError(modelName)
}
return nil, err
return nil, fmt.Errorf("error while getting hardware info %w", err)
}
compatibles := utils.NewStringSet(strings.Split(string(compatiblesRd), "\x00")...)

var pinDefs []PinDefinition
for _, info := range boardInfoMappings {
Expand Down
33 changes: 33 additions & 0 deletions components/board/upboard/board.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Package upboard implements an Intel based board.
package upboard

// This is experimental
/*
Datasheet: https://github.com/up-board/up-community/wiki/Pinout_UP4000
Supported board: UP4000
*/

import (
"github.com/edaniels/golog"
"github.com/pkg/errors"
"periph.io/x/host/v3"

"go.viam.com/rdk/components/board/genericlinux"
)

const modelName = "upboard"

func init() {
if _, err := host.Init(); err != nil {
golog.Global().Debugw("error initializing host", "error", err)
}

gpioMappings, err := genericlinux.GetGPIOBoardMappings(modelName, boardInfoMappings)
var noBoardErr genericlinux.NoBoardFoundError
if errors.As(err, &noBoardErr) {
golog.Global().Debugw("error getting up board GPIO board mapping", "error", err)
}

// Not using Periph io for GPIO
genericlinux.RegisterBoard(modelName, gpioMappings, false)
}
56 changes: 56 additions & 0 deletions components/board/upboard/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package upboard

// This is experimental.

import "go.viam.com/rdk/components/board/genericlinux"

const upboard = "up_4000"

var boardInfoMappings = map[string]genericlinux.BoardInformation{
upboard: {
[]genericlinux.PinDefinition{
/*
pinout for up4000: https://github.com/up-board/up-community/wiki/Pinout_UP4000
GPIOChipRelativeIDs: {ngpio : base-linux_gpio_number}
GPIOChipSysFSDir: path to the directory of a chip. Can be found from the output of gpiodetect
*/
// GPIO pin definition
{map[int]int{78: 73}, map[int]string{}, "INT3452:01", 29, 0, "GPIO10", "", "", -1},
{map[int]int{77: 46}, map[int]string{}, "INT3452:01", 31, 0, "BCM26", "", "", -1},
{map[int]int{77: 48}, map[int]string{}, "INT3452:01", 18, 0, "BCM24", "", "", -1},
{map[int]int{77: 45}, map[int]string{}, "INT3452:01", 22, 0, "BCM25", "", "", -1},
{map[int]int{77: 46}, map[int]string{}, "INT3452:01", 37, 0, "BCM26", "", "", -1},
{map[int]int{47: 17}, map[int]string{}, "INT3452:02", 35, 0, "BCM19", "", "", -1},
{map[int]int{77: 75}, map[int]string{}, "INT3452:01", 13, 0, "BMC27", "", "", -1},

// ttyS4 UART
{map[int]int{78: 43}, map[int]string{}, "INT3452:00", 8, 0, "BCM14_TXD", "", "", -1},
{map[int]int{78: 42}, map[int]string{}, "INT3452:00", 10, 0, "BCM15_RXD", "", "", -1},
{map[int]int{78: 44}, map[int]string{}, "INT3452:00", 11, 0, "BCM17", "", "", -1},
{map[int]int{78: 45}, map[int]string{}, "INT3452:00", 36, 0, "BMC16", "", "", -1},

// I2c
{map[int]int{78: 28}, map[int]string{}, "INT3452:00", 3, 0, "BCM2_SDA", "", "", -1},
{map[int]int{78: 29}, map[int]string{}, "INT3452:00", 5, 0, "BVM3_SCL", "", "", -1},
{map[int]int{78: 31}, map[int]string{}, "INT3452:00", 28, 0, "BMC1_ID_SCL", "", "", -1},

// pwm
{map[int]int{78: 35}, map[int]string{}, "INT3452:00", 33, 0, "BMC13_PWM1", "", "0000:00:1a.0", 0},
{map[int]int{78: 34}, map[int]string{}, "INT3452:00", 32, 0, "BCM12_PWM0", "", "0000:00:1a.0", 1},
{map[int]int{78: 37}, map[int]string{}, "INT3452:00", 16, 0, "BCM23", "", "0000:00:1a.0", 3},

{map[int]int{77: 76}, map[int]string{}, "INT3452:01", 7, 0, "BCM4", "", "", -1},
{map[int]int{77: 65}, map[int]string{}, "INT3452:01", 19, 0, "BCM10_MOSI", "", "", -1},
{map[int]int{77: 64}, map[int]string{}, "INT3452:01", 21, 0, "BCM9_MISO", "", "", -1},
{map[int]int{77: 61}, map[int]string{}, "INT3452:01", 23, 0, "BCM11_SCLK", "", "", -1},
{map[int]int{78: 30}, map[int]string{}, "INT3452:00", 27, 0, "BCM0_ID_SD", "", "", -1},
{map[int]int{47: 16}, map[int]string{}, "INT3452:02", 12, 0, "BCM15_RXD", "", "", -1},
{map[int]int{77: 62}, map[int]string{}, "INT3452:01", 24, 0, "BCM8_CE0", "", "", -1},
{map[int]int{77: 63}, map[int]string{}, "INT3452:01", 26, 0, "BCM7_CE1", "", "", -1},
{map[int]int{47: 18}, map[int]string{}, "INT3452:02", 38, 0, "BCM20", "", "", -1},
{map[int]int{47: 19}, map[int]string{}, "INT3452:02", 40, 0, "BCM21", "", "", -1},
{map[int]int{77: 74}, map[int]string{}, "INT3452:01", 15, 0, "BCM22", "", "", -1},
},
[]string{"UP-APL03"},
},
}
61 changes: 61 additions & 0 deletions utils/hardware_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package utils

import (
"bytes"
"fmt"
"os"
"runtime"
"strings"

"go.viam.com/utils"
)

// GetDeviceInfo returns the device information in stringset.
func GetDeviceInfo(modelName string) (utils.StringSet, error) {
arch := runtime.GOARCH

switch {
case strings.HasPrefix(arch, "amd"):
return stringSetFromX86(modelName)
case strings.HasPrefix(arch, "arm"):
return stringSetFromARM(modelName)
default:
return nil, noBoardError(modelName)
}
}

// A helper function for ARM architecture to process contents of the
// device path and returns the compatible device information.
func stringSetFromARM(modelName string) (utils.StringSet, error) {
const path = "/proc/device-tree/compatible"
compatiblesRd, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil, noBoardError(modelName)
}
return nil, err
}

return utils.NewStringSet(strings.Split(string(compatiblesRd), "\x00")...), nil
}

// A helper function for AMD architecture to process contents of the
// device path and returns the compatible device information.
func stringSetFromX86(modelName string) (utils.StringSet, error) {
const path = "/sys/devices/virtual/dmi/id/board_name"
compatiblesRd, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil, noBoardError(modelName)
}
return nil, err
}

compatiblesRd = bytes.TrimSpace(compatiblesRd)

return utils.NewStringSet(string(compatiblesRd)), nil
}

func noBoardError(modelName string) error {
return fmt.Errorf("could not determine %q model", modelName)
}

0 comments on commit 627dd95

Please sign in to comment.