Categorygithub.com/lion187chen/socketcan-go
repositorypackage
1.0.5
Repository: https://github.com/lion187chen/socketcan-go.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author

# README

socketcan-go

socketcan-go makes use of the Linux SocketCAN abstraction for CAN communication.

Realize:

  • Up/Down
  • Set bitrate
  • Set hardware filters
  • Loopback mode

Full Demo:

package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/lion187chen/socketcan-go"
	"github.com/lion187chen/socketcan-go/canframe"
)

var lookback bool = true

var wg sync.WaitGroup

func main() {
	// Create a new CAN, the can interface name is "can0".
	can := new(socketcan.Can).Init("can0")
	// Set down to set bitrate.
	can.SetDown()
	// Test if CAN is down.
	fmt.Println(can.IsUp())
	// To set bitrate, we must down the CAN interface first.
	can.SetBitrate(100000)
	// Up the CAN to set filter or transmit CAN frames.
	can.SetUp()
	// To see CAN bitrate.
	fmt.Println(can.Bitrate())
	// Test if CAN is up.
	fmt.Println(can.IsUp())
	// Dial() will open a CAN socket and bind it to the given interface in Init().
	can.Dial()

	// After Dial(), we can set CAN hardware filters.
	var filters []socketcan.Filter = []socketcan.Filter{
		socketcan.NewExtFilter(0x20),
		socketcan.NewExtFilter(0x21),
		socketcan.NewExtFilter(0x40),
	}
	can.SetFilter(filters)

	// Or set the CAN in lookback mode.
	// We will stop lookback mode in EchoTsk.
	var sendFrame canframe.Frame = canframe.Frame{
		ID:         0x20,
		Data:       []byte{0x01, 0x02, 0x03, 0x4, 0x05, 0x06, 0x07, 0x08},
		IsExtended: true,
		IsRemote:   false,
		IsError:    false,
	}
	can.SetLoopback(lookback)
	// Send a frame. We will receive it immediately because we are in the lookback mode.
	n, err := can.SendFrame(&sendFrame)
	if err != nil {
		fmt.Println(n, err)
	}
	// Start a echo goroutine.
	wg.Add(1)
	go Echoroutine(can)

	// Wait 1 minute for CAN echo test.
	time.Sleep(1 * time.Minute)
	// Close the CAN.
	can.Close()
	// After the close operation, can.RcvFrame() will return an error, so we can exit from Echoroutine().
	// Wait until Echoroutine() done.
	wg.Wait()
}

func Echoroutine(can *socketcan.Can) {
	var err error = nil
	var frame canframe.Frame
	for err == nil {
		// can.RcvFrame() will block until new datas arrived.
		frame, err = can.RcvFrame()
		if lookback {
			lookback = false
			can.SetLoopback(lookback)
		}

		fmt.Println(frame)
		n, err := can.SendFrame(&frame)
		if err != nil {
			fmt.Println(n, err)
		}
	}
	fmt.Println("Echoroutine Exit:", err)
	wg.Done()
}

Some codes were referenced: