Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


J-Link API Wrapper 🔌

Minimal C wrapper + Go bindings for the SEGGER J-Link API.
Cross‑platform: Windows & Linux.

Uses Zig to build a tiny C wrapper, making J-Link API calls accessible from Go without CGO headaches.


1. What This Is 📌

A very small, low‑level wrapper around the official J-Link API:

  • Thin C layer compiled with Zig
  • Go bindings on top
  • Dynamic loading of the SEGGER shared library
  • No abstractions, no magic — just direct access to the API

Perfect if you want to call J-Link functions from Go with minimal overhead.


2. Requirements 📦

  • SEGGER J-Link Software installed
  • Shared library available at runtime:
    • Windows: JLink_x64.dll or JLinkARM.dll
    • Linux: libjlinkarm.so
  • Zig compiler (to build the C wrapper)
  • Go toolchain

3. Building 🛠️

1. Install dependencies

  1. Install the official SEGGER J-Link package
    (download from the SEGGER website).

  2. Ensure the shared library is discoverable:

    • place it next to your executable
  3. Install MSYS2 (Windows)
    (instructions available at the MSYS2 website).

  4. Install the Go toolchain
    (available at the Go downloads page).

  5. Install the Zig compiler
    (download from the Zig website).


2. Build the project

Clone example project (same as module)

git clone https://github.com/SimonTechv/gojlink.git

cd gojlink

Linux ARM64 (cross‑compile) e.x. Raspberry PI5

CC="zig cc -target aarch64-linux-gnu" \
CGO_ENABLED=1 \
GOOS=linux \
GOARCH=arm64 \
go build .

Windows AMD64 (native)

CC="zig cc" \
CGO_ENABLED=1 \
GOOS=windows \
GOARCH=amd64 \
go build .

4. Example ✏️

package main

import (
    "fmt"
    "time"

    "github.com/SimonTechv/gojlink/jlink"
)

var JLinkEmuSerialNumber uint32 = 123456 // Put your emulator SN here

func main() {
    // Load the J-Link shared library (.dll / .so)
    emu, err := jlink.APIInit()
    if err != nil {
        return
    }

    defer func() {
        emu.Close()
        time.Sleep(100 * time.Millisecond)

        _ = emu.APIClose() // Unload the shared library
        if err != nil {
            fmt.Printf("Error: %s", err.Error())
        }
    }()

    fmt.Println("Select EMU")
    if err = emu.SelectByUSBSN(JLinkEmuSerialNumber); err != nil {
        return
    }

    fmt.Println("Connect to EMU")
    if err = emu.Open(); err != nil {
        return
    }

    fmt.Println("Select IF")
    if err = emu.TIFSelect(jlink.SWD); err != nil {
        return
    }

    fmt.Println("Select target")
    if err = emu.ExecCommand("Device = STM32F103C8"); err != nil {
        return
    }

    fmt.Println("Connect to target")
    if err = emu.Connect(); err != nil {
        return
    }

    // Simple read/write test (RAM on STM32)
    fmt.Println("Write to RAM: 0xFAFAFAFA")
    if err = emu.WriteU32(0x20000000, 0xFAFAFAFA); err != nil {
        return
    }

    mem, err := emu.ReadMemU32(0x20000000, 1)
    if err != nil {
        return
    }

    fmt.Printf("Read from RAM: 0x%X\n", mem[0])
}

About

Painless CGO bindings for JLinkDLL

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages