mirror of
https://github.com/m5stack/AI-Pyramid-EC-Proxy.git
synced 2026-05-20 11:50:27 -07:00
[init]
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
[submodule "SDK"]
|
||||
path = SDK
|
||||
url = https://github.com/m5stack/M5Stack_Linux_Libs.git
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 M5Stack
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,369 @@
|
||||
# EC Proxy - Embedded Controller Communication System
|
||||
|
||||
<p align="center"><img src="https://static-cdn.m5stack.com/resource/public/assets/m5logo2022.svg" alt="M5Stack" width="300" height="300"></p>
|
||||
|
||||
<p align="center">
|
||||
EC Proxy is a high-performance embedded controller communication system that provides hardware abstraction and control for embedded devices. It bridges Modbus RTU communication with modern ZeroMQ-based RPC/PUB-SUB architecture, enabling intuitive hardware control through simple command-line tools or programmatic interfaces.
|
||||
</p>
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Features](#features)
|
||||
* [Architecture](#architecture)
|
||||
* [Components](#components)
|
||||
* [System Requirements](#system-requirements)
|
||||
* [Compilation](#compilation)
|
||||
* [Installation](#installation)
|
||||
* [Usage](#usage)
|
||||
* [Hardware Support](#hardware-support)
|
||||
* [Documentation](#documentation)
|
||||
* [Contributing](#contributing)
|
||||
* [License](#license)
|
||||
|
||||
## Features
|
||||
|
||||
* **Modbus RTU Bridge**: Seamless communication with embedded controllers via serial interface
|
||||
* **ZeroMQ RPC Service**: Modern, high-performance remote procedure call interface
|
||||
* **Event Broadcasting**: Real-time PUB/SUB event system for hardware state changes
|
||||
* **Comprehensive Hardware Control**: Manage power, USB ports, PCIe slots, RGB LEDs, LCD displays, fans, and sensors
|
||||
* **Network Interface Management**: Automatic IP address synchronization for multiple network interfaces
|
||||
* **Configuration Persistence**: Flash storage for critical configuration data
|
||||
* **Multi-threaded Architecture**: Efficient concurrent handling of multiple hardware subsystems
|
||||
* **Simple CLI Tool**: User-friendly command-line interface for all hardware operations
|
||||
* **Cross-platform**: Built for embedded Linux devices (ARM64 architecture)
|
||||
* **Open Source**: Licensed under MIT License
|
||||
|
||||
## Architecture
|
||||
|
||||
The EC Proxy system consists of two main components that work together to provide hardware abstraction:
|
||||
|
||||
```
|
||||
┌─────────────────┐ Modbus RTU ┌──────────────────┐ ZMQ RPC/PUB ┌─────────────┐
|
||||
│ Hardware EC │ ◄─────────────────► │ EC Proxy │ ◄──────────────────► │ Client │
|
||||
│ (STM32/MCU) │ /dev/ttyS3 │ Server │ IPC/TCP Sockets │ (CLI/App) │
|
||||
└─────────────────┘ 115200-921600bps └──────────────────┘ └─────────────┘
|
||||
```
|
||||
|
||||
### Communication Flow
|
||||
|
||||
1. **Hardware Layer**: Embedded controller (EC) exposes Modbus RTU interface over serial port
|
||||
2. **Proxy Layer**: EC Proxy server translates Modbus commands to ZMQ RPC calls
|
||||
3. **Client Layer**: CLI tools or applications interact via simple RPC interface
|
||||
4. **Event Layer**: Hardware events (button presses, status changes) broadcast via PUB/SUB
|
||||
|
||||
## Components
|
||||
|
||||
### 1. EC Proxy Server (`ec_proxy`)
|
||||
|
||||
The proxy server daemon that manages all hardware communication:
|
||||
|
||||
- Modbus RTU serial communication
|
||||
- ZeroMQ RPC service (`ipc:///tmp/rpc.ec_prox`)
|
||||
- Event publisher (`ipc:///tmp/llm/ec_prox.event.socket`)
|
||||
- Network interface monitoring
|
||||
- Automatic fan control
|
||||
- Button event handling
|
||||
|
||||
### 2. EC CLI Tool (`cli`)
|
||||
|
||||
Command-line interface for hardware control:
|
||||
|
||||
```bash
|
||||
# Control hardware peripherals
|
||||
ec_cli device --fan -d 80 # Set fan to 80% speed
|
||||
ec_cli device --rgb -d 5 # Set RGB LED mode
|
||||
ec_cli device --board # Get power consumption info
|
||||
ec_cli device --poweroff -d 1 # Trigger system poweroff
|
||||
|
||||
# Execute custom RPC calls
|
||||
ec_cli exec -l # List all available functions
|
||||
ec_cli exec -f <function> -d <data> # Call custom function
|
||||
|
||||
# Monitor hardware events
|
||||
ec_cli echo --button # Subscribe to button events
|
||||
```
|
||||
|
||||
See [detailed documentation](./projects/ec_proxy/README.md) for complete command reference.
|
||||
|
||||
## System Requirements
|
||||
|
||||
### Hardware
|
||||
- ARM64-based embedded Linux device (AX630C, AX650N, or compatible)
|
||||
- Serial port for Modbus communication (e.g., `/dev/ttyS3`)
|
||||
- Embedded controller with Modbus RTU support
|
||||
|
||||
### Software
|
||||
- **Operating System**: Ubuntu 20.04+ (ARM64) or compatible Linux distribution
|
||||
- **Cross-compilation Toolchain**: aarch64-none-linux-gnu-gcc 10.3+
|
||||
- **Build Tools**: SCons, Python 3.8+
|
||||
- **Libraries**: ZeroMQ, libmodbus, fmt, nlohmann-json
|
||||
|
||||
## Compilation
|
||||
|
||||
### 1. Install Cross-compilation Toolchain
|
||||
|
||||
```bash
|
||||
# Download and install ARM64 cross-compilation toolchain
|
||||
wget https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/linaro/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
|
||||
sudo tar Jxvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz -C /opt
|
||||
|
||||
# Add to PATH (add to ~/.bashrc for persistence)
|
||||
export PATH=/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH
|
||||
```
|
||||
|
||||
### 2. Install Build Dependencies
|
||||
|
||||
```bash
|
||||
# Install required packages
|
||||
sudo apt update
|
||||
sudo apt install -y python3 python3-pip libffi-dev git
|
||||
|
||||
# Install Python build tools
|
||||
pip3 install parse scons requests kconfiglib
|
||||
```
|
||||
|
||||
### 3. Clone and Build
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/m5stack/Ai_Pyramid_ec_proxy.git
|
||||
cd Ai_Pyramid_ec_proxy
|
||||
|
||||
# Initialize submodules (SDK components)
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Navigate to EC Proxy project
|
||||
cd projects/ec_proxy
|
||||
|
||||
# Clean previous builds (optional)
|
||||
scons distclean
|
||||
|
||||
# Compile (use -j flag for parallel compilation)
|
||||
scons -j$(nproc)
|
||||
```
|
||||
|
||||
### 4. Build Output
|
||||
|
||||
After successful compilation, binaries will be located in:
|
||||
|
||||
```
|
||||
projects/ec_proxy/build/
|
||||
├── main_ec_proxy/
|
||||
│ └── ec_proxy # Proxy server executable
|
||||
└── main_ec_cli/
|
||||
└── ec_cli # CLI tool executable
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
### Deploy to Target Device
|
||||
|
||||
```bash
|
||||
# Copy binaries to target device
|
||||
scp build/main_ec_proxy/ec_proxy root@<target-ip>:/usr/local/bin/
|
||||
scp build/main_ec_cli/ec_cli root@<target-ip>:/usr/local/bin/
|
||||
|
||||
# On target device, make executable
|
||||
chmod +x /usr/local/bin/ec_proxy
|
||||
chmod +x /usr/local/bin/cli
|
||||
```
|
||||
|
||||
### Create Systemd Service (Optional)
|
||||
|
||||
Create `/etc/systemd/system/ec-proxy.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=EC Proxy Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/ec_proxy
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Enable and start the service:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ec-proxy
|
||||
sudo systemctl start ec-proxy
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Start EC Proxy Server
|
||||
|
||||
```bash
|
||||
# Run directly
|
||||
./ec_proxy
|
||||
|
||||
# Or use systemd service
|
||||
sudo systemctl start ec-proxy
|
||||
```
|
||||
|
||||
### Using the CLI Tool
|
||||
|
||||
```bash
|
||||
# Get hardware status
|
||||
ec_cli device --board # Power consumption info
|
||||
ec_cli device --version # EC firmware version
|
||||
ec_cli device --fanspeed # Current fan speed
|
||||
|
||||
# Control peripherals
|
||||
ec_cli device --fan -d 60 # Set fan PWM to 60%
|
||||
ec_cli device --rgb -d 1 # Set RGB mode to 1
|
||||
ec_cli device --lcd_brightness -d 200 # Set LCD brightness
|
||||
|
||||
# Network configuration
|
||||
ec_cli device --ip_eth0 -d "192.168.1.100"
|
||||
ec_cli device --flash_value # Save to flash memory
|
||||
|
||||
# Monitor events
|
||||
ec_cli echo --button # Watch for button presses
|
||||
```
|
||||
|
||||
## Hardware Support
|
||||
|
||||
EC Proxy supports control of the following hardware peripherals:
|
||||
|
||||
### Power Management
|
||||
- Board power control
|
||||
- External power switch
|
||||
- USB PD power info
|
||||
- Power consumption monitoring
|
||||
- Scheduled power on/off
|
||||
|
||||
### Peripherals
|
||||
- 3× USB downstream ports (with high-power mode)
|
||||
- 2× PCIe slots
|
||||
- GL3510 USB hub
|
||||
- Grove I2C/UART interfaces
|
||||
|
||||
### Display & LEDs
|
||||
- RGB LED array (up to 64 LEDs)
|
||||
- LCD display with brightness control
|
||||
- Multiple display modes
|
||||
|
||||
### Sensors & Control
|
||||
- Fan PWM control with RPM monitoring
|
||||
- Temperature-based auto fan control
|
||||
- CPU voltage (VDD) adjustment
|
||||
- Button input detection
|
||||
|
||||
### Network
|
||||
- Ethernet interface management (eth0, eth1)
|
||||
- WLAN interface support
|
||||
- Automatic IP address synchronization
|
||||
|
||||
See [complete hardware documentation](./projects/ec_proxy/README.md#supported-hardware-peripherals) for detailed register mappings.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **[EC Proxy Full Documentation](./projects/ec_proxy/README.md)** - Complete guide with all commands and features
|
||||
- **[SDK Documentation](./SDK/README.md)** - Build system and component information
|
||||
- **[API Reference](./projects/ec_proxy/README.md#supported-hardware-peripherals)** - Modbus register mapping
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# RPC socket path (default: ipc:///tmp/rpc.ec_prox)
|
||||
export AX650C_EC_PROXY_RPC_SOCKET="ipc:///tmp/rpc.ec_prox"
|
||||
|
||||
# PUB socket path (default: ipc:///tmp/llm/ec_prox.event.socket)
|
||||
export AX650C_EC_PROXY_PUB_SOCKET="ipc:///tmp/llm/ec_prox.event.socket"
|
||||
|
||||
# Initial RGB LED mode (default: 1)
|
||||
export AX650_EC_RGB_MODE=1
|
||||
|
||||
# Initial LCD display mode (default: 2)
|
||||
export AX650_EC_LCD_MODE=2
|
||||
|
||||
# Auto power-off timer in seconds (default: 30000)
|
||||
export AX650_EC_POWER_OFF_TIME=30000
|
||||
```
|
||||
|
||||
### Modbus Configuration
|
||||
|
||||
- **Serial Port**: `/dev/ttyS3` (configurable in code)
|
||||
- **Baud Rate**: 921600 bps (auto-negotiable)
|
||||
- **Data Format**: 8N1 (8 data bits, no parity, 1 stop bit)
|
||||
- **Slave Address**: 1
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**1. Compilation Errors**
|
||||
```bash
|
||||
# Ensure toolchain is in PATH
|
||||
which aarch64-none-linux-gnu-gcc
|
||||
|
||||
# Update submodules
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Clean and rebuild
|
||||
scons distclean && scons -j$(nproc)
|
||||
```
|
||||
|
||||
**2. Connection Issues**
|
||||
```bash
|
||||
# Check if proxy is running
|
||||
systemctl status ec-proxy
|
||||
|
||||
# Verify serial port
|
||||
ls -l /dev/ttyS3
|
||||
|
||||
# Check socket files
|
||||
ls -l /tmp/rpc.ec_prox
|
||||
```
|
||||
|
||||
**3. Permission Issues**
|
||||
```bash
|
||||
# Add user to dialout group for serial access
|
||||
sudo usermod -aG dialout $USER
|
||||
|
||||
# Set proper permissions
|
||||
sudo chmod 666 /dev/ttyS3
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
||||
4. Push to the branch (`git push origin feature/amazing-feature`)
|
||||
5. Open a Pull Request
|
||||
|
||||
### Reporting Issues
|
||||
|
||||
Please report bugs and feature requests via [GitHub Issues](https://github.com/m5stack/Ai_Pyramid_ec_proxy/issues).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
- M5Stack team for hardware platform support
|
||||
- AXERA for AI acceleration platform
|
||||
- Open source community for excellent libraries (ZeroMQ, libmodbus, fmt, nlohmann-json)
|
||||
|
||||
## Support
|
||||
|
||||
- **Documentation**: [M5Stack Docs](https://docs.m5stack.com)
|
||||
- **Forum**: [M5Stack Community](https://community.m5stack.com)
|
||||
- **Issues**: [GitHub Issues](https://github.com/m5stack/Ai_Pyramid_ec_proxy/issues)
|
||||
|
||||
---
|
||||
|
||||
**Note**: This project provides hardware abstraction for embedded controllers. It can be integrated with AI frameworks for advanced applications like voice-controlled hardware or automated system management.
|
||||
Submodule
+1
Submodule SDK added at afbf2d2382
@@ -0,0 +1,11 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
import shutil
|
||||
|
||||
os.environ['SDK_PATH'] = os.path.normpath(str(Path(os.getcwd())/'..'/'..'/'SDK'))
|
||||
os.environ['EXT_COMPONENTS_PATH'] = os.path.normpath(str(Path(os.getcwd())/'..'/'..'/'ext_components'))
|
||||
|
||||
|
||||
with open(str(Path(os.getcwd())/'..'/'..'/'SDK'/'tools'/'scons'/'project.py')) as f:
|
||||
exec(f.read())
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# unix
|
||||
# CONFIG_TOOLCHAIN_PATH="/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin"
|
||||
# win
|
||||
# CONFIG_TOOLCHAIN_PATH="..\\gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf\\bin"
|
||||
|
||||
# CONFIG_TOOLCHAIN_PREFIX="arm-linux-gnueabihf-"
|
||||
# CONFIG_TOOLCHAIN_PATH="/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin"
|
||||
CONFIG_TOOLCHAIN_PREFIX="aarch64-linux-gnu-"
|
||||
CONFIG_CPU_ARCH="armv8"
|
||||
CONFIG_UTILITIES_ENABLED=y
|
||||
CONFIG_UTILITIES_BASE64_ENABLED=y
|
||||
CONFIG_MODBUS_ENABLED=y
|
||||
CONFIG_UTILITIES_FMT_ENABLED=y
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: MPL-2.0 */
|
||||
|
||||
/* This file is deprecated, and all its functionality provided by zmq.h */
|
||||
/* Note that -Wpedantic compilation requires GCC to avoid using its custom
|
||||
extensions such as #warning, hence the trick below. Also, pragmas for
|
||||
warnings or other messages are not standard, not portable, and not all
|
||||
compilers even have an equivalent concept.
|
||||
So in the worst case, this include file is treated as silently empty. */
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) \
|
||||
|| defined(_MSC_VER)
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic warning "-Wcpp"
|
||||
#pragma GCC diagnostic ignored "-Werror"
|
||||
#pragma GCC diagnostic ignored "-Wall"
|
||||
#endif
|
||||
#pragma message( \
|
||||
"Warning: zmq_utils.h is deprecated. All its functionality is provided by zmq.h.")
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
#ifndef _TBL_YIELD_H_
|
||||
#define _TBL_YIELD_H_
|
||||
|
||||
#define CORO_CTX(name) \
|
||||
static void * __coro_##name = NULL
|
||||
|
||||
#define CORO_BEGIN(name) \
|
||||
CORO_CTX(name); \
|
||||
if (__coro_##name == NULL) { \
|
||||
__coro_##name = &&__coro_start_##name; \
|
||||
} \
|
||||
goto *__coro_##name; \
|
||||
__coro_start_##name:
|
||||
|
||||
|
||||
#define CORO_END(name) \
|
||||
__coro_##name = NULL
|
||||
|
||||
#define CORO_CONCAT(a, b, c) a##b##c
|
||||
|
||||
#define CORO_YIELD_IMPL(name, codelin) \
|
||||
do { \
|
||||
__coro_##name = &&CORO_CONCAT(__coro_resume_, name, codelin); \
|
||||
return; \
|
||||
CORO_CONCAT(__coro_resume_, name, codelin):; \
|
||||
} while (0)
|
||||
|
||||
#define CORO_YIELD(name) CORO_YIELD_IMPL(name, __LINE__)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
|
||||
Import('env')
|
||||
with open(env['PROJECT_TOOL_S']) as f:
|
||||
exec(f.read())
|
||||
|
||||
|
||||
SRCS = []
|
||||
INCLUDE = [ADir('../include')]
|
||||
PRIVATE_INCLUDE = []
|
||||
REQUIREMENTS = ['pthread', 'utilities', 'modbus_component', 'zmq']
|
||||
STATIC_LIB = []
|
||||
DYNAMIC_LIB = []
|
||||
DEFINITIONS = []
|
||||
DEFINITIONS_PRIVATE = []
|
||||
LDFLAGS = []
|
||||
LINK_SEARCH_PATH = []
|
||||
STATIC_FILES = []
|
||||
|
||||
LINK_SEARCH_PATH += [ADir('../static')]
|
||||
|
||||
LDFLAGS+=['-Wl,-rpath=/opt/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib/gcc-10.3', '-Wl,-rpath=/opt/lib', '-Wl,-rpath=/opt/usr/lib', '-Wl,-rpath=./']
|
||||
|
||||
|
||||
|
||||
SRCS = [AFile('src/ec_cli_main.cpp')]
|
||||
env['COMPONENTS'].append({'target':'ec_cli-1.0',
|
||||
'SRCS':SRCS,
|
||||
'INCLUDE':INCLUDE,
|
||||
'PRIVATE_INCLUDE':PRIVATE_INCLUDE,
|
||||
'REQUIREMENTS':REQUIREMENTS,
|
||||
'STATIC_LIB':STATIC_LIB,
|
||||
'DYNAMIC_LIB':DYNAMIC_LIB,
|
||||
'DEFINITIONS':DEFINITIONS,
|
||||
'DEFINITIONS_PRIVATE':DEFINITIONS_PRIVATE,
|
||||
'LDFLAGS':LDFLAGS,
|
||||
'LINK_SEARCH_PATH':LINK_SEARCH_PATH,
|
||||
'STATIC_FILES':STATIC_FILES,
|
||||
'REGISTER':'project'
|
||||
})
|
||||
@@ -0,0 +1,383 @@
|
||||
#include <iostream>
|
||||
#include <modbus.h>
|
||||
#include "pzmq.hpp"
|
||||
#include "cmdline.hpp"
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include "json.hpp"
|
||||
int condition = 1;
|
||||
const char *rpc_socket_path;
|
||||
const char *pub_socket_path;
|
||||
|
||||
void info_fun(cmdline::parser &a, std::string set_fun, std::string get_fun)
|
||||
{
|
||||
if (a.exist("data") || a.exist("DataRaw")) {
|
||||
if (set_fun.length() == 0) return;
|
||||
std::string DataRaw = a.get<std::string>("DataRaw");
|
||||
if (DataRaw.empty()) {
|
||||
DataRaw = fmt::format("{{ \"data\": {} }}", a.get<std::string>("data"));
|
||||
}
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action(set_fun, DataRaw,
|
||||
[set_fun](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call " << set_fun << " faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (get_fun.length() == 0) {
|
||||
std::cout << "please set data: -d or -D" << std::endl;
|
||||
return;
|
||||
}
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action(get_fun, "{}",
|
||||
[get_fun](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call " << get_fun << " faile! " << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void info_set_fun(cmdline::parser &a, std::string set_fun, std::string default_data)
|
||||
{
|
||||
if (set_fun.length() == 0) return;
|
||||
std::string DataRaw = default_data;
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action(set_fun, DataRaw,
|
||||
[set_fun](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call " << set_fun << " faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void lcd_putc_fun(cmdline::parser &a)
|
||||
{
|
||||
if (a.exist("data")) {
|
||||
std::string DataRaw = a.get<std::string>("data");
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
for (auto i = 0; i < DataRaw.length(); i++) {
|
||||
Context.call_rpc_action("lcd_putc", fmt::format("{{ \"data\": {} }}", (int)DataRaw[i]),
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
} else {
|
||||
std::cout << "call lcd_putc faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void get_info_fun(cmdline::parser &a, std::string fun)
|
||||
{
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action(fun, "{\"data\":\"None\"}",
|
||||
[fun](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call " << fun << " faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void set_info_fun(cmdline::parser &a, std::string fun)
|
||||
{
|
||||
if (a.exist("data") || a.exist("DataRaw")) {
|
||||
std::string DataRaw = a.get<std::string>("DataRaw");
|
||||
if (DataRaw.empty()) {
|
||||
DataRaw = fmt::format("{{ \"data\": {} }}", a.get<std::string>("data"));
|
||||
}
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action(fun, DataRaw,
|
||||
[fun](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call " << fun << "faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void fan_speed_fun(cmdline::parser &a)
|
||||
{
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action("fan_get_speed", "{}",
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call fan_get_speed faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void fan_pwm_fun(cmdline::parser &a)
|
||||
{
|
||||
if (a.exist("data") || a.exist("DataRaw")) {
|
||||
std::string DataRaw = a.get<std::string>("DataRaw");
|
||||
if (DataRaw.empty()) {
|
||||
DataRaw = fmt::format("{{ \"data\": {} }}", a.get<std::string>("data"));
|
||||
}
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action("fan_set_pwm", DataRaw,
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call fan_set_pwm faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action("fan_get_pwm", "{}",
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call fan_get_pwm faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_fun(cmdline::parser &a)
|
||||
{
|
||||
if (a.exist("data") || a.exist("DataRaw")) {
|
||||
std::string DataRaw = a.get<std::string>("DataRaw");
|
||||
if (DataRaw.empty()) {
|
||||
DataRaw = fmt::format("{{ \"data\": {} }}", a.get<std::string>("data"));
|
||||
}
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action("rgb_set_mode", DataRaw,
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call rgb_set_mode faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action("rgb_get_mode", "{}",
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call rgb_get_mode faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void exec_fun(cmdline::parser &a)
|
||||
{
|
||||
if (a.exist("list")) {
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
std::cout << "list" << std::endl;
|
||||
Context.call_rpc_action("list_action", "None",
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
try {
|
||||
nlohmann::json _data = nlohmann::json::parse(data->string());
|
||||
std::cout << _data.dump(4) << std::endl;
|
||||
} catch (const nlohmann::json::parse_error &e) {
|
||||
std::cerr << "JSON parsing failed for list_action response. Error: " << e.what()
|
||||
<< ". Invalid JSON data received: " << data->string() << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "call list_action faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string fun = a.get<std::string>("fun");
|
||||
const std::string data = a.get<std::string>("data");
|
||||
if (fun.length() == 0) {
|
||||
std::cout << "fun is empty! cli exec -f <fun> -d <data>" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
StackFlows::pzmq Context(rpc_socket_path);
|
||||
Context.call_rpc_action(fun, data, [](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
if (data->size() > 0) {
|
||||
std::cout << "" << data->string() << std::endl;
|
||||
} else {
|
||||
std::cout << "call ax650_ec_prox faile!" << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void echo_fun(cmdline::parser &a)
|
||||
{
|
||||
if (a.exist("button")) {
|
||||
StackFlows::pzmq Context(pub_socket_path, ZMQ_SUB,
|
||||
[](StackFlows::pzmq *_pzmq, const std::shared_ptr<StackFlows::pzmq_data> &data) {
|
||||
std::cout << data->string() << std::endl;
|
||||
});
|
||||
while (condition) {
|
||||
usleep(100 * 1000);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void signalHandler(int signum)
|
||||
{
|
||||
condition = 0;
|
||||
std::exit(0); // 这会调用全局对象的析构函数
|
||||
}
|
||||
|
||||
struct call_fun {
|
||||
std::string fun;
|
||||
char flage;
|
||||
std::string dec;
|
||||
std::function<void(cmdline::parser &a)> fun_call;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
error_print_exit:
|
||||
std::cout << R"help(
|
||||
用法:git [--version] [--help]
|
||||
<命令> [<参数>]
|
||||
|
||||
这些是各种场合常见的 cli 命令:
|
||||
|
||||
直接操作 ec (参见:cli help device)
|
||||
device 直接执行一个操作,使用指令传递参数
|
||||
|
||||
自定义操作 ec (参见:git help exec)
|
||||
exec 执行一个原始函数调用
|
||||
|
||||
订阅 prox 的通道数据(参见:git help echo)
|
||||
echo 显示 prox 的通道数据
|
||||
|
||||
命令 'cli help -a' 和 'cli help -g' 显示可用的子命令和一些概念帮助。
|
||||
查看 'cli help <命令>' 或 'cli help <概念>' 以获取给定子命令或概念的
|
||||
帮助。
|
||||
)help" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
signal(SIGTERM, signalHandler);
|
||||
signal(SIGINT, signalHandler);
|
||||
rpc_socket_path = getenv("AX650C_EC_PROXY_RPC_SOCKET");
|
||||
if (rpc_socket_path == NULL) {
|
||||
rpc_socket_path = "ipc:///tmp/rpc.ec_prox";
|
||||
}
|
||||
pub_socket_path = getenv("AX650C_EC_PROXY_PUB_SOCKET");
|
||||
if (pub_socket_path == NULL) {
|
||||
pub_socket_path = "ipc:///tmp/llm/ec_prox.event.socket";
|
||||
}
|
||||
if (std::string(argv[1]) == "device") {
|
||||
cmdline::parser a;
|
||||
// clang-format off
|
||||
std::list<struct call_fun> cmd_list = {
|
||||
{"rgb", 'r', "Get or set RGB LED display mode", std::bind(&info_fun, std::placeholders::_1, "rgb_set_mode", "rgb_get_mode")},
|
||||
{"poweron_time", 0, "Get or set the scheduled power-on time", std::bind(&info_fun, std::placeholders::_1, "poweron_set_time", "poweron_get_time")},
|
||||
{"poweroff_time", 0, "Get or set the scheduled power-off time", std::bind(&info_fun, std::placeholders::_1, "poweroff_set_time", "poweroff_get_time")},
|
||||
{"rgb_size", 0, "Get or set the number of RGB LEDs in the array", std::bind(&info_fun, std::placeholders::_1, "rgb_set_size", "rgb_get_size")},
|
||||
{"rgb_get_color", 0, "Get the color value of a specific RGB LED", std::bind(&info_fun, std::placeholders::_1, "rgb_get_color", "")},
|
||||
{"rgb_set_color", 0, "Set color for a specific RGB LED, example: cli --rgb_set_color -d '{\"rgb_index\":0,\"rgb_color\":255}'", std::bind(&info_fun, std::placeholders::_1, "rgb_set_color", "")},
|
||||
{"fan", 'f', "Get or set the fan PWM duty cycle", std::bind(&info_fun, std::placeholders::_1, "fan_set_pwm", "fan_get_pwm")},
|
||||
{"fanspeed", 'F', "Get the current fan rotation speed in RPM", std::bind(&info_fun, std::placeholders::_1, "", "fan_get_speed")},
|
||||
{"pd_power_info", 0, "Get the USB PD power delivery information", std::bind(&info_fun, std::placeholders::_1, "", "pd_power_info")},
|
||||
{"board", 'B', "Get the board power consumption information", std::bind(&info_fun, std::placeholders::_1, "", "board_get_power_info")},
|
||||
{"ip_eth0", 0, "Get or set the IP address for Ethernet interface eth0", std::bind(&info_fun, std::placeholders::_1, "eth0_ip_set", "eth0_ip_get")},
|
||||
{"ip_eth1", 0, "Get or set the IP address for Ethernet interface eth1", std::bind(&info_fun, std::placeholders::_1, "eth1_ip_set", "eth1_ip_get")},
|
||||
{"ip_wlan", 0, "Get or set the IP address for wireless LAN interface", std::bind(&info_fun, std::placeholders::_1, "wlan_ip_set", "wlan_ip_get")},
|
||||
{"lcd", 'l', "Get or set the LCD display mode", std::bind(&info_fun, std::placeholders::_1, "lcd_set_mode", "lcd_get_mode")},
|
||||
{"lcd_ram", 0, "Set the LCD RAM buffer data directly", std::bind(&info_fun, std::placeholders::_1, "lcd_set_ram", "")},
|
||||
{"vddcpu", 'c', "Get or set the CPU core voltage (VDD)", std::bind(&info_fun, std::placeholders::_1, "vddcpu_set", "vddcpu_get")},
|
||||
{"modbus_speed", 0, "Get or set the Modbus communication baud rate", std::bind(&info_fun, std::placeholders::_1, "modbus_set_speed", "modbus_get_speed")},
|
||||
{"ext_power", 'p', "Control the external power supply output", std::bind(&info_fun, std::placeholders::_1, "ext_power", "")},
|
||||
{"board_power", 'b', "Control the main board power switch", std::bind(&info_fun, std::placeholders::_1, "board_power", "")},
|
||||
{"pcie0", 0, "Set the PCIe slot 0 switch on/off state", std::bind(&info_fun, std::placeholders::_1, "pcie0_set_switch", "")},
|
||||
{"pcie1", 0, "Set the PCIe slot 1 switch on/off state", std::bind(&info_fun, std::placeholders::_1, "pcie1_set_switch", "")},
|
||||
{"gl3510_reset", 0, "Reset the GL3510 USB hub controller", std::bind(&info_fun, std::placeholders::_1, "gl3510_reset", "")},
|
||||
{"usbds1_big", 0, "Set the high-power mode for USB downstream port 1", std::bind(&info_fun, std::placeholders::_1, "usbds1_set_big_power", "")},
|
||||
{"usbds2_big", 0, "Set the high-power mode for USB downstream port 2", std::bind(&info_fun, std::placeholders::_1, "usbds2_set_big_power", "")},
|
||||
{"usbds1", 0, "Set the switch on/off state for USB downstream port 1", std::bind(&info_fun, std::placeholders::_1, "usbds1_set_switch", "")},
|
||||
{"usbds2", 0, "Set the switch on/off state for USB downstream port 2", std::bind(&info_fun, std::placeholders::_1, "usbds2_set_switch", "")},
|
||||
{"usbds3", 0, "Set the switch on/off state for USB downstream port 3", std::bind(&info_fun, std::placeholders::_1, "usbds3_set_switch", "")},
|
||||
{"hdmi_loop_en", 0, "Switch HDMI OUT port input source between IN and AX8850", std::bind(&info_fun, std::placeholders::_1, "usbds3_set_switch", "")},
|
||||
{"grove_uart", 0, "Set the switch on/off state for Grove UART interface", std::bind(&info_fun, std::placeholders::_1, "grove_uart_set_switch", "")},
|
||||
{"grove_iic", 0, "Set the switch on/off state for Grove I2C interface", std::bind(&info_fun, std::placeholders::_1, "grove_iic_set_switch", "")},
|
||||
{"flash_switch", 0, "Save switch configuration to flash memory (stores coil registers 4-14)", std::bind(&info_set_fun, std::placeholders::_1, "flash_save_switch", "{\"data\":1}")},
|
||||
{"flash_value", 0, "Save value configuration to flash memory (stores holding registers 1, 2, 11, 12, 14, 16-21)", std::bind(&info_set_fun, std::placeholders::_1, "flash_save_value", "{\"data\":1}")},
|
||||
{"poweroff", 0, "Trigger the system power-off sequence", std::bind(&info_fun, std::placeholders::_1, "poweroff", "")},
|
||||
{"lcd_brightness", 0, "Get or set the LCD backlight brightness level", std::bind(&info_fun, std::placeholders::_1, "lcd_set_brightness", "lcd_get_brightness")},
|
||||
{"lcd_putc", 'P', "Output a character or string to the LCD display", lcd_putc_fun},
|
||||
{"i2c_set_reg", 0, "Write a value to an I2C device register", std::bind(&info_fun, std::placeholders::_1, "i2c_set_reg", "i2c_set_reg")},
|
||||
{"i2c_get_reg", 0, "Read a value from an I2C device register", std::bind(&info_fun, std::placeholders::_1, "i2c_get_reg", "i2c_get_reg")},
|
||||
{"ec_button_head_event", 0, "Get or set the event handler for EC head button press", std::bind(&info_fun, std::placeholders::_1, "ec_button_set_head_event", "ec_button_get_head_event")},
|
||||
{"soc_button_head_event", 0, "Get or set the event handler for SoC head button press", std::bind(&info_fun, std::placeholders::_1, "soc_button_set_head_event", "soc_button_get_head_event")},
|
||||
{"ec_button_lcd_event", 0, "Get or set the event handler for EC LCD button press", std::bind(&info_fun, std::placeholders::_1, "ec_button_set_lcd_event", "ec_button_get_lcd_event")},
|
||||
{"fun_auto", 0, "Get or set the automatic control mode for the proxy service", std::bind(&info_fun, std::placeholders::_1, "fun_set_auto", "fun_get_auto")},
|
||||
{"ec_modbus_set_bit", 0, "Set a specific bit in the EC Modbus coil register", std::bind(&info_fun, std::placeholders::_1, "ec_modbus_set_bit", "ec_modbus_set_bit")},
|
||||
{"ec_modbus_get_bit", 0, "Get a specific bit value from the EC Modbus coil register", std::bind(&info_fun, std::placeholders::_1, "ec_modbus_get_bit", "ec_modbus_get_bit")},
|
||||
{"ec_modbus_input_bits", 0, "Read the EC Modbus discrete input bits status", std::bind(&info_fun, std::placeholders::_1, "ec_modbus_get_input_bits", "ec_modbus_get_input_bits")},
|
||||
{"ec_modbus_input_registers", 0, "Read the EC Modbus input registers values", std::bind(&info_fun, std::placeholders::_1, "ec_modbus_get_input_registers", "ec_modbus_get_input_registers")},
|
||||
{"ec_modbus_set_hold_registers", 0, "Write values to the EC Modbus holding registers", std::bind(&info_fun, std::placeholders::_1, "ec_modbus_set_hold_registers", "ec_modbus_set_hold_registers")},
|
||||
{"ec_modbus_get_hold_registers", 0, "Read values from the EC Modbus holding registers", std::bind(&info_fun, std::placeholders::_1, "ec_modbus_get_hold_registers", "ec_modbus_get_hold_registers")},
|
||||
|
||||
{"pcie0_exists", 0, "Check if a PCIe device is present in slot 0", std::bind(&info_fun, std::placeholders::_1, "", "pcie0_exists")},
|
||||
{"pcie1_exists", 0, "Check if a PCIe device is present in slot 1", std::bind(&info_fun, std::placeholders::_1, "", "pcie1_exists")},
|
||||
{"V3_3_good", 0, "Check if the 3.3V power rail is within normal operating range", std::bind(&info_fun, std::placeholders::_1, "", "V3_3_good")},
|
||||
{"V1_8_good", 0, "Check if the 1.8V power rail is within normal operating range", std::bind(&info_fun, std::placeholders::_1, "", "V1_8_good")},
|
||||
{"head_button", 0, "Get the current state of the head button (pressed/released)", std::bind(&info_fun, std::placeholders::_1, "", "head_button")},
|
||||
{"lcd_button", 0, "Get the current state of the LCD button (pressed/released)", std::bind(&info_fun, std::placeholders::_1, "", "lcd_button")},
|
||||
{"version", 0, "Get the EC firmware version information", std::bind(&info_fun, std::placeholders::_1, "", "version")},
|
||||
|
||||
};
|
||||
// clang-format on
|
||||
for (auto &cmd : cmd_list) {
|
||||
a.add(cmd.fun, cmd.flage, cmd.dec);
|
||||
}
|
||||
a.add<std::string>("data", 'd', "call param", false);
|
||||
a.add<std::string>("DataRaw", 'D', "call param raw", false);
|
||||
a.parse_check(argc, argv);
|
||||
int not_find_index = 1;
|
||||
for (auto &cmd : cmd_list) {
|
||||
if (a.exist(cmd.fun)) {
|
||||
cmd.fun_call(a);
|
||||
not_find_index = 0;
|
||||
}
|
||||
}
|
||||
if (not_find_index) {
|
||||
std::cout << a.usage() << std::endl;
|
||||
}
|
||||
} else if (std::string(argv[1]) == "exec") {
|
||||
cmdline::parser a;
|
||||
a.add("list", 'l', "list call function");
|
||||
a.add<std::string>("fun", 'f', "call ax650c_ec_proxy function", false);
|
||||
a.add<std::string>("data", 'd', "call ax650c_ec_proxy function input data", false);
|
||||
a.parse_check(argc, argv);
|
||||
exec_fun(a);
|
||||
} else if (std::string(argv[1]) == "echo") {
|
||||
cmdline::parser a;
|
||||
a.add("button", 'b', "button event");
|
||||
a.parse_check(argc, argv);
|
||||
echo_fun(a);
|
||||
std::cout << a.usage() << std::endl;
|
||||
return 0;
|
||||
} else {
|
||||
goto error_print_exit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
|
||||
Import('env')
|
||||
with open(env['PROJECT_TOOL_S']) as f:
|
||||
exec(f.read())
|
||||
|
||||
|
||||
SRCS = []
|
||||
INCLUDE = [ADir('../include')]
|
||||
PRIVATE_INCLUDE = []
|
||||
REQUIREMENTS = ['pthread', 'utilities', 'modbus_component', 'zmq']
|
||||
STATIC_LIB = []
|
||||
DYNAMIC_LIB = []
|
||||
DEFINITIONS = []
|
||||
DEFINITIONS_PRIVATE = []
|
||||
LDFLAGS = []
|
||||
LINK_SEARCH_PATH = []
|
||||
STATIC_FILES = []
|
||||
|
||||
LINK_SEARCH_PATH += [ADir('../static')]
|
||||
|
||||
LDFLAGS+=['-Wl,-rpath=/opt/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib/gcc-10.3', '-Wl,-rpath=/opt/lib', '-Wl,-rpath=/opt/usr/lib', '-Wl,-rpath=./']
|
||||
|
||||
|
||||
|
||||
SRCS = [AFile('src/ec_proxy_main.cpp')]
|
||||
env['COMPONENTS'].append({'target':'ec_proxy-1.0',
|
||||
'SRCS':SRCS,
|
||||
'INCLUDE':INCLUDE,
|
||||
'PRIVATE_INCLUDE':PRIVATE_INCLUDE,
|
||||
'REQUIREMENTS':REQUIREMENTS,
|
||||
'STATIC_LIB':STATIC_LIB,
|
||||
'DYNAMIC_LIB':DYNAMIC_LIB,
|
||||
'DEFINITIONS':DEFINITIONS,
|
||||
'DEFINITIONS_PRIVATE':DEFINITIONS_PRIVATE,
|
||||
'LDFLAGS':LDFLAGS,
|
||||
'LINK_SEARCH_PATH':LINK_SEARCH_PATH,
|
||||
'STATIC_FILES':STATIC_FILES,
|
||||
'REGISTER':'project'
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Reference in New Issue
Block a user