Skip to content

Conversation

@luoliwoshang
Copy link
Member

@luoliwoshang luoliwoshang commented Sep 16, 2025

Overview

This PR migrates TinyGo's machine package to the GoPlus/LLGo environment, providing complete embedded hardware abstraction layer support for LLGo.

Current Status: Initial migration phase. The primary goal is to enable llgo build to execute correctly and pass compilation validation. Many functions that require compiler support currently use placeholder implementations (panic), to be gradually implemented as LLGo compiler features are enhanced.

Major Changes

1. Code Synchronization

1.1 Sync TinyGo Machine Code

  • Source Version: TinyGo v0.39.0
  • Source Path: tinygo/src/machine
  • Target Path: lib/emb/machine

1.2 Sync TinyGo Runtime Interrupt Code

  • Source Version: TinyGo v0.39.0
  • Source Path: tinygo/src/runtime/interrupt
  • Target Path: lib/emb/runtime/interrupt
  • Purpose: Temporary placeholder implementation to ensure compilation passes

1.3 Sync Internal Packages

Need to migrate the following internal packages:

  • "internal/binary" - from tinygo/src/internal to lib/emb/internal
  • "internal/bytealg" - from tinygo/src/internal to lib/emb/internal
  • "internal/itoa" - from Go v1.24.0 standard library to lib/emb/internal

2. LLGo Environment Adaptation

2.1 External Symbol Mapping

2.1.1 Machine Package External Symbol Mapping

Convert TinyGo's //export directives to //go:linkname mappings:

// TinyGo original approach:
//export __tinygo_pwm_configure
func pwmConfigure(instance int32, frequency float64, top uint32)

// Changed to LLGo mapping approach:
//go:linkname pwmConfigure __llgo_pwm_configure
func pwmConfigure(instance int32, frequency float64, top uint32)

Mapping Rule: __tinygo_*__llgo_*

Functions in emb/machine/machine_generic.go that apply this mapping rule include:

  • gpioConfigure

  • gpioSet

  • gpioGet

  • pwmConfigure

  • pwmChannelConfigure

  • pwmChannelSet

  • spiConfigure

  • spiTransfer

  • spiTX

  • adcRead

  • uartConfigure

  • uartRead

  • uartWrite

  • TODO: Subsequently need to implement concrete mappings for these external symbols in LLGo runtime to provide real hardware abstraction layer functionality.

2.1.2 Interrupt Package External Symbol Mapping

The checkpointJump() function in emb/runtime/interrupt/checkpoint.go:

  • Originally used //export tinygo_checkpointJump to declare external function
  • Changed to use //go:linkname checkpointJump __llgo_checkpointJump mapping to LLGo external symbol

2.2 Compiler Directive Placeholders

2.2.1 Interrupt Creation Mechanism

Interrupt creation functions in emb/runtime/interrupt/interrupt.go file require compiler support:

New() Interrupt Creation Function: func New(id int, handler func(Interrupt)) Interrupt

  • Needs LLGo compiler to implement interrupt handling mechanism

  • Used for creating and registering interrupt handlers

  • TODO: Need to implement interrupt creation and registration mechanism in LLGo compiler.

2.2.2 Interrupt Checkpoint Mechanism

Checkpoint-related functions in emb/runtime/interrupt/checkpoint.go file require compiler support:

Save() Compiler Intrinsic Function: func (c *Checkpoint) Save() bool

  • This is a compiler intrinsic function that needs to be implemented in LLGo compiler

  • Functions similar to setjmp, saves execution state and supports dual return value mechanism

  • TODO: Need to implement compiler intrinsic function support in LLGo compiler.

2.3 Import Path Adaptation

Adapt all related package import paths to conform with GoPlus module structure:

Device Package Path Adaptation:

  • "device/stm32""github.com/goplus/lib/emb/device/stm32"
  • "device/*""github.com/goplus/lib/emb/device/*"

Machine Package Path Adaptation:

  • "machine""github.com/goplus/lib/emb/machine"

Runtime Package Path Adaptation:

  • "runtime/interrupt""github.com/goplus/lib/emb/runtime/interrupt"
  • "runtime/volatile""github.com/goplus/lib/emb/runtime/volatile"

2.4 instead cgo

0a0c7c2

2.5 some runtime-function

emb/machine/machine_avr.go

// linked from runtime.adjustMonotonicTimer
// TODO(zzy): implement at runtime
func adjustMonotonicTimer() {}

// TODO(zzy): implement at runtime
// linked from runtime.initMonotonicTimer
func initMonotonicTimer() {}

@niupilot
Copy link

niupilot bot commented Sep 16, 2025

PR Review: Embedded Device Support Implementation

Reviewing PR #19 - Adding embedded device support for ARM/AVR microcontrollers

Tasks:

  • Analyze overall PR structure and scope
  • Review validation scripts and CI workflows
  • Examine core device implementation files (ARM/AVR)
  • Check for empty files and potential issues
  • Verify code quality and best practices
  • Assess documentation consistency
  • Provide comprehensive feedback and recommendations

Executive Summary

This PR adds extensive embedded device support (~19,972 lines) for ARM, AVR, and other microcontroller families. The implementation includes device-specific register definitions, interrupt handlers, and validation infrastructure.

Strengths

1. Comprehensive Device Coverage

  • 400+ device files spanning ARM (Cortex-M), AVR (ATmega/ATtiny), ESP32, STM32, and more
  • Consistent structure across device families with standardized register definitions
  • Complete interrupt vectors for each device with proper linkage

2. Robust Validation Infrastructure

  • Sophisticated validation script (.github/scripts/validate_device_packages.sh)
  • Comprehensive CI integration with LLGO target validation
  • LLGO compatibility checks with proper ignore lists for unsupported targets

3. Code Quality

  • Generated code markers clearly identifying auto-generated files
  • Proper Go build constraints (//go:build avr && atmega328p)
  • Volatile register access using appropriate types
  • Memory-mapped I/O with correct unsafe pointer usage

⚠️ Areas of Concern

1. Critical Implementation Issues

Missing Interrupt Handler Implementation emb/device/arm/arm.go:57

func callHandlers(num int){
    // TODO: implement interrupt handler dispatch mechanism
}
  • Impact: All interrupt handlers are non-functional stubs
  • Risk: Runtime failures when interrupts fire
  • Recommendation: Implement proper LLGO runtime integration

Incomplete System Call Support emb/device/arm/arm.go:75-107

func SVCall0(num uintptr) uintptr {
    // TODO(zzy): implement system call (SVCall) functionality
    panic("TODO: SVCall0")
}
  • Impact: ARM Cortex-M system calls will panic
  • Risk: Application crashes on SVC instructions

2. Architecture & Design Issues

Inconsistent Assembly Linkage

  • emb/device/asm.go and emb/device/arm/arm.go have duplicate assembly functions
  • Different linkage patterns: //llgo:link vs //go:linkname
  • Potential conflicts between implementations

Incomplete Interrupt Integration

  • Missing connection between LLGO runtime and callHandlers
  • Note states "runtime/interrupt.callHandlers is not yet implemented in LLGO"
  • Gap between device definitions and runtime support

3. Build System Issues

Empty Device Files

Several AVR device files exist but are empty (0 bytes), suggesting incomplete generation

CI Workflow Concerns .github/workflows/validate-device-packages.yml:21

wget https://github.com/luoliwoshang/llgo/releases/download/v0.0.1-clang-withemb-runtime/llgo0.0.1-clang-withemb-runtime.linux-amd64.tar.gz
  • Security risk: Downloading binaries from external source
  • Maintenance burden: Manual version management
  • Reliability: Potential for download failures

🔧 Recommendations

High Priority (Blocking)

  1. Implement interrupt handler dispatch in LLGO runtime
  2. Complete ARM system call implementation or provide alternative
  3. Fix empty AVR device files - complete code generation
  4. Resolve assembly function conflicts between device/asm.go and arm/arm.go

Medium Priority

  1. Secure CI dependencies - consider building LLGO from source or verifying checksums
  2. Add runtime integration tests beyond compilation validation
  3. Document incomplete features clearly in README/docs

Low Priority

  1. Standardize comment formatting across device files
  2. Add device-specific examples for common use cases
  3. Consider device family organization (separate packages vs single namespace)

🏗️ Architecture Assessment

Well-Designed Aspects

  • Memory-mapped register abstraction using volatile types
  • Build constraint organization allowing selective compilation
  • Validation framework ensuring LLGO target compatibility

Areas for Improvement

  • Runtime integration layer needs completion
  • Error handling strategy for incomplete features
  • Documentation of LLGO-specific limitations

📋 Summary

This PR provides a solid foundation for embedded device support but has critical implementation gaps that must be addressed:

  • 70% of functionality is well-implemented (device definitions, registers)
  • 30% requires completion (runtime integration, system calls)
  • Architecture is sound but needs runtime support

Recommendation: Conditional approval pending completion of interrupt handler implementation and system call support. The validation infrastructure and device definitions are excellent, but the runtime gaps make this unsuitable for production use without additional work.


👉 Want me to re-run this review? Just type /review in the comments! For more usage examples, visit CodeAgent GitHub Repository.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @luoliwoshang, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the project's hardware abstraction capabilities by introducing a structured emb/device package. It provides foundational support for various ARM and AVR microcontrollers, enabling more robust bare-metal programming with LLGO. A new validation script has also been added to streamline testing of these new device integrations.

Highlights

  • New Device Package Structure: Introduced a new comprehensive structure under emb/device to house hardware abstraction layers for various microcontroller architectures and specific devices.
  • ARM and ARM64 Support: Added initial hardware register definitions and core functionalities for ARM Cortex-M (including System Control Block, SysTick, and Semihosting) and ARM64 architectures.
  • Extensive AVR Microcontroller Definitions: Included detailed peripheral and interrupt definitions for a wide range of AVR microcontrollers, such as AT90CAN, AT90PWM, and AT90USB series.
  • Automated Device Package Validation: Implemented a new shell script (validate_device_packages.sh) to automatically test the compilation of these device-specific packages against different LLGO targets, ensuring compatibility and correctness.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new embed:machine package, providing low-level hardware access for various microcontrollers, including ARM, ARM64, and a wide range of AVR devices. A validation script is also added to test the compilation of these device packages. The overall structure is sound, but I've identified a couple of issues in the validation script that should be addressed to improve its robustness and efficiency. The Go files, being mostly definitions and stubs, appear to be correctly structured for their purpose.

@luoliwoshang luoliwoshang changed the title embed:machine pkg embed:machine pkg Sep 16, 2025
@luoliwoshang luoliwoshang force-pushed the task3/machine branch 4 times, most recently from 75d4b7a to d2828f2 Compare September 19, 2025 03:15
@luoliwoshang
Copy link
Member Author

@xushiwei

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant