2017-05-06 14 views
1

RProc/RPMsgインタフェースを使用してマイクロプロセッサと通信する高レベルのラッパーとコマンド・コレクションを作成しました。可能な限りテストするために、使用するユニット・テストを作成しました。 '本当の'インターフェースの代わりにLinuxの擬似端末。擬似端末から読み取ることができない

私のテストはうまくいかなかった。私は最終的にそれは私のコードの痕跡を含まない点までテストを簡素化 - そしてそれはまだ動作しません:

BOOST_AUTO_TEST_CASE(constructor) 
{ 
    const auto master_pty = ::posix_openpt(O_RDWR); 
    BOOST_REQUIRE(master_pty != -1); 
    BOOST_REQUIRE(::grantpt(master_pty) != -1); 
    BOOST_REQUIRE(::unlockpt(master_pty) != -1); 

    const auto slave_pty_name = ::ptsname(master_pty); 
    const auto slave_pty = ::open(slave_pty_name, O_RDWR); 
    BOOST_REQUIRE(slave_pty != -1); 

    const auto in_data = std::array<std::uint8_t, 4>{1, 2, 3, 4}; 
    const auto bytes_written = ::write(master_pty, in_data.data(), in_data.size()); 
    if (bytes_written < 0) { 
     BOOST_FAIL("Failed to write: " << errno); 
    } 
    BOOST_REQUIRE_EQUAL(in_data.size(), bytes_written); 

    auto out_data = std::array<std::uint8_t, in_data.size()>{}; 
    const auto bytes_read = ::read(slave_pty, out_data.data(), out_data.size()); 
    BOOST_CHECK_EQUAL(bytes_read, bytes_written); 
    if (bytes_read < 0) { 
     BOOST_FAIL("::read failed: " << errno); 
    } 

    ::close(slave_pty); 
    ::close(master_pty); 
} 

の出力は次のとおりです。

*** 1 failure is detected in the test module "cmPTP Test Suite" 
# cmPTP-manager-test -l all --run_test=comms_rproc_interface/constructor 
Running 1 test case... 
Entering test module "cmPTP Test Suite" 
interface_test.cpp(17): Entering test suite "comms_rproc_interface" 
interface_test.cpp(19): Entering test case "constructor" 
interface_test.cpp(23): info: check master_pty != -1 has passed 
interface_test.cpp(24): info: check grantpt(master_pty) != -1 has passed 
interface_test.cpp(25): info: check unlockpt(master_pty) != -1 has passed 
interface_test.cpp(32): info: check slave_pty != -1 has passed 
interface_test.cpp(72): info: check in_data.size() == bytes_written has passed 
interface_test.cpp(77): error: in "comms_rproc_interface/constructor": check bytes_read == bytes_written has failed [0 != 4] 
interface_test.cpp(19): Leaving test case "constructor"; testing time: 15282us 
interface_test.cpp(17): Leaving test suite "comms_rproc_interface"; testing time: 15931us 
Leaving test module "cmPTP Test Suite"; testing time: 16879us 

*** 1 failure is detected in the test module "cmPTP Test Suite" 

私は4を書くことができますバイトは正常ですが、スレーブ側には何も存在しません。どうして?

+0

読み取りが実際に失敗したように見えるが、それはバイトを取得していないことをしないこと。書き込みバッファはフラッシュされていますか? – starturtle

+0

@starturtle POSIXは、write()が返された後に発生することが判明しているread(2)が新しいデータを返すことを要求しています。私はもちろん、Linux/EXT4がPOSIXに準拠していると仮定しています...どうすれば強制的にフラッシュできますか? – cmannett85

+0

@starturtle実際には、PTSがファイル記述子の2つであるため、上記は当てはまりません。 – cmannett85

答えて

0

私は擬似端末を作成していて、シリアルデバイスではないことを忘れていたからです。 PTYは私の入力値をASCIIで処理していたので、フラッシング前にラインリターンを待っていたので、フラッシングに関する@ starturtleのコメントは正しく、単に「通常の」ファイル書き込み方法ではなかった。

このtrival SSCCEは、私はそれを行っている必要があります方法を示しています。

#include <unistd.h> 
#include <pty.h> 

#include <array> 
#include <iostream> 

int main() 
{ 
    // Make the PTY 'raw' to disable traditional terminal-like 
    // behaviour 
    struct termios ts; 
    cfmakeraw(&ts); 

    auto master_pty = -1; 
    auto slave_pty = -1; 
    if (::openpty(&master_pty, &slave_pty, nullptr, &ts, nullptr) < 0) { 
     std::cerr << "Cannot create PTY: " << errno << std::endl; 
     return EXIT_FAILURE; 
    } 

    const auto in_data = std::array<std::uint8_t, 5>{1, 2, 3, 4, 5}; 
    const auto bytes_written = ::write(master_pty, in_data.data(), in_data.size()); 
    if (bytes_written < 0) { 
     std::cerr << "Failed to write: " << errno << std::endl; 
     return EXIT_FAILURE; 
    } 

    auto out_data = std::array<std::uint8_t, in_data.size()>{}; 
    out_data.fill(0); 

    const auto bytes_read = ::read(slave_pty, out_data.data(), out_data.size()); 
    if (bytes_read < 0) { 
     std::cerr << "::read failed: " << errno << std::endl; 
     return EXIT_FAILURE; 
    } 

    for (auto&& c : out_data) { 
     std::cout << static_cast<int>(c); 
    } 
    std::cout << std::endl; 

    ::close(slave_pty); 
    ::close(master_pty); 
} 
関連する問題