LLCOM Documentation

repository·master·Indexed 22 days ago

https://github.com/chenxuuu/llcom

A high-freedom serial port debugging tool featuring Lua script support for data pre-processing and automated testing. It includes task/coroutine management, C# interop via the CS namespace, and integrated network testing for TCP, UDP, and MQTT. The tool also provides serial_monitor.dll, a Windows x64 library that uses inline hooking to intercept serial I/O calls in target processes.

Tokens
5.5K
Snippets
12
Records
30
Agent score
78%

What's inside LLCOM

  1. Manage tasks with sys.taskInit and sys.wait

    master

    Use sys.taskInit to create a new task thread. Note that sys.taskInit should be called at the end of the module to register task functions, and the module should be imported in main.lua. Once a task is running, you can use sys.wait to introduce delays.

    Note: sys.wait and sys.waitUntil can only be used within task functions.

  2. Automate serial communication with independent Lua scripts

    master

    LLCOM features a dedicated Lua debugging area where you can run independent scripts. These scripts have access to timers, coroutines (tasks), and can interact with the serial port and the system. This allows for full automation of serial testing.

    Key capabilities:

    • Registering receive functions: Define uartReceive to handle incoming data.
    • Task Management: Use sys.taskInit to create asynchronous tasks.
    • Message Passing: Use sys.publish and sys.waitUntil to communicate between tasks.
    • Timers: Use sys.timerLoopStart for periodic execution.
    • C# Interop: Access .NET classes via the CS namespace to perform advanced operations like HTTP requests.
  3. Use the sys module for coroutine scheduling

    master
    The sys module provides a Luat coroutine scheduling framework for managing tasks, timers, and message subscriptions. It allows for asynchronous-style programming within a Lua environment, supporting task delays, conditional waiting, and event-driven callbacks.
  4. How serial_monitor.dll works (Architecture)

    master

    The serial_monitor.dll works by injecting a hook into a target process to intercept serial I/O calls.

    Workflow

    1. Initialization: llcom.exe calls MonitorComm. The DLL creates a named pipe \\.\pipe\llcom_smv2_<our_pid> and writes the pipe name to shared memory Local\llcom_smv2_session.
    2. Injection: The DLL extracts serial_monitor_hook.dll (which is embedded inside the main DLL) to %TEMP%\llcom_smv2\ and injects it into the target process using CreateRemoteThread + LoadLibraryW.
    3. Hooking: The injected serial_monitor_hook.dll installs inline hooks on kernel32: CreateFileW/A, ReadFile, WriteFile, and CloseHandle. It detects COM ports by checking for paths like \\.\COMx or \Device\Serialx.
    4. Data Capture: Whenever the target process performs a read or write on a COM handle, the hook writes a Udata packet to the named pipe.
    5. Callback: A worker thread in serial_monitor.dll polls the pipe and executes the C# callback for every Udata packet received.
  5. Understand the differences between script execution areas

    master

    LLCOM provides different Lua execution environments with varying capabilities:

    1. Sending Processing Scripts (发送处理脚本): Used for pre-processing data before it is sent.
      • Restrictions: You cannot use timers/tasks or log/print interfaces in this area.
    2. Independent Lua Scripts (独立的Lua脚本): Used for automatic serial port transceiver processing. This environment has full access to timers, tasks, and logging.

    The Lua environment is version 5.3 and uses the xlua framework, allowing direct calls to C# underlying functions.

  6. Download and contribute Lua scripts

    master

    You can download various Lua scripts from the scripts/ directory to extend the functionality of LLCOM.

    Users are encouraged to share their own Lua scripts. You can contribute by:

    1. Submitting a Pull Request directly to the scripts/ folder.
    2. Opening an Issue if you are unable to submit a Pull Request, and the maintainer will assist in adding your script.
  7. Install LLCOM

    master

    LLCOM can be installed via the Microsoft Store or downloaded as a portable executable. For development or testing, CI snapshots are also available via GitHub Actions.

    • Microsoft Store: Search for LLCOM in the Microsoft Store.
    • Portable Version: Download the .zip file for a portable experience.
    • CI Snapshots: Use the nightly builds for the latest features.
  8. Process outgoing data with Lua scripts

    master

    You can use Lua scripts to transform data before it is sent through the serial port. These scripts also work with the Quick send bar. The script should return the processed data.

    Common patterns:

    • Append a suffix (e.g., \r\n).
    • Convert input to HEX values using uartData:fromHex().
    • Transform strings into JSON objects using a JSON library.
    -- Append newline
    return uartData.."\r\n"
    
    -- Send HEX values (e.g., converts '30313233' to '0123')
    return uartData:fromHex()
    
    -- Transform comma-separated string to JSON
    json = require("JSON")
    t = uartData:split(",")
    return json:encode({
        key1 = t[1],
        key2 = t[2],
        key3 = t[3],
    })
  9. Build serial_monitor.dll

    master

    To build the serial_monitor.dll for use in llcom, you can use the provided PowerShell script or perform a manual build. The project requires the Rust toolchain (stable ≥ 1.75 or nightly) and the x86_64-pc-windows-msvc target.

    Prerequisites

    • Rust toolchain (stable ≥ 1.75 or nightly)
    • MSVC target: rustup target add x86_64-pc-windows-msvc
    • Visual Studio Build Tools (MSVC linker)

    Run the build script to compile the DLL and automatically copy it to the llcom/costura64/ directory.

    cd serial_monitor_rs
    .\build.ps1

    Option 2: Manual build

    If building manually, you must build the serial_monitor_hook crate first, as the serial_monitor crate embeds the hook DLL during its build process.

    cd serial_monitor_rs
    # 1. Build the Hook DLL
    cargo build --release -p serial_monitor_hook --target x86_64-pc-windows-msvc
    
    # 2. Build the main DLL
    cargo build --release -p serial_monitor --target x86_64-pc-windows-msvc

    Output location: target/x86_64-pc-windows-msvc/release/serial_monitor.dll

    .
    cd serial_monitor_rs
    .\build.ps1
  10. Pre-process outgoing data with Lua scripts

    master

    You can use Lua scripts to transform data before it is sent over the serial port. This applies to both the main send area and the right-side quick-send bar. The script must return the processed data.

    Common patterns:

    • Append newline: return uartData.."\r\n"
    • Convert Hex to String: Use uartData:fromHex() to convert a hex string like 30313233 into 0123.
    • JSON Encoding: Use a JSON library to wrap comma-separated values into a JSON object.
    -- Append newline
    return uartData.."\r\n"
    
    -- Convert hex string to actual bytes
    return uartData:fromHex()
    
    -- Convert comma-separated string to JSON
    json = require("JSON")
    t = uartData:split(",")
    return json:encode({
        key1 = t[1],
        key2 = t[2],
        key3 = t[3],
    })
  11. Run independent Lua scripts for automated UART processing

    master

    LLCOM allows you to run independent Lua scripts that can automatically handle UART communication using a task-based model (based on LUAT TASK).

    Key capabilities:

    • uartReceive: Register a function to handle incoming serial data.
    • sys.publish / sys.waitUntil: Use a message-passing pattern to communicate between different parts of your script.
    • sys.taskInit: Create asynchronous tasks for loops or waiting for specific events.
    • sys.timerLoopStart: Run a function on a periodic timer.
    • apiSendUartData: Send data from within the script.
    • xlua: Access C# classes directly via the CS namespace for advanced tasks like HTTP requests.
    -- Register serial port receiver function
    uartReceive = function (data)
        log.info("uartReceive",data)
        sys.publish("UART",data)--publish message
    end
    
    -- Create a task, wait for message
    sys.taskInit(function()
        while true do
            local _,udata = sys.waitUntil("UART")--wait for message
            log.info("task waitUntil",udata)
            local sendResult = apiSendUartData("ok!")--send uart data
            log.info("uart send",sendResult)
        end
    end)
    
    -- Create a task, sleep 1000ms and loop
    sys.taskInit(function()
        while true do
            sys.wait(1000)--wait 1000ms
            log.info("task wait",os.time())
        end
    end)
    
    -- 1000ms loop timer
    sys.timerLoopStart(log.info,1000,"timer test")
  12. How the serial monitoring injection works

    master

    The serial_monitor.dll implements a multi-step injection and communication architecture:

    1. Setup: Creates a named-pipe server and a shared-memory segment named Local\llcom_smv2_session to pass the pipe name to the hook.
    2. Extraction: Extracts the embedded serial_monitor_hook.dll to %TEMP%\llcom_smv2\.
    3. Injection: Uses CreateRemoteThread and LoadLibraryW to inject the hook DLL into the target process (identified by Pid).
    4. Communication: The injected hook writes Udata messages to the named pipe. A worker thread in the host process reads these messages and executes the provided CallbackFn.
    5. Cleanup: UnMonitorComm triggers the worker thread to exit and uses FreeLibrary via a remote thread to eject the hook from the target process.