someip环境搭建
吐槽
虽然网上有很多vsomeip和common api构建的文章,但是看了很多,也没说明白这2个到底是什么关系,总结一句话,vsomeip实现了someip协议(包括服务发现等),common api是让用户更好的使用vsomeip(序列化等)。为了使用common api我们需要依赖很多模块,使用大致顺序为(boost->vsomeip->common api)。下面将逐一进行介绍
Boost下载与编译
1 boost下载:
https://github.com/boostorg/boost/releases/tag/
本文这里使用的是boost_1_70_0
2 boost交叉编译
修改了原始的bootstrap.sh脚本,修改如下:
#!/bin/sh
# Copyright (C) 2005, 2006 Douglas Gregor.
# Copyright (C) 2006 The Trustees of Indiana University
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# boostinspect:notab - Tabs are required for the Makefile.
BJAM=""
TOOLSET=""
BJAM_CONFIG=""
BUILD=""
PREFIX=/usr/local
EPREFIX=
LIBDIR=
INCLUDEDIR=
LIBS=""
PYTHON=python
PYTHON_VERSION=
PYTHON_ROOT=
ICU_ROOT=
# Handle case where builtin shell version of echo command doesn't
# support -n. Use the installed echo executable if there is one
# rather than builtin version to ensure -n is supported.
ECHO=`which echo`
if test "x$ECHO" = x; then
ECHO=echo
fi
# Internal flags
flag_no_python=
flag_icu=
flag_show_libraries=
for option
do
case $option in
-help | --help | -h)
want_help=yes ;;
-prefix=* | --prefix=*)
PREFIX=`expr "x$option" : "x-*prefix=\(.*\)"`
;;
-exec-prefix=* | --exec-prefix=*)
EPREFIX=`expr "x$option" : "x-*exec-prefix=\(.*\)"`
;;
-libdir=* | --libdir=*)
LIBDIR=`expr "x$option" : "x-*libdir=\(.*\)"`
;;
-includedir=* | --includedir=*)
INCLUDEDIR=`expr "x$option" : "x-*includedir=\(.*\)"`
;;
-show-libraries | --show-libraries )
flag_show_libraries=yes
;;
-with-bjam=* | --with-bjam=* )
BJAM=`expr "x$option" : "x-*with-bjam=\(.*\)"`
;;
-with-icu | --with-icu )
flag_icu=yes
;;
-with-icu=* | --with-icu=* )
flag_icu=yes
ICU_ROOT=`expr "x$option" : "x-*with-icu=\(.*\)"`
;;
-without-icu | --without-icu )
flag_icu=no
;;
-with-libraries=* | --with-libraries=* )
library_list=`expr "x$option" : "x-*with-libraries=\(.*\)"`
if test "$library_list" != "all"; then
old_IFS=$IFS
IFS=,
for library in $library_list
do
LIBS="$LIBS --with-$library"
if test $library = python; then
requested_python=yes
fi
done
IFS=$old_IFS
if test "x$requested_python" != xyes; then
flag_no_python=yes
fi
fi
;;
-without-libraries=* | --without-libraries=* )
library_list=`expr "x$option" : "x-*without-libraries=\(.*\)"`
old_IFS=$IFS
IFS=,
for library in $library_list
do
LIBS="$LIBS --without-$library"
if test $library = python; then
flag_no_python=yes
fi
done
IFS=$old_IFS
;;
-with-python=* | --with-python=* )
PYTHON=`expr "x$option" : "x-*with-python=\(.*\)"`
;;
-with-python-root=* | --with-python-root=* )
PYTHON_ROOT=`expr "x$option" : "x-*with-python-root=\(.*\)"`
;;
-with-python-version=* | --with-python-version=* )
PYTHON_VERSION=`expr "x$option" : "x-*with-python-version=\(.*\)"`
;;
-with-toolset=* | --with-toolset=* )
TOOLSET=`expr "x$option" : "x-*with-toolset=\(.*\)"`
;;
-*)
{ echo "error: unrecognized option: $option
Try \`$0 --help' for more information." >&2
{ (exit 1); exit 1; }; }
;;
esac
done
if test "x$want_help" = xyes; then
cat <<EOF
\`./bootstrap.sh' prepares Boost for building on a few kinds of systems.
Usage: $0 [OPTION]...
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
--with-bjam=BJAM use existing Boost.Jam executable (bjam)
[automatically built]
--with-toolset=TOOLSET use specific Boost.Build toolset
[automatically detected]
--show-libraries show the set of libraries that require build
and installation steps (i.e., those libraries
that can be used with --with-libraries or
--without-libraries), then exit
--with-libraries=list build only a particular set of libraries,
describing using either a comma-separated list of
library names or "all"
[all]
--without-libraries=list build all libraries except the ones listed []
--with-icu enable Unicode/ICU support in Regex
[automatically detected]
--without-icu disable Unicode/ICU support in Regex
--with-icu=DIR specify the root of the ICU library installation
and enable Unicode/ICU support in Regex
[automatically detected]
--with-python=PYTHON specify the Python executable [python]
--with-python-root=DIR specify the root of the Python installation
[automatically detected]
--with-python-version=X.Y specify the Python version as X.Y
[automatically detected]
Installation directories:
--prefix=PREFIX install Boost into the given PREFIX
[/usr/local]
--exec-prefix=EPREFIX install Boost binaries into the given EPREFIX
[PREFIX]
More precise control over installation directories:
--libdir=DIR install libraries here [EPREFIX/lib]
--includedir=DIR install headers here [PREFIX/include]
EOF
fi
test -n "$want_help" && exit 0
my_dir=$(dirname "$0")
# Determine the toolset, if not already decided
if test "x$TOOLSET" = x; then
guessed_toolset=`$my_dir/tools/build/src/engine/build.sh --guess-toolset`
case $guessed_toolset in
acc | darwin | gcc | como | mipspro | pathscale | pgi | qcc | vacpp )
TOOLSET=$guessed_toolset
;;
intel-* )
TOOLSET=intel
;;
mingw )
TOOLSET=gcc
;;
sun* )
TOOLSET=sun
;;
* )
# Not supported by Boost.Build
;;
esac
fi
rm -f config.log
# Build bjam
if test "x$BJAM" = x; then
$ECHO -n "Building Boost.Build engine with toolset $1... "
pwd=`pwd`
(cd "$my_dir/tools/build/src/engine" && ./build.sh "$TOOLSET") > bootstrap.log 2>&1
if [ $? -ne 0 ]; then
echo
echo "Failed to build Boost.Build build engine"
echo "Consult 'bootstrap.log' for more details"
exit 1
fi
cd "$pwd"
arch=`cd $my_dir/tools/build/src/engine && ./bootstrap/jam0 -d0 -f build.jam --toolset=$TOOLSET --toolset-root= --show-locate-target && cd ..`
BJAM="$my_dir/tools/build/src/engine/$arch/b2"
echo "tools/build/src/engine/$arch/b2"
cp "$BJAM" .
cp "$my_dir/tools/build/src/engine/$arch/bjam" .
fi
# TBD: Turn BJAM into an absolute path
# If there is a list of libraries
if test "x$flag_show_libraries" = xyes; then
cat <<EOF
The following Boost libraries have portions that require a separate build
and installation step. Any library not listed here can be used by including
the headers only.
The Boost libraries requiring separate building and installation are:
EOF
$BJAM -d0 --show-libraries | grep '^[[:space:]]*-'
exit 0
fi
# Setup paths
if test "x$EPREFIX" = x; then
EPREFIX="$PREFIX"
fi
if test "x$LIBDIR" = x; then
LIBDIR="$EPREFIX/lib"
fi
if test "x$INCLUDEDIR" = x; then
INCLUDEDIR="$PREFIX/include"
fi
# Find Python
if test "x$flag_no_python" = x; then
result=`$PYTHON -c "exit" > /dev/null 2>&1`
if [ "$?" -ne "0" ]; then
flag_no_python=yes
fi
fi
if test "x$flag_no_python" = x; then
if test "x$PYTHON_VERSION" = x; then
$ECHO -n "Detecting Python version... "
PYTHON_VERSION=`$PYTHON -c "import sys; print (\"%d.%d\" % (sys.version_info[0], sys.version_info[1]))"`
echo $PYTHON_VERSION
fi
if test "x$PYTHON_ROOT" = x; then
$ECHO -n "Detecting Python root... "
PYTHON_ROOT=`$PYTHON -c "import sys; print(sys.prefix)"`
echo $PYTHON_ROOT
fi
fi
# Configure ICU
$ECHO -n "Unicode/ICU support for Boost.Regex?... "
if test "x$flag_icu" != xno; then
if test "x$ICU_ROOT" = x; then
if command -v pkg-config > /dev/null && pkg-config icu-uc ; then
ICU_ROOT=`pkg-config --variable=prefix icu-uc`
fi
fi
if test "x$ICU_ROOT" = x; then
COMMON_ICU_PATHS="/usr /usr/local /sw"
for p in $COMMON_ICU_PATHS; do
if test -r $p/include/unicode/utypes.h; then
ICU_ROOT=$p
fi
done
if test "x$ICU_ROOT" = x; then
echo "not found."
else
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
echo "$ICU_ROOT"
fi
else
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
echo "$ICU_ROOT"
fi
else
echo "disabled."
fi
# # Backup the user's existing project-config.jam
# JAM_CONFIG_OUT="project-config.jam"
# if test -r "project-config.jam"; then
# counter=1
# while test -r "project-config.jam.$counter"; do
# counter=`expr $counter + 1`
# done
# echo "Backing up existing Boost.Build configuration in project-config.jam.$counter"
# mv "project-config.jam" "project-config.jam.$counter"
# fi
# Generate user-config.jam
echo "Generating Boost.Build configuration in project-config.jam for $TOOLSET..."
cat > project-config.jam <<EOF
# Boost.Build Configuration
# Automatically generated by bootstrap.sh
import option ;
import feature ;
# Compiler configuration. This definition will be used unless
# you already have defined some toolsets in your user-config.jam
# file.
if ! $TOOLSET in [ feature.values <toolset> ]
{
using gcc : : $1 ;
}
project : default-build <toolset>$TOOLSET ;
EOF
# - Python configuration
if test "x$flag_no_python" = x; then
cat >> project-config.jam <<EOF
# Python configuration
import python ;
if ! [ python.configured ]
{
using python : $PYTHON_VERSION : $PYTHON_ROOT ;
}
EOF
fi
if test "x$ICU_ROOT" != x; then
cat >> project-config.jam << EOF
path-constant ICU_PATH : $ICU_ROOT ;
EOF
fi
cat >> project-config.jam << EOF
# List of --with-<library> and --without-<library>
# options. If left empty, all libraries will be built.
# Options specified on the command line completely
# override this variable.
libraries = $LIBS ;
# These settings are equivalent to corresponding command-line
# options.
option.set prefix : $PREFIX ;
option.set exec-prefix : $EPREFIX ;
option.set libdir : $LIBDIR ;
option.set includedir : $INCLUDEDIR ;
# Stop on first error
option.set keep-going : false ;
EOF
cat << EOF
Bootstrapping is done. To build, run:
./b2
To generate header files, run:
./b2 headers
To adjust configuration, edit 'project-config.jam'.
Further information:
- Command line help:
./b2 --help
- Getting started guide:
http://www.boost.org/more/getting_started/unix-variants.html
- Boost.Build documentation:
http://www.boost.org/build/
EOF
主要修改如下,$TOOLSET代表了使用哪种工具链(默认期望使用gcc),$1为具体使用的工具链:
echo "Generating Boost.Build configuration in project-config.jam for $TOOLSET..."
cat > project-config.jam <<EOF
# Boost.Build Configuration
# Automatically generated by bootstrap.sh
import option ;
import feature ;
# Compiler configuration. This definition will be used unless
# you already have defined some toolsets in your user-config.jam
# file.
if ! $TOOLSET in [ feature.values <toolset> ]
{
using gcc : : $1 ;
}
project : default-build <toolset>$TOOLSET ;
EOF
这里编写了一个build.sh脚本
#! /usr/bin/bash
bash bootstrap.sh $1 --prefix=$2
./bjam clean
./bjam -j8
./bjam install
其中$1和上述一样为指定的交叉编译工具链地址,$2为boost库编译后安装的地址
VSOMEIP交叉编译
1.下载vsomeip
下载地址:
https://github.com/COVESA/vsomeip
本文直接使用了vsomeip最新的源码
2.修改源码中的CmakeLists.txt
添加刚刚编译好的Boost地址:
set (Boost_INCLUDE_DIR /xxx/include)
set (BOOST_LIBRARYDIR /xxx/lib)
set (Boost_LIBRARY_DIR /xxx/lib)
add_definitions(-w)
本文再次提供build.sh,脚本来简化操作
#!/usr/bin/bash
if [ ! -d "build" ];then
mkdir build
else
rm -r build
mkdir build
fi
basedir=`cd $(dirname $0); pwd -P`
cd $basedir/build
pwd
cmake -DCMAKE_INSTALL_PREFIX=xxx -DCMAKE_CXX_COMPILER=xxx -DCMAKE_C_COMPILER=xxx ..
make -j8
make examples -j8
make install
Common api环境部署
此段内容主要参考:
https://github.com/COVESA/capicxx-core-tools/wiki
1 下载获取CommonAPI库
git clone https://github.com/GENIVI/capicxx-core-runtime.git
本文再次提供了编译脚本,build.sh如下
#!/usr/bin/bash
if [ ! -d "build" ];then
mkdir build
else
rm -r build
mkdir build
fi
basedir=`cd $(dirname $0); pwd -P`
cd $basedir/build
pwd
cmake -DCMAKE_INSTALL_PREFIX=/xxx -DCMAKE_CXX_COMPILER=/xxx -DCMAKE_C_COMPILER=/xxx ..
make -j8
make install
2 构建CommonAPI SOME/IP库
git clone https://github.com/GENIVI/capicxx-someip-runtime.git
再次提供build.sh脚本,如下:
#!/usr/bin/bash
if [ ! -d "build" ];then
mkdir build
else
rm -r build
mkdir build
fi
basedir=`cd $(dirname $0); pwd -P`
cd $basedir/build
pwd
cmake -DCMAKE_INSTALL_PREFIX=/xxx -DCMAKE_PREFIX_PATH=/xxx -DUSE_INSTALLED_COMMONAPI=OFF -DCMAKE_CXX_COMPILER=/xxx -DCMAKE_C_COMPILER=/xxx -DUSE_INSTALLED_COMMONAPI=OFF ..
make -j8
make install
3 编写fidl与fedl文件
fidl文件为约束服务的文件,参考此HelloWorld.fidl
package commonapi
interface HelloWorld {
version {major 1 minor 0}
method sayHello {
in {
String name
}
out {
String message
}
}
}
同样还需要配置带有someip标识符的.fdepl文件,参考此HelloWorld.fdepl
import "platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-SOMEIP_deployment_spec.fdepl"
import "HelloWorld.fidl"
define org.genivi.commonapi.someip.deployment for interface commonapi.HelloWorld {
SomeIpServiceID = 4660
method sayHello {
SomeIpMethodID = 123
}
}
define org.genivi.commonapi.someip.deployment for provider MyService {
instance commonapi.HelloWorld {
InstanceId = "test"
SomeIpInstanceID = 22136
}
}
4 使用代码生成器
commonapi-generator,本文使用最新3.2.0.1版本。生成器地址:
https://github.com/COVESA/capicxx-core-tools/releases/tag/3.2.0.1
commonapi-vsomeip,本文使用最新3.2.0.1版本。生成器地址:
https://github.com/COVESA/capicxx-someip-tools
执行命令就可以生成对应的src-gen代码:
./commonapi-generator/commonapi-generator-linux-x86 -sk ./fidl/HelloWorld.fidl
./commonapi_someip_generator/commonapi-someip-generator-linux-x86 ./fidl/HelloWorld.fdepl
会有如下产物:
$ cd src-gen/v1/commonapi
<.>/src-gen/v1/commonapi$ ls
HelloWorld.hpp HelloWorldSomeIPDeployment.cpp HelloWorldSomeIPProxy.hpp HelloWorldStubDefault.cpp HelloWorldProxyBase.hpp HelloWorldSomeIPDeployment.hpp HelloWorldSomeIPStubAdapter.cpp HelloWorldStubDefault.hpp HelloWorldProxy.hpp HelloWorldSomeIPProxy.cpp HelloWorldSomeIPStubAdapter.hpp HelloWorldStub.hpp
5 构建并运行
参考10分钟Common API 的示例代码,客户端为 HelloWorldClient.cpp:
// HelloWorldClient.cpp
#include <iostream>
#include <string>
#include <unistd.h>
#include <CommonAPI/CommonAPI.hpp>
#include <v1/commonapi/HelloWorldProxy.hpp>
using namespace v1_0::commonapi;
int main() {
std::shared_ptr < CommonAPI::Runtime > runtime = CommonAPI::Runtime::get();
std::shared_ptr<HelloWorldProxy<>> myProxy =
runtime->buildProxy<HelloWorldProxy>("local", "test");
std::cout << "Checking availability!" << std::endl;
while (!myProxy->isAvailable())
usleep(10);
std::cout << "Available..." << std::endl;
CommonAPI::CallStatus callStatus;
std::string returnMessage;
myProxy->sayHello("Bob", callStatus, returnMessage);
std::cout << "Got message: '" << returnMessage << "'\n";
return 0;
}
服务端 HelloWorldService.cpp:
// HelloWorldService.cpp
#include <iostream>
#include <thread>
#include <CommonAPI/CommonAPI.hpp>
#include "HelloWorldStubImpl.hpp"
using namespace std;
int main() {
std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get();
std::shared_ptr<HelloWorldStubImpl> myService =
std::make_shared<HelloWorldStubImpl>();
runtime->registerService("local", "test", myService);
std::cout << "Successfully Registered Service!" << std::endl;
while (true) {
std::cout << "Waiting for calls... (Abort with CTRL+C)" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(30));
}
return 0;
}
HelloWorldStubImpl.hpp,此文件是为了实现自己在idl中定义的sayHello方法:
// HelloWorldStubImpl.hpp
#ifndef HELLOWORLDSTUBIMPL_H_
#define HELLOWORLDSTUBIMPL_H_
#include <CommonAPI/CommonAPI.hpp>
#include <v1/commonapi/HelloWorldStubDefault.hpp>
class HelloWorldStubImpl: public v1_0::commonapi::HelloWorldStubDefault {
public:
HelloWorldStubImpl();
virtual ~HelloWorldStubImpl();
virtual void sayHello(const std::shared_ptr<CommonAPI::ClientId> _client,
std::string _name, sayHelloReply_t _return);
};
#endif /* HELLOWORLDSTUBIMPL_H_ */
HelloWorldStubImpl.cpp 是HelloWorldStubImpl.hpp的具体实现
// HelloWorldStubImpl.cpp
#include "HelloWorldStubImpl.hpp"
HelloWorldStubImpl::HelloWorldStubImpl() { }
HelloWorldStubImpl::~HelloWorldStubImpl() { }
void HelloWorldStubImpl::sayHello(const std::shared_ptr<CommonAPI::ClientId> _client,
std::string _name, sayHelloReply_t _reply) {
std::stringstream messageStream;
messageStream << "Hello " << _name << "!";
std::cout << "sayHello('" << _name << "'): '" << messageStream.str() << "'\n";
_reply(messageStream.str());
};
使用如下CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(my)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -std=c++0x")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ldl")
set(RUNTIME_PATH /xxx)
set(VSOMEIP_PATH /xxx)
include_directories(
src-gen
src
${RUNTIME_PATH}/capicxx-core-runtime/include
${RUNTIME_PATH}/capicxx-someip-runtime/include
${VSOMEIP_PATH}/interface
/xxx/vsomeip
)
link_directories(
${RUNTIME_PATH}/capicxx-core-runtime/build
${RUNTIME_PATH}/capicxx-someip-runtime/build
${VSOMEIP_PATH}/build
/xxx/vsomeip
)
add_executable(HelloWorldClient
src/HelloWorldClient.cpp
src-gen/v1/commonapi/HelloWorldSomeIPProxy.cpp
src-gen/v1/commonapi/HelloWorldSomeIPDeployment.cpp
)
target_link_libraries(HelloWorldClient CommonAPI CommonAPI-SomeIP vsomeip3)
add_executable(HelloWorldService
src/HelloWorldService.cpp
src/HelloWorldStubImpl.cpp
src-gen/v1/commonapi/HelloWorldSomeIPStubAdapter.cpp
#src-gen/v1/commonapi/HelloWorldStubDefault.cpp
src-gen/v1/commonapi/HelloWorldSomeIPDeployment.cpp
)
target_link_libraries(HelloWorldService CommonAPI CommonAPI-SomeIP vsomeip3)
并且再次奉献上build.sh,来方便大家一键编译:
#!/usr/bin/bash
if [ ! -d "build" ];then
mkdir build
else
rm -r build
mkdir build
fi
basedir=`cd $(dirname $0); pwd -P`
cd $basedir/build
cmake -DCMAKE_CXX_COMPILER=/xxx -DCMAKE_C_COMPILER=/xxx ..
make -j8
测试
终于到了最终测试的步骤啦!
我们需要在测试环境上部署以上这些编译好的库(boost commapi commonapt_someip),如果有需要还可以配上指定的vsomeip所依赖的Json,编写了启动进程的脚本 start.sh:
export LD_LIBRARY_PATH=/xxx/vsomeip/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/xxx/boost/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/xxx/commonapi/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/xxx/commonapi_someip/lib:$LD_LIBRARY_PATH
export VSOMEIP_CONFIGURATION=/xxx/vsomeip-udp-client.json
export VSOMEIP_APPLICATION_NAME=client-sample
./HelloWorldClient
服务端配置大致类似,运行起来,大致截图如下,本文在代码中做了对应的修改,因此log与demo中提供的略有不同:
补充
这里再补充一下加入struct length width的配置,fidl如下:
package commonapi
interface HelloWorld {
version {major 1 minor 0}
method sayHello {
in {
String name
Test test
}
out {
String message
}
}
struct Test {
Int32 a
Int32 b
Int32 c
}
}
fdepl如下:文章来源:https://www.toymoban.com/news/detail-495866.html
import "platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-SOMEIP_deployment_spec.fdepl"
import "HelloWorld.fidl"
define org.genivi.commonapi.someip.deployment for interface commonapi.HelloWorld {
SomeIpServiceID = 4660
method sayHello {
SomeIpMethodID = 123
}
struct Test {
a{}
b{}
c{}
}
struct Test{
SomeIpStructLengthWidth = 4
}
}
define org.genivi.commonapi.someip.deployment for provider as MyService {
instance commonapi.HelloWorld {
InstanceId = "test"
SomeIpInstanceID = 22136
}
}
总结
总算是圆满完成啦!后续准吧把整个工程也搞个一键编译的脚本,大家有问题随时留言,写的不太好,海涵海涵哈!文章来源地址https://www.toymoban.com/news/detail-495866.html
到了这里,关于commonapi和vsomeip构建的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!