qnx str-ctl

本文详细解释了str-ctl在QNX系统中的作用,涉及设备休眠、唤醒时的参数设置,以及与powermanager的交互,展示了如何通过str-ctl命令执行整机休眠过程和相关模块的同步操作。

str-ctl 实现源码

AMSS/platform/services/applications/str-ctl/main.c

int main ( int argc, char** argv)
{
    int c ;
    uint64_t entry_timeout_nsec = 1000000000ull;
    uint64_t wakeup_timeout_nsec = 1000000000ull;
    bool initiate = false ;

    while( ( c = getopt( argc, argv, "e:w:i" ) ) != -1 ) {
        switch( c ) {
            case 'e':
                entry_timeout_nsec = strtoull ( optarg, NULL, 0 );
                break;
            case 'w':
                wakeup_timeout_nsec = strtoull ( optarg, NULL, 0 );
                break;
            case 'i':
                initiate = true;
                break;
            case '?':
                ERR("Invalid option(%c), see \"use %s\"", c, argv[0]);
                return -1;
        }
    }

    if ( !initiate ) {
        ERR("'-i' option mandatory, see \"use %s\"", argv[0]);
        return EOK ;
    }

    int fd = open ( "/dev/pm", O_RDWR | O_CLOEXEC) ;
    if ( fd < 0 ) {
        ERR ("open(/dev/pm) failed, err=%d", errno);
        return -1;
    }

    struct timespec start, stop;
    uint64_t cycle, ncycles;
    uint64_t duration_nsec ;

    struct pm_str_s cmd = {0};
    cmd.entry_timeout = entry_timeout_nsec ;
    cmd.wakeup_timeout = wakeup_timeout_nsec ;

    (void) clock_gettime( CLOCK_REALTIME, &start) ;
    cycle = ClockCycles();

    int const rc = devctl ( fd, DCMD_PM_ENTER_STR , &cmd, sizeof (struct pm_str_s), 0 );

    ncycles = ClockCycles() - cycle;
    (void) clock_gettime( CLOCK_REALTIME, &stop) ;

    duration_nsec = timespec2nsec (&stop) - timespec2nsec (&start);

    if ( rc == EOK && duration_nsec < wakeup_timeout_nsec ) {
        LOG("STR interrupted, expected to sleep=%llu ms, actual sleep =%llu ms",
                NSEC_TO_MSEC ( wakeup_timeout_nsec ), NSEC_TO_MSEC (duration_nsec ));
    }

    LOG("DCMD_PM_ENTER_STR %s rc=%d",  rc ? "failed" : "succeeded" , rc );
    LOG("Elapsed system time -> %fs", 1.0f * duration_nsec / ( BILLION * 1.0f) );
    LOG("Elapsed raw cycles time -> %fs", (double) ncycles / SYSPAGE_ENTRY(q
你正在为 **QNX Neutrino 7.1.0** 系统在 **AArch64(ARM64)架构** 上进行交叉编译,并使用了 `./configure` 脚本配置一个项目(很可能是 `libunwind` 或其他底层库)。你的目标是正确地构建适用于 QNX 的二进制文件。 当前命令基本结构是对的,但有一些关键点需要**修正和优化**以确保成功交叉编译。下面我会详细解释如何修改并提供正确的参数建议。 --- ### ✅ 正确的 `configure` 命令写法(推荐版本) ```bash ./configure \ --host=aarch64-unknown-nto-qnx7.1.0 \ --build=x86_64-pc-linux-gnu \ --target=aarch64-unknown-nto-qnx7.1.0 \ --disable-tests \ CC="aarch64-unknown-nto-qnx7.1.0-gcc" \ CXX="aarch64-unknown-nto-qnx7.1.0-g++" \ AR="aarch64-unknown-nto-qnx7.1.0-ar" \ RANLIB="aarch64-unknown-nto-qnx7.1.0-ranlib" \ LD="aarch64-unknown-nto-qnx7.1.0-ld" \ STRIP="aarch64-unknown-nto-qnx7.1.0-strip" \ CFLAGS="-march=armv8-a -O3 -fPIC" \ CXXFLAGS="-march=armv8-a -O3 -fPIC" \ LDFLAGS="-lsocket -lexit" ``` --- ### 🔍 修改说明与问题分析 #### ❌ 问题 1:`AR`, `RANLIB`, `LD`, `STRIP` 工具命名错误 你在原命令中使用了: ```bash AR=aarch64-unknown-nto-qnx7.1.0-gcc-ar ``` 但实际上 QNX 提供的标准工具链前缀下,这些工具应该是独立的二进制文件,而不是通过 GCC 包装器调用。正确的名称是: | 错误写法 | 正确写法 | |--------|--------| | `gcc-ar` → `ar` | `aarch64-unknown-nto-qnx7.1.0-ar` | | `gcc-ranlib` → `ranlib` | `aarch64-unknown-nto-qnx7.1.0-ranlib` | > ⚠️ `gcc-ar` 是 GNU Binutils 中用于插件支持的包装器,在 QNX 工具链中通常不存在或不兼容。 ✅ 应改为: ```bash AR=aarch64-unknown-nto-qnx7.1.0-ar RANLIB=aarch64-unknown-nto-qnx7.1.0-ranlib ``` --- #### ✅ 添加 `--build` 和 `--target`(可选但推荐) 虽然 `--host` 是必须的,但在某些 Autotools 配置中,缺少 `--build` 可能导致检测失败。 - `--build`: 本地编译环境(通常是 `x86_64-pc-linux-gnu`) - `--host`: 目标运行平台(即你要交叉编译到的平台) - `--target`: 主要用于编译器工具链开发,一般可以省略,但如果构建的是工具链则需设置 示例: ```bash --build=x86_64-pc-linux-gnu \ --host=aarch64-unknown-nto-qnx7.1.0 \ ``` --- #### ✅ CFLAGS 补充 `-fPIC`(重要!) 如果你要生成共享库(`.so`),必须添加 `-fPIC`,否则链接会报错(relocation error)。 ```bash CFLAGS="-march=armv8-a -O3 -fPIC" CXXFLAGS="-march=armv8-a -O3 -fPIC" ``` --- #### ✅ LDFLAGS:QNX 特殊库依赖 QNX 的网络、线程等功能可能依赖额外库,如: - `-lsocket`:网络编程所需 - `-lexit`:某些系统调用需要 - `-lcpp` 或 `-lc++`:C++ 支持(如果启用 C++) 根据实际需求添加: ```bash LDFLAGS="-lsocket -lexit" ``` 如果是 C++ 项目: ```bash LDFLAGS="-lcpp -lsocket -lexit" ``` --- #### ✅ 使用 `CC=` 和 `CXX=` 显式指定编译器 这一步你已经做得很好,保持即可。 --- ### 🧪 验证工具链是否存在 请确认你的 PATH 中包含 QNX 工具链,或者使用完整路径测试某个工具: ```bash aarch64-unknown-nto-qnx7.1.0-gcc --version aarch64-unknown-nto-qnx7.1.0-ar --version ``` 如果没有该命令,请检查以下几点: 1. 是否已安装 QNX SDP 7.1? 2. 是否将 `$QNX_HOST/usr/bin` 加入了 `PATH`? ```bash export QNX_HOST=/path/to/qnx710/host/linux/x86_64 export PATH=$QNX_HOST/usr/bin:$PATH ``` --- ### 💡 其他建议 #### 如果 configure 报错 “cannot run C compiled programs” 这是常见的交叉编译问题,表示 configure 尝试运行一个编译后的程序(比如 test executable),但在目标平台上无法执行。 ✅ 解决方法:添加 `--disable-some-feature` 或手动告诉 config 某些结果: ```bash ac_cv_func_mmap_file=yes ``` 或者直接跳过运行测试: ```bash ./configure ... --build=x86_64-pc-linux-gnu --host=aarch64-unknown-nto-qnx7.1.0 \ ax_cv_cxx_compile_cxx11=yes \ ac_cv_func_mmap_fixed_mapped=yes \ am_cv_libtool_disable_static=yes ``` 具体变量可通过查看 `config.log` 找出失败项后绕过。 --- ### 🛠 示例:完整脚本(保存为 build.sh) ```bash #!/bin/bash export QNX_HOST=/opt/qnx710/host/linux/x86_64 export PATH=$QNX_HOST/usr/bin:$PATH ./configure \ --build=x86_64-pc-linux-gnu \ --host=aarch64-unknown-nto-qnx7.1.0 \ --disable-tests \ CC=aarch64-unknown-nto-qnx7.1.0-gcc \ CXX=aarch64-unknown-nto-qnx7.1.0-g++ \ AR=aarch64-unknown-nto-qnx7.1.0-ar \ RANLIB=aarch64-unknown-nto-qnx7.1.0-ranlib \ LD=aarch64-unknown-nto-qnx7.1.0-ld \ STRIP=aarch64-unknown-nto-qnx7.1.0-strip \ CFLAGS="-march=armv8-a -O3 -fPIC" \ CXXFLAGS="-march=armv8-a -O3 -fPIC" \ LDFLAGS="-lsocket -lexit" make clean && make -j$(nproc) ``` --- ### ✅ 成功标志 - `config.status` 生成成功 - `make` 编译通过 - 输出 `.a` 或 `.so` 文件可用 `file libxxx.so` 检查: ```bash file .libs/libunwind.so # 输出应类似: # libunwind.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked ``` ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值