### Configure Installation Rules Source: https://github.com/ascress/flusbserial/blob/master/example/windows/CMakeLists.txt Defines installation paths and rules for the executable, Flutter assets, and native libraries. ```cmake # === Installation === # Support files are copied into place next to the executable, so that it can # run in place. This is done instead of making a separate bundle (as on Linux) # so that building and running from within Visual Studio will work. set(BUILD_BUNDLE_DIR "$") # Make the "install" step default, as it's required to run. set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() # Copy the native assets provided by the build.dart from all packages. set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") install(DIRECTORY "${NATIVE_ASSETS_DIR}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) # Install the AOT library on non-Debug builds only. install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) ``` -------------------------------- ### Install libusb on macOS Source: https://github.com/ascress/flusbserial/blob/master/README.md Command to install libusb using Homebrew. ```bash brew install libusb ``` -------------------------------- ### Install libusb on Linux Source: https://github.com/ascress/flusbserial/blob/master/README.md Commands to install the libusb dependency on Ubuntu/Debian and Fedora/RHEL systems. ```bash # Ubuntu / Debian sudo apt-get install libusb-1.0-0 # Fedora / RHEL sudo dnf install libusb1 ``` -------------------------------- ### Read Data from USB Serial Device Source: https://context7.com/ascress/flusbserial/llms.txt Read bytes from the USB serial device using bulk transfer. Specify the number of bytes to read and a timeout in milliseconds. Includes examples for different timeout values and data conversion. ```dart import 'dart:typed_data'; import 'dart:convert'; import 'package:flusbserial/flusbserial.dart'; Future readDataExample() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); UsbDevice targetDevice = devices.firstWhere( (d) => d.vendorId == 0x10C4 && d.productId == 0xEA60, ); UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice(targetDevice); await serialDevice!.open(); await serialDevice.setBaudRate(115200); await serialDevice.setDataBits(UsbSerialInterface.dataBits8); await serialDevice.setStopBits(UsbSerialInterface.stopBits1); await serialDevice.setParity(UsbSerialInterface.parityNone); try { // Read up to 64 bytes with 1000ms timeout Uint8List receivedData = await serialDevice.read(64, 1000); print('Received ${receivedData.length} bytes'); print('Raw data: $receivedData'); // Convert to string if ASCII/UTF-8 data String textData = utf8.decode(receivedData, allowMalformed: true); print('As text: $textData'); // Read with shorter timeout for polling Uint8List quickRead = await serialDevice.read(32, 100); print('Quick read: ${quickRead.length} bytes'); } catch (e) { print('Read error: $e'); } await serialDevice.close(); UsbSerialDevice.exit(); } ``` -------------------------------- ### Open and configure device Source: https://github.com/ascress/flusbserial/blob/master/README.md Open the device connection and set communication parameters like baud rate and parity. ```dart await mDevice.open(); await mDevice.setBaudRate(1000000); await mDevice.setDataBits(UsbSerialInterface.dataBits8); await mDevice.setStopBits(UsbSerialInterface.stopBits1); await mDevice.setParity(UsbSerialInterface.parityNone); ``` -------------------------------- ### Instantiate UsbSerialDevice Source: https://github.com/ascress/flusbserial/blob/master/README.md Create a device instance using auto-detection, specific interface, or specific driver type. ```dart UsbDevice? device; ... // Auto-detect interface UsbSerialDevice? mDevice = UsbSerialDevice.createDevice(device); // Specific interface UsbSerialDevice? mDevice = UsbSerialDevice.createDevice(device, interfaceId: 0); // Specific driver (eg:- CDC ACM) UsbSerialDevice? mDevice = UsbSerialDevice.createDevice(device, type: UsbSerialDevice.cdc); ``` -------------------------------- ### Configure CMake Project and Build Settings Source: https://github.com/ascress/flusbserial/blob/master/example/windows/CMakeLists.txt Sets up the project name, CMake policies, and custom build configurations for Debug, Profile, and Release modes. ```cmake cmake_minimum_required(VERSION 3.14) project(flusbserial_example LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "flusbserial_example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. cmake_policy(VERSION 3.14...3.25) # Define build configuration option. get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(IS_MULTICONFIG) set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" CACHE STRING "" FORCE) else() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() endif() # Define settings for the Profile build mode. set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") # Use Unicode for all projects. add_definitions(-DUNICODE -D_UNICODE) ``` -------------------------------- ### Initialize plugin Source: https://github.com/ascress/flusbserial/blob/master/README.md Initialize the plugin before performing operations. ```dart UsbSerialDevice.init(); ``` -------------------------------- ### Configure Linux udev rules Source: https://github.com/ascress/flusbserial/blob/master/README.md Udev rule configuration to allow non-root access to USB devices. ```text SUBSYSTEM=="usb|tty", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="xxxx", MODE="666" ``` -------------------------------- ### Initialize and Cleanup Flusbserial Source: https://context7.com/ascress/flusbserial/llms.txt Initialize the libusb library before any USB operations and clean up resources when done. This must be called once at application startup. ```dart import 'package:flusbserial/flusbserial.dart'; void main() { // Initialize libusb - required before any USB operations UsbSerialDevice.init(); // Your application code here... // Clean up when done (typically on app exit) UsbSerialDevice.exit(); } ``` -------------------------------- ### Include Flutter and Plugin Build Rules Source: https://github.com/ascress/flusbserial/blob/master/example/windows/CMakeLists.txt Includes the necessary Flutter managed directories and generated plugin build rules. ```cmake # Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) # Application build; see runner/CMakeLists.txt. add_subdirectory("runner") # Enable the test target. set(include_flusbserial_tests TRUE) # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) ``` -------------------------------- ### Create UsbSerialDevice Instance Source: https://context7.com/ascress/flusbserial/llms.txt Create a UsbSerialDevice instance for a specific USB device. The factory method auto-detects the driver type or allows explicit specification. Ensure UsbSerialDevice.init() is called prior to creating a device instance. ```dart import 'package:flusbserial/flusbserial.dart'; Future createDeviceExample() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); UsbDevice? targetDevice; // Find a specific device by vendor/product ID (CP210x example) for (var device in devices) { if (device.vendorId == 0x10C4 && device.productId == 0xEA60) { targetDevice = device; break; } } if (targetDevice == null) { print('Device not found'); return; } // Auto-detect driver type (recommended) UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice(targetDevice); // Or specify interface ID explicitly UsbSerialDevice? serialDeviceWithInterface = UsbSerialDevice.createDevice( targetDevice, interfaceId: 0, ); // Or force a specific driver type UsbSerialDevice? cp210xDevice = UsbSerialDevice.createDevice( targetDevice, type: UsbSerialDevice.cp210x, // Options: cp210x, ch34x, cdc ); // Driver type constants print('Supported drivers:'); print(' CDC ACM: ${UsbSerialDevice.cdc}'); // 'CDC' print(' CP210x: ${UsbSerialDevice.cp210x}'); // 'CP210x' print(' CH34x: ${UsbSerialDevice.ch34x}'); // 'CH34x' } ``` -------------------------------- ### List Connected USB Devices Source: https://context7.com/ascress/flusbserial/llms.txt Enumerate all USB devices connected to the system. Returns a list of UsbDevice objects with vendor ID, product ID, and configuration count. Ensure UsbSerialDevice.init() is called before listing devices. ```dart import 'package:flusbserial/flusbserial.dart'; Future listConnectedDevices() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); for (var device in devices) { print('Device found:'); print(' Identifier: ${device.identifier}'); print(' Vendor ID: 0x${device.vendorId.toRadixString(16).toUpperCase()}'); print(' Product ID: 0x${device.productId.toRadixString(16).toUpperCase()}'); print(' Configuration Count: ${device.configurationCount}'); } // Example output: // Device found: // Identifier: 5 // Vendor ID: 0x10C4 // Product ID: 0xEA60 // Configuration Count: 1 } ``` -------------------------------- ### CMakeLists.txt Configuration for Flusbserial Source: https://github.com/ascress/flusbserial/blob/master/linux/CMakeLists.txt Defines the project name, sets the plugin name, and adds the shared library for the flusbserial plugin. It also applies standard settings and configures visibility and compile definitions. ```cmake cmake_minimum_required(VERSION 3.14) set(PROJECT_NAME "flusbserial") project(${PROJECT_NAME} LANGUAGES CXX) # This value is used when generating builds using this plugin, so it must # not be changed set(PLUGIN_NAME "flusbserial_plugin") add_library(${PLUGIN_NAME} SHARED "fl_usb_serial_plugin.cc" ) apply_standard_settings(${PLUGIN_NAME}) set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden) target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) target_include_directories(${PLUGIN_NAME} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) ``` -------------------------------- ### Find and check GTK, GLIB, and GIO modules in CMake Source: https://github.com/ascress/flusbserial/blob/master/example/linux/flutter/CMakeLists.txt This snippet uses PkgConfig to find and check for the required GTK, GLIB, and GIO development libraries. It ensures these system-level dependencies are available before proceeding with the build. The IMPORTED_TARGET option makes the found libraries available as CMake targets. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) ``` -------------------------------- ### Complete Bidirectional USB Serial Communication Source: https://context7.com/ascress/flusbserial/llms.txt Demonstrates full USB serial communication, including device discovery, opening a connection, configuring serial parameters (baud rate, data bits, stop bits, parity), sending commands, reading responses, and closing the device. Ensure libusb is initialized and kernel drivers are detached if necessary. ```dart import 'dart:typed_data'; import 'dart:convert'; import 'package:flusbserial/flusbserial.dart'; Future completeSerialCommunication() async { // Initialize libusb UsbSerialDevice.init(); // Enable kernel driver detachment for Linux UsbSerialDevice.setAutoDetachKernelDriver(true); try { // Discover devices List devices = await UsbSerialDevice.listDevices(); print('Found ${devices.length} USB devices'); // Find CP210x device (Silicon Labs) UsbDevice? targetDevice; for (var device in devices) { if (device.vendorId == 0x10C4 && device.productId == 0xEA60) { targetDevice = device; print('Found CP210x device: ${device.identifier}'); break; } } if (targetDevice == null) { print('No compatible device found'); return; } // Create serial device with auto-detection UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice( targetDevice, interfaceId: 0, ); if (serialDevice == null) { print('Failed to create serial device'); return; } // Open connection bool opened = await serialDevice.open(); if (!opened) { print('Failed to open device'); return; } print('Device opened successfully'); // Configure serial port: 1000000 baud, 8N1 await serialDevice.setBaudRate(1000000); await serialDevice.setDataBits(UsbSerialInterface.dataBits8); await serialDevice.setStopBits(UsbSerialInterface.stopBits1); await serialDevice.setParity(UsbSerialInterface.parityNone); print('Serial port configured'); // Send a command Uint8List command = Uint8List.fromList([0x0B, 0x05]); // Example command bytes int bytesWritten = await serialDevice.write(command, 500); print('Sent $bytesWritten bytes'); // Read response Uint8List response = await serialDevice.read(64, 1000); print('Received ${response.length} bytes: $response'); // Decode as string if applicable String responseText = utf8.decode(response, allowMalformed: true); print('Response text: $responseText'); // Close device await serialDevice.close(); print('Device closed'); } catch (e) { print('Error: $e'); } finally { UsbSerialDevice.exit(); } } void main() async { await completeSerialCommunication(); } ``` -------------------------------- ### List available devices Source: https://github.com/ascress/flusbserial/blob/master/README.md Retrieve a list of connected USB devices. ```dart List devices = await UsbSerialDevice.listDevices(); ``` -------------------------------- ### Configure Serial Port Parameters Source: https://context7.com/ascress/flusbserial/llms.txt Set baud rate, data bits, stop bits, and parity for serial communication. These settings must be applied after opening the device. ```dart import 'package:flusbserial/flusbserial.dart'; Future configureSerialPort() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); UsbDevice targetDevice = devices.firstWhere( (d) => d.vendorId == 0x10C4 && d.productId == 0xEA60, ); UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice(targetDevice); await serialDevice!.open(); // Set baud rate (bits per second) await serialDevice.setBaudRate(115200); // Common rates: 9600, 19200, 38400, 57600, 115200, 1000000 // Set data bits (5, 6, 7, or 8) await serialDevice.setDataBits(UsbSerialInterface.dataBits8); // Available: dataBits5, dataBits6, dataBits7, dataBits8 // Set stop bits await serialDevice.setStopBits(UsbSerialInterface.stopBits1); // Available: stopBits1, stopBits1_5, stopBits2 // Set parity await serialDevice.setParity(UsbSerialInterface.parityNone); // Available: parityNone, parityOdd, parityEven, parityMark, paritySpace print('Serial port configured: 115200 8N1'); await serialDevice.close(); UsbSerialDevice.exit(); } ``` -------------------------------- ### Add flusbserial dependency Source: https://github.com/ascress/flusbserial/blob/master/README.md Add the package to the pubspec.yaml file. ```yaml dependencies: flusbserial: ``` -------------------------------- ### Configure Flutter Windows Runner Build Source: https://github.com/ascress/flusbserial/blob/master/example/windows/runner/CMakeLists.txt Defines the executable target, applies standard build settings, sets preprocessor definitions, and links necessary libraries for a Flutter Windows application. ```cmake cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Add preprocessor definitions for the build version. target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") # Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Flutter Windows CMake Build Configuration Source: https://github.com/ascress/flusbserial/blob/master/example/windows/flutter/CMakeLists.txt This script defines the build environment, including library paths, wrapper sources, and the custom command to invoke the Flutter tool backend. ```cmake # This file controls Flutter-level build steps. It should not be edited. cmake_minimum_required(VERSION 3.14) set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") # Configuration provided via flutter tool. include(${EPHEMERAL_DIR}/generated_config.cmake) # TODO: Move the rest of this into files in ephemeral. See # https://github.com/flutter/flutter/issues/57146. set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") # Set fallback configurations for older versions of the flutter tool. if (NOT DEFINED FLUTTER_TARGET_PLATFORM) set(FLUTTER_TARGET_PLATFORM "windows-x64") endif() # === Flutter Library === set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "flutter_export.h" "flutter_windows.h" "flutter_messenger.h" "flutter_plugin_registrar.h" "flutter_texture_registrar.h" ) list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") add_dependencies(flutter flutter_assemble) # === Wrapper === list(APPEND CPP_WRAPPER_SOURCES_CORE "core_implementations.cc" "standard_codec.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_PLUGIN "plugin_registrar.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_APP "flutter_engine.cc" "flutter_view_controller.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") # Wrapper sources needed for a plugin. add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ) apply_standard_settings(flutter_wrapper_plugin) set_target_properties(flutter_wrapper_plugin PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(flutter_wrapper_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) target_include_directories(flutter_wrapper_plugin PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_plugin flutter_assemble) # Wrapper sources needed for the runner. add_library(flutter_wrapper_app STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_APP} ) apply_standard_settings(flutter_wrapper_app) target_link_libraries(flutter_wrapper_app PUBLIC flutter) target_include_directories(flutter_wrapper_app PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_app flutter_assemble) # === Flutter tool backend === # _phony_ is a non-existent file to force this command to run every time, # since currently there's no way to get a full input/output list from the # flutter tool. set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ${PHONY_OUTPUT} COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ) ``` -------------------------------- ### Import flusbserial Source: https://github.com/ascress/flusbserial/blob/master/README.md Import the library into your Dart code. ```dart import 'package:flusbserial/flusbserial.dart'; ``` -------------------------------- ### Open and Close USB Device Connections Source: https://context7.com/ascress/flusbserial/llms.txt Open a device connection to claim the USB interface and prepare for communication. Always close the device when finished to release resources. Ensure UsbSerialDevice.init() is called before opening and UsbSerialDevice.exit() is called after closing. ```dart import 'package:flusbserial/flusbserial.dart'; Future openCloseExample() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); UsbDevice targetDevice = devices.firstWhere( (d) => d.vendorId == 0x10C4 && d.productId == 0xEA60, ); UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice(targetDevice); if (serialDevice == null) { print('Failed to create device'); return; } try { // Open the device - claims USB interface bool opened = await serialDevice.open(); if (!opened) { print('Failed to open device'); return; } print('Device opened successfully'); // Perform serial operations here... } finally { // Always close the device to release resources await serialDevice.close(); print('Device closed'); } UsbSerialDevice.exit(); } ``` -------------------------------- ### Serial Configuration Constants Reference Source: https://context7.com/ascress/flusbserial/llms.txt Provides a reference for all available serial configuration constants within the UsbSerialInterface class, including data bits, stop bits, parity, and flow control options. Use these constants when configuring the serial port. ```dart import 'package:flusbserial/flusbserial.dart'; void configurationConstantsReference() { // Data Bits print('Data Bits:'); print(' dataBits5 = ${UsbSerialInterface.dataBits5}'); // 5 print(' dataBits6 = ${UsbSerialInterface.dataBits6}'); // 6 print(' dataBits7 = ${UsbSerialInterface.dataBits7}'); // 7 print(' dataBits8 = ${UsbSerialInterface.dataBits8}'); // 8 // Stop Bits print('Stop Bits:'); print(' stopBits1 = ${UsbSerialInterface.stopBits1}'); // 1 print(' stopBits1_5 = ${UsbSerialInterface.stopBits1_5}'); // 3 (1.5 stop bits) print(' stopBits2 = ${UsbSerialInterface.stopBits2}'); // 2 // Parity print('Parity:'); print(' parityNone = ${UsbSerialInterface.parityNone}'); // 0 print(' parityOdd = ${UsbSerialInterface.parityOdd}'); // 1 print(' parityEven = ${UsbSerialInterface.parityEven}'); // 2 print(' parityMark = ${UsbSerialInterface.parityMark}'); // 3 print(' paritySpace = ${UsbSerialInterface.paritySpace}'); // 4 // Flow Control print('Flow Control:'); print(' flowControlOff = ${UsbSerialInterface.flowControlOff}'); // 0 print(' flowControlRtsCts = ${UsbSerialInterface.flowControlRtsCts}'); // 1 print(' flowControlDsrDtr = ${UsbSerialInterface.flowControlDsrDtr}'); // 2 print(' flowControlXonXoff = ${UsbSerialInterface.flowControlXonXoff}');// 3 } ``` -------------------------------- ### Define Executable Target Source: https://github.com/ascress/flusbserial/blob/master/example/linux/runner/CMakeLists.txt Defines the main executable for the application. Source files for the application should be added here. Ensure BINARY_NAME is consistent with the top-level CMakeLists.txt for `flutter run` compatibility. ```cmake cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Add preprocessor definitions for the application ID. add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") # Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Reload Linux udev rules Source: https://github.com/ascress/flusbserial/blob/master/README.md Command to apply new udev rules without rebooting. ```bash sudo udevadm control --reload-rules && sudo udevadm trigger ``` -------------------------------- ### Custom command to build Flutter library and headers in CMake Source: https://github.com/ascress/flusbserial/blob/master/example/linux/flutter/CMakeLists.txt This custom command uses the Flutter tool backend script to generate the Flutter shared library and its header files. The `_phony_` output is a common technique to ensure the command runs on every build. Environment variables like `FLUTTER_TOOL_ENVIRONMENT` and `FLUTTER_ROOT` are used to configure the tool. ```cmake add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/_phony_ COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} VERBATIM ) ``` -------------------------------- ### Configure Flutter library and headers in CMake Source: https://github.com/ascress/flusbserial/blob/master/example/linux/flutter/CMakeLists.txt This section defines the paths to the Flutter Linux GTK shared library and its header files. It also sets environment variables for the Flutter tool backend and the application's AOT library. These variables are published to the parent scope for use in other build steps. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) ``` -------------------------------- ### Define Standard Compilation Settings Source: https://github.com/ascress/flusbserial/blob/master/example/windows/CMakeLists.txt Defines a function to apply standard C++17 compilation features and flags to a target. ```cmake function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_17) target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") target_compile_options(${TARGET} PRIVATE /EHsc) target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") endfunction() ``` -------------------------------- ### Set flow control Source: https://github.com/ascress/flusbserial/blob/master/README.md Configure flow control for supported devices (CP210x & CH34x). ```dart await mDevice.setFlowControl(UsbSerialInterface.flowControlRtsCts); ``` -------------------------------- ### Define list_prepend function in CMake Source: https://github.com/ascress/flusbserial/blob/master/example/linux/flutter/CMakeLists.txt This custom CMake function prepends a prefix to each element in a list. It is used as a workaround for older CMake versions that do not support `list(TRANSFORM ... PREPEND ...)`. Ensure the list variable is correctly set before calling this function. ```cmake function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Set auto detach kernel driver Source: https://github.com/ascress/flusbserial/blob/master/README.md Configure kernel driver detachment, specifically for Linux. ```dart UsbSerialDevice.setAutoDetachKernelDriver(true); ``` -------------------------------- ### Write Data to USB Serial Device Source: https://context7.com/ascress/flusbserial/llms.txt Write raw bytes or string commands to a USB serial device. Ensure the device is opened and configured before writing. Handles potential write errors. ```dart import 'dart:typed_data'; import 'dart:convert'; import 'package:flusbserial/flusbserial.dart'; Future writeDataExample() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); UsbDevice targetDevice = devices.firstWhere( (d) => d.vendorId == 0x10C4 && d.productId == 0xEA60, ); UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice(targetDevice); await serialDevice!.open(); await serialDevice.setBaudRate(115200); await serialDevice.setDataBits(UsbSerialInterface.dataBits8); await serialDevice.setStopBits(UsbSerialInterface.stopBits1); await serialDevice.setParity(UsbSerialInterface.parityNone); try { // Write raw bytes Uint8List rawData = Uint8List.fromList([0x01, 0x02, 0x03, 0x04]); int bytesWritten = await serialDevice.write(rawData, 500); print('Wrote $bytesWritten bytes'); // Write a string command String command = 'AT+VERSION\r\n'; Uint8List commandBytes = Uint8List.fromList(utf8.encode(command)); int cmdBytesWritten = await serialDevice.write(commandBytes, 500); print('Sent command: $command ($cmdBytesWritten bytes)'); // Write single byte Uint8List singleByte = Uint8List.fromList([0xFF]); await serialDevice.write(singleByte, 100); } catch (e) { print('Write error: $e'); } await serialDevice.close(); UsbSerialDevice.exit(); } ``` -------------------------------- ### Enable Auto-Detach Kernel Driver (Linux) Source: https://context7.com/ascress/flusbserial/llms.txt Enable automatic kernel driver detachment for USB serial devices on Linux. This is necessary when a kernel driver is already bound to the device, preventing libusb from claiming it. Call this before opening the device. ```dart import 'package:flusbserial/flusbserial.dart'; Future linuxKernelDriverExample() async { UsbSerialDevice.init(); // Enable auto-detach before opening devices (Linux only) // This detaches any kernel driver (e.g., cdc_acm, ch341) so libusb can claim the interface UsbSerialDevice.setAutoDetachKernelDriver(true); List devices = await UsbSerialDevice.listDevices(); UsbDevice targetDevice = devices.firstWhere( (d) => d.vendorId == 0x1A86 && d.productId == 0x7523, // CH340 device ); UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice( targetDevice, type: UsbSerialDevice.ch34x, ); // The kernel driver will be automatically detached when open() is called bool opened = await serialDevice!.open(); if (opened) { print('Device opened with kernel driver detached'); await serialDevice.setBaudRate(9600); // ... perform operations await serialDevice.close(); } UsbSerialDevice.exit(); } ``` -------------------------------- ### Add Flutter library interface target in CMake Source: https://github.com/ascress/flusbserial/blob/master/example/linux/flutter/CMakeLists.txt This snippet creates an INTERFACE library target named 'flutter'. It includes the Flutter library headers and links against the Flutter shared library and the PkgConfig-found GTK, GLIB, and GIO libraries. This target simplifies linking Flutter dependencies for other parts of the build. ```cmake add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") target_link_libraries(flutter INTERFACE PkgConfig::GTK PkgConfig::GLIB PkgConfig::GIO ) add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Read and write data Source: https://github.com/ascress/flusbserial/blob/master/README.md Perform read and write operations on the serial device. ```dart int bytesWritten = await mDevice.write(data, timeout); Uint8List bytesRead = await mDevice.read(bytesToRead, timeout); ``` -------------------------------- ### Close device Source: https://github.com/ascress/flusbserial/blob/master/README.md Close the active device connection. ```dart await mDevice.close(); ``` -------------------------------- ### Control DTR/RTS lines Source: https://github.com/ascress/flusbserial/blob/master/README.md Toggle the state of DTR and RTS control lines. ```dart await mDevice.setDtr(true); await mDevice.setDtr(false); await mDevice.setRts(true); await mDevice.setRts(false); ``` -------------------------------- ### Control DTR and RTS Lines Source: https://context7.com/ascress/flusbserial/llms.txt Manually assert or deassert DTR and RTS hardware control lines. Useful for signaling device readiness or implementing flow control. Toggling DTR can reset some devices. ```dart import 'package:flusbserial/flusbserial.dart'; Future controlLinesExample() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); UsbDevice targetDevice = devices.firstWhere( (d) => d.vendorId == 0x10C4 && d.productId == 0xEA60, ); UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice(targetDevice); await serialDevice!.open(); await serialDevice.setBaudRate(115200); // Assert DTR (Data Terminal Ready) - commonly used to signal device is ready await serialDevice.setDtr(true); print('DTR asserted'); // Deassert DTR await serialDevice.setDtr(false); print('DTR deasserted'); // Assert RTS (Request To Send) - used in hardware flow control await serialDevice.setRts(true); print('RTS asserted'); // Deassert RTS await serialDevice.setRts(false); print('RTS deasserted'); // Common pattern: Toggle DTR to reset a device (e.g., Arduino) await serialDevice.setDtr(false); await Future.delayed(Duration(milliseconds: 100)); await serialDevice.setDtr(true); print('Device reset via DTR toggle'); await serialDevice.close(); UsbSerialDevice.exit(); } ``` -------------------------------- ### Custom target for Flutter assembly in CMake Source: https://github.com/ascress/flusbserial/blob/master/example/linux/flutter/CMakeLists.txt This defines a custom target 'flutter_assemble' that depends on the generated Flutter library and its headers. This target ensures that the Flutter library and headers are built before they are used by other targets. ```cmake add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ) ``` -------------------------------- ### Set Flow Control for Serial Port Source: https://context7.com/ascress/flusbserial/llms.txt Configure hardware or software flow control. Flow control is supported on CP210x and CH34x devices, but not on CDC ACM. ```dart import 'package:flusbserial/flusbserial.dart'; Future flowControlExample() async { UsbSerialDevice.init(); List devices = await UsbSerialDevice.listDevices(); UsbDevice targetDevice = devices.firstWhere( (d) => d.vendorId == 0x10C4 && d.productId == 0xEA60, ); UsbSerialDevice? serialDevice = UsbSerialDevice.createDevice( targetDevice, type: UsbSerialDevice.cp210x, // Flow control requires CP210x or CH34x ); await serialDevice!.open(); // No flow control (default) await serialDevice.setFlowControl(UsbSerialInterface.flowControlOff); // Hardware flow control using RTS/CTS await serialDevice.setFlowControl(UsbSerialInterface.flowControlRtsCts); // Hardware flow control using DSR/DTR await serialDevice.setFlowControl(UsbSerialInterface.flowControlDsrDtr); // Software flow control using XON/XOFF await serialDevice.setFlowControl(UsbSerialInterface.flowControlXonXoff); await serialDevice.close(); UsbSerialDevice.exit(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.