Nuttxでuorbノートを移植

36979 ワード

Nuttxでuorbノートを移植


以前rosの下のメッセージメカニズム(生産者/消費者)モデルに触れたことがありますが、第一に柔軟で使いやすいと感じましたが、資源の限られた埋め込み環境の中で、メールボックス、メッセージ...は少し柔軟ではありません.その後、nuttxとuorbがrosの下のメッセージメカニズムとは異なることを開発しました.しかし、px 4は高度にカスタマイズされた(飛行制御の問題を解決する)システムです.しかしnuttxだけをosとして開発したいなら、それほど友好的ではないので移植を始めましょう.以下のキーワードは移植の重点であり、事前に理解する必要がある.
  • c++コンパイラコンパイルcコード
  • px 4でのCDevクラス
  • nuttx駆動モデル(上半部、下半部)
  • makefile

  • uORB


    uORBの使い方についてはネット上で多くの紹介がありますが、重複していません.ここでは主にuORBのソフトウェアフレームワークを整理します.
    namespace uORB
    {
    	class DeviceNode;
    	class DeviceMaster;
    	class Manager;
    }
    

    この3つのクラスはuORB全体を実現する主な要素である:class Manager:サービスアプリケーション、メッセージを提供する操作インタフェース(サブスクリプション/パブリッシュ/キャンセル/チェックなど)、uORBを使用するアプリケーション向けである.class DeviceNode:メッセージの最小エンティティユニット(nuttxの文字駆動に対応)は、各メッセージが/obj/xxxの文字駆動形式で存在する.class DeviceMaster:DeviceNodeを管理し、すべてのメッセージの作成、パラメータチェック、記録はそれが完成する責任を負う.だからここまで、実は私たちはuORBのフレームワークを垣間見ることができませんでした.他の人がまとめた一言で「複数のタスクが同じ設備を開く」ということです.

    class CDev


    これはpx 4の上で作った1つの文字駆動のベースクラスで、nuttxの次の文字駆動の上/下部分を実現して、通俗的に言えば、nuttx定義の文字駆動フレームワークをすべて埋め尽くしました;後で実現する必要がある駆動は直接共通に継承すればOKです.開発者の重複作業を減らし,駆動符号化も直接規範化することを目的としている(優れたやり方)
    この意味は、uorbに関するDeviceNode、DeviceMasterがCDevクラスを公的に継承しているため、移植にもこのフレームワークを移植する必要があります.ここでは、githubにもuorbを移植するオープンソースコードがありますが、ringbufferに基づいて実現されています.固定されたOSに依存していません.これは私たちが今回移植したものとは少し違います(Nutx文字駆動に基づいて実現されています)具体的には、著者のオープンソースのコードアドレスGithubを参照してください.

    CDevの移植


    ここでは移植全体の考え方とキーポイントを整理するだけで,具体的な移植は開発者自身が実現する必要がある.第1段階の目標はCDevのフレームワークをnuttx上に構築することです
    移植の手順:CDev==>Manager==>DeviceNode==>DeviceMaster
    1、まずappディレクトリの下でuORBフォルダを作成し、パスの下で次の3つのフォルダを作成します:device、topic、uorb;2、次のファイルをdeviceフォルダの下にコピーする
    CDev.cxx  cdev_platform.cxx  device.h    drv_device.h
    CDev.hpp  cdev_platform.hpp  Device.hpp  drv_orb_dev.h
    

    これらのファイルはpx 4のソースコードで見つけることができ、後でそれぞれの役割を話しています.3、次はmakefile./uORB/Makefile【uORBファイルをappのコンパイルパスに追加】
    ############################################################################
    # apps/uORB/Makefile
    #
    #   Copyright (C) 2011-2015 Gregory Nutt. All rights reserved.
    #   Author: Gregory Nutt 
    #
    # Redistribution and use in source and binary forms, with or without
    # modification, are permitted provided that the following conditions
    # are met:
    #
    # 1. Redistributions of source code must retain the above copyright
    #    notice, this list of conditions and the following disclaimer.
    # 2. Redistributions in binary form must reproduce the above copyright
    #    notice, this list of conditions and the following disclaimer in
    #    the documentation and/or other materials provided with the
    #    distribution.
    # 3. Neither the name NuttX nor the names of its contributors may be
    #    used to endorse or promote products derived from this software
    #    without specific prior written permission.
    #
    # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
    # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    # POSSIBILITY OF SUCH DAMAGE.
    #
    ############################################################################
    
    MENUDESC = "uORB"
    
    include $(APPDIR)/Directory.mk
    
    

    ./uORB/Make.defs【uORBの次のレベルのファイルを含むmakefile】
    ############################################################################
    # apps/uORB/Make.defs
    # Adds selected applications to apps/ build
    #
    #   Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved.
    #   Author: Gregory Nutt 
    #
    # Redistribution and use in source and binary forms, with or without
    # modification, are permitted provided that the following conditions
    # are met:
    #
    # 1. Redistributions of source code must retain the above copyright
    #    notice, this list of conditions and the following disclaimer.
    # 2. Redistributions in binary form must reproduce the above copyright
    #    notice, this list of conditions and the following disclaimer in
    #    the documentation and/or other materials provided with the
    #    distribution.
    # 3. Neither the name NuttX nor the names of its contributors may be
    #    used to endorse or promote products derived from this software
    #    without specific prior written permission.
    #
    # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
    # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    # POSSIBILITY OF SUCH DAMAGE.
    #
    ############################################################################
    
    include $(wildcard uORB/*/Make.defs)
    
    

    上のmakefileでは、新しいファイルパスをコンパイルシステムに組み込むことができます.
    4、CDevのコンパイルに戻ってmakefileを見てみる
    ############################################################################
    # apps/uORB/uorb/Makefile
    #
    #   Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
    #   Author: Gregory Nutt 
    #
    # Redistribution and use in source and binary forms, with or without
    # modification, are permitted provided that the following conditions
    # are met:
    #
    # 1. Redistributions of source code must retain the above copyright
    #    notice, this list of conditions and the following disclaimer.
    # 2. Redistributions in binary form must reproduce the above copyright
    #    notice, this list of conditions and the following disclaimer in
    #    the documentation and/or other materials provided with the
    #    distribution.
    # 3. Neither the name NuttX nor the names of its contributors may be
    #    used to endorse or promote products derived from this software
    #    without specific prior written permission.
    #
    # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
    # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    # POSSIBILITY OF SUCH DAMAGE.
    #
    ############################################################################
    
    -include $(TOPDIR)/Make.defs
    
    # uorb
    
    ASRCS =
    CSRCS =
    #CXXSRCS 
    CXXSRCS = ../device/cdev_platform.cxx ../device/CDev.cxx  uORBManager.cxx uORBDevices.cxx uORB.cxx uORBUtils.cxx 
    MAINSRC = uORBMain.cxx
    
    CONFIG_UORB_PROGNAME ?= uorb$(EXEEXT)
    PROGNAME = $(CONFIG_UORB_PROGNAME)
    
    # uorb built-in application info
    
    APPNAME = uorb
    PRIORITY = SCHED_PRIORITY_DEFAULT
    STACKSIZE = 2048
    
    include $(APPDIR)/Application.mk
    
    

    CDevをコンパイルするフレームワークでは、最初は.../device/cdev_を追加するだけです.platform.cxx …/device/CDev.cxxという2つのファイルでOKですが、移植する際にはいくつかの点に注意する必要があります:!フレームワークにはPX 4 NUTTXマクロ定義のコードクリップしか残っておらず、残りのプラットフォームの例えばPOSIXの全乾き!コンパイル中に警告やエラーが発生しないまで、ヘッダファイルに何かが欠けています.

    uORBの移植


    px 4のソースコードのuorbを全体的にコピーします.次のファイルです.
    ORBMap.hpp        Subscription.hpp      uORBDevices.hpp  uORBTopics.h
    ORBSet.hpp        uORBCommon.hpp        uORB.h           uORBUtils.cxx
    Publication.cxx   uORBCommunicator.hpp  uORBMain.cxx     uORBUtils.hpp
    Publication.hpp   uORB.cxx              uORBManager.cxx
    Subscription.cxx  uORBDevices.cxx       uORBManager.hpp
    
    

    Subscription.hpp Subscription.cxx Publication.cxx Publication.hppという4つのファイルはしばらく使われていないので、makefileにもコンパイルを加える必要はありません.移植の時も同じようにいくつかの点に注意する必要があります:!フレームワークにはPX 4 NUTTXマクロ定義のコードクリップしか残っておらず、残りのプラットフォームの例えばPOSIXの全乾き!コンパイル中に警告やエラーが発生しないまで、ヘッダファイルに何かが欠けています.

    hrtの移植


    この高精度タイマーはnuttxドライバと独立して作られているので、ソースコードをそのまま.../arch/arm/src/stm 32 f 7の下に(makefileにも入れるように注意)、私はf 7を使っています.移植するときは自分のMCUに対応します
    /****************************************************************************
     *
     *   Copyright (c) 2012, 2013 PX4 Development Team. All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in
     *    the documentation and/or other materials provided with the
     *    distribution.
     * 3. Neither the name PX4 nor the names of its contributors may be
     *    used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     *
     ****************************************************************************/
    
    /**
     * @file drv_hrt.c
     *
     * High-resolution timer callouts and timekeeping.
     *
     * This can use any general or advanced STM32 timer.
     *
     * Note that really, this could use systick too, but that's
     * monopolised by NuttX and stealing it would just be awkward.
     *
     * We don't use the NuttX STM32 driver per se; rather, we
     * claim the timer and then drive it directly.
     */
    
    #include 
    #include 
    #include 
    
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    #include 
    #include "stm32_gpio.h"
    #include "stm32_tim.h"
    
    /* High-resolution timer */
    #define HRT_TIMER			9	/* use timer8 for the HRT */
    #define HRT_TIMER_CHANNEL	1	/* use capture/compare channel */
    
    #ifdef CONFIG_DEBUG_HRT
    #  define hrtinfo _info
    #else
    #  define hrtinfo(x...)
    #endif
    
    #ifdef HRT_TIMER
    
    /* HRT configuration */
    #if   HRT_TIMER == 1
    # define HRT_TIMER_BASE		STM32_TIM1_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB2ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB2ENR_TIM1EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM1CC
    # define HRT_TIMER_CLOCK	STM32_APB2_TIM1_CLKIN
    # if CONFIG_STM32F7_TIM1
    #  error must not set CONFIG_STM32_TIM1=y and HRT_TIMER=1
    # endif
    #elif HRT_TIMER == 2
    # define HRT_TIMER_BASE		STM32_TIM2_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB1ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB1ENR_TIM2EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM2
    # define HRT_TIMER_CLOCK	STM32_APB1_TIM2_CLKIN
    # if CONFIG_STM32F7_TIM2
    #  error must not set CONFIG_STM32_TIM2=y and HRT_TIMER=2
    # endif
    #elif HRT_TIMER == 3
    # define HRT_TIMER_BASE		STM32_TIM3_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB1ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB1ENR_TIM3EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM3
    # define HRT_TIMER_CLOCK	STM32_APB1_TIM3_CLKIN
    # if CONFIG_STM32F7_TIM3
    #  error must not set CONFIG_STM32_TIM3=y and HRT_TIMER=3
    # endif
    #elif HRT_TIMER == 4
    # define HRT_TIMER_BASE		STM32_TIM4_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB1ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB1ENR_TIM4EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM4
    # define HRT_TIMER_CLOCK	STM32_APB1_TIM4_CLKIN
    # if CONFIG_STM32F7_TIM4
    #  error must not set CONFIG_STM32_TIM4=y and HRT_TIMER=4
    # endif
    #elif HRT_TIMER == 5
    # define HRT_TIMER_BASE		STM32_TIM5_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB1ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB1ENR_TIM5EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM5
    # define HRT_TIMER_CLOCK	STM32_APB1_TIM5_CLKIN
    # if CONFIG_STM32F7_TIM5
    #  error must not set CONFIG_STM32_TIM5=y and HRT_TIMER=5
    # endif
    #elif HRT_TIMER == 8
    # define HRT_TIMER_BASE		STM32_TIM8_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB2ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB2ENR_TIM8EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM8CC
    # define HRT_TIMER_CLOCK	STM32_APB2_TIM8_CLKIN
    # if CONFIG_STM32F7_TIM8
    #  error must not set CONFIG_STM32_TIM8=y and HRT_TIMER=8
    # endif
    #elif HRT_TIMER == 9
    # define HRT_TIMER_BASE		STM32_TIM9_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB2ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB2ENR_TIM9EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM1BRK
    # define HRT_TIMER_CLOCK	STM32_APB2_TIM9_CLKIN
    # ifdef CONFIG_STM32F7_TIM9
    #  error must not set CONFIG_STM32_TIM9=y and HRT_TIMER=9
    # endif
    #elif HRT_TIMER == 10
    # define HRT_TIMER_BASE		STM32_TIM10_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB2ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB2ENR_TIM10EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM1UP
    # define HRT_TIMER_CLOCK	STM32_APB2_TIM10_CLKIN
    # if CONFIG_STM32F7_TIM10
    #  error must not set CONFIG_STM32_TIM11=y and HRT_TIMER=10
    # endif
    #elif HRT_TIMER == 11
    # define HRT_TIMER_BASE		STM32_TIM11_BASE
    # define HRT_TIMER_POWER_REG	STM32_RCC_APB2ENR
    # define HRT_TIMER_POWER_BIT	RCC_APB2ENR_TIM11EN
    # define HRT_TIMER_VECTOR	STM32_IRQ_TIM1TRGCOM
    # define HRT_TIMER_CLOCK	STM32_APB2_TIM11_CLKIN
    # if CONFIG_STM32F7_TIM11
    #  error must not set CONFIG_STM32_TIM11=y and HRT_TIMER=11
    # endif
    #else
    # error HRT_TIMER must be a value between 1 and 11
    #endif
    
    /*
     * HRT clock must be a multiple of 1MHz greater than 1MHz
     */
    #if (HRT_TIMER_CLOCK % 1000000) != 0
    # error HRT_TIMER_CLOCK must be a multiple of 1MHz
    #endif
    #if HRT_TIMER_CLOCK <= 1000000
    # error HRT_TIMER_CLOCK must be greater than 1MHz
    #endif
    
    /**
     * Minimum/maximum deadlines.
     *
     * These are suitable for use with a 16-bit timer/counter clocked
     * at 1MHz.  The high-resolution timer need only guarantee that it
     * not wrap more than once in the 50ms period for absolute time to
     * be consistently maintained.
     *
     * The minimum deadline must be such that the time taken between
     * reading a time and writing a deadline to the timer cannot
     * result in missing the deadline.
     */
    #define HRT_INTERVAL_MIN	50
    #define HRT_INTERVAL_MAX	50000
    
    /*
     * Period of the free-running counter, in microseconds.
     */
    #define HRT_COUNTER_PERIOD	65536
    
    /*
     * Scaling factor(s) for the free-running counter; convert an input
     * in counts to a time in microseconds.
     */
    #define HRT_COUNTER_SCALE(_c)	(_c)
    
    /*
     * Timer register accessors
     */
    #define REG(_reg)	(*(volatile uint32_t *)(HRT_TIMER_BASE + _reg))
    
    #define rCR1     	REG(STM32_GTIM_CR1_OFFSET)
    #define rCR2     	REG(STM32_GTIM_CR2_OFFSET)
    #define rSMCR    	REG(STM32_GTIM_SMCR_OFFSET)
    #define rDIER    	REG(STM32_GTIM_DIER_OFFSET)
    #define rSR      	REG(STM32_GTIM_SR_OFFSET)
    #define rEGR     	REG(STM32_GTIM_EGR_OFFSET)
    #define rCCMR1   	REG(STM32_GTIM_CCMR1_OFFSET)
    #define rCCMR2   	REG(STM32_GTIM_CCMR2_OFFSET)
    #define rCCER    	REG(STM32_GTIM_CCER_OFFSET)
    #define rCNT     	REG(STM32_GTIM_CNT_OFFSET)
    #define rPSC     	REG(STM32_GTIM_PSC_OFFSET)
    #define rARR     	REG(STM32_GTIM_ARR_OFFSET)
    #define rCCR1    	REG(STM32_GTIM_CCR1_OFFSET)
    #define rCCR2    	REG(STM32_GTIM_CCR2_OFFSET)
    #define rCCR3    	REG(STM32_GTIM_CCR3_OFFSET)
    #define rCCR4    	REG(STM32_GTIM_CCR4_OFFSET)
    #define rDCR     	REG(STM32_GTIM_DCR_OFFSET)
    #define rDMAR    	REG(STM32_GTIM_DMAR_OFFSET)
    
    /*
     * Specific registers and bits used by HRT sub-functions
     */
    /* FIXME! There is an interaction in the CCMR registers that prevents using Chan 1 as the timer and chan 2 as the PPM*/
    #if HRT_TIMER_CHANNEL == 1
    # define rCCR_HRT	rCCR1			/* compare register for HRT */
    # define DIER_HRT	GTIM_DIER_CC1IE		/* interrupt enable for HRT */
    # define SR_INT_HRT	GTIM_SR_CC1IF		/* interrupt status for HRT */
    #elif HRT_TIMER_CHANNEL == 2
    # define rCCR_HRT	rCCR2			/* compare register for HRT */
    # define DIER_HRT	GTIM_DIER_CC2IE		/* interrupt enable for HRT */
    # define SR_INT_HRT	GTIM_SR_CC2IF		/* interrupt status for HRT */
    #elif HRT_TIMER_CHANNEL == 3
    # define rCCR_HRT	rCCR3			/* compare register for HRT */
    # define DIER_HRT	GTIM_DIER_CC3IE		/* interrupt enable for HRT */
    # define SR_INT_HRT	GTIM_SR_CC3IF		/* interrupt status for HRT */
    #elif HRT_TIMER_CHANNEL == 4
    # define rCCR_HRT	rCCR4			/* compare register for HRT */
    # define DIER_HRT	GTIM_DIER_CC4IE		/* interrupt enable for HRT */
    # define SR_INT_HRT	GTIM_SR_CC4IF		/* interrupt status for HRT */
    #else
    # error HRT_TIMER_CHANNEL must be a value between 1 and 4
    #endif
    
    /*
     * Queue of callout entries.
     */
    static struct sq_queue_s	callout_queue;
    
    /* latency baseline (last compare value applied) */
    static uint16_t			latency_baseline;
    
    /* timer count at interrupt (for latency purposes) */
    static uint16_t			latency_actual;
    
    /* latency histogram */
    #define LATENCY_BUCKET_COUNT 8
    //__EXPORT const uint16_t latency_bucket_count = LATENCY_BUCKET_COUNT;
    //__EXPORT const uint16_t	latency_buckets[LATENCY_BUCKET_COUNT] = { 1, 2, 5, 10, 20, 50, 100, 1000 };
    //__EXPORT uint32_t		latency_counters[LATENCY_BUCKET_COUNT + 1];
    const uint16_t  latency_bucket_count = LATENCY_BUCKET_COUNT;
    const uint16_t	latency_buckets[LATENCY_BUCKET_COUNT] = { 1, 2, 5, 10, 20, 50, 100, 1000 };
    uint32_t		latency_counters[LATENCY_BUCKET_COUNT + 1];
    
    
    /* timer-specific functions */
    static void		hrt_tim_init(void);
    static int		hrt_tim_isr(int irq, void *context, void *arg);
    static void		hrt_latency_update(void);
    
    /* callout list manipulation */
    static void		hrt_call_internal(struct hrt_call *entry,
    										 hrt_abstime deadline,
    										 hrt_abstime interval,
    										 hrt_callout callout,
    										 void *arg);
    static void		hrt_call_enter(struct hrt_call *entry);
    static void		hrt_call_reschedule(void);
    static void		hrt_call_invoke(void);
    
    /**
     * Initialise the timer we are going to use.
     *
     * We expect that we'll own one of the reduced-function STM32 general
     * timers, and that we can use channel 1 in compare mode.
     */
    static void
    hrt_tim_init(void)
    {
    	/* claim our interrupt vector */
    	irq_attach(HRT_TIMER_VECTOR, hrt_tim_isr, NULL);
    
    	/* clock/power on our timer */
    	modifyreg32(HRT_TIMER_POWER_REG, 0, HRT_TIMER_POWER_BIT);
    
    	/* disable and configure the timer */
    	rCR1 = 0;
    	rCR2 = 0;
    	rSMCR = 0;
    	rDIER = DIER_HRT ;
    	rCCER = 0;		/* unlock CCMR* registers */
    	rCCMR1 = 0;
    	rCCMR2 = 0;
    	rCCER = 0;
    	rDCR = 0;
    
    	/* configure the timer to free-run at 1MHz */
    	rPSC = (HRT_TIMER_CLOCK / 1000000) - 1;	/* this really only works for whole-MHz clocks */
    
    	/* run the full span of the counter */
    	rARR = 0xffff;
    
    	/* set an initial capture a little ways off */
    	rCCR_HRT = 1000;
    
    	/* generate an update event; reloads the counter, all registers */
    	rEGR = GTIM_EGR_UG;
    
    	/* enable the timer */
    	rCR1 = GTIM_CR1_CEN;
    
    	/* enable interrupts */
    	up_enable_irq(HRT_TIMER_VECTOR);
    }
    
    
    /**
     * Handle the compare interrupt by calling the callout dispatcher
     * and then re-scheduling the next deadline.
     */
    static int
    hrt_tim_isr(int irq, void *context, void *arg)
    {
    	uint32_t status;
    
    	/* grab the timer for latency tracking purposes */
    	latency_actual = rCNT;
    
    	/* copy interrupt status */
    	status = rSR;
    
    	/* ack the interrupts we just read */
    	rSR = ~status;
    
    	/* was this a timer tick? */
    	if (status & SR_INT_HRT) {
    
    		/* do latency calculations */
    		hrt_latency_update();
    
    		/* run any callouts that have met their deadline */
    		hrt_call_invoke();
    
    		/* and schedule the next interrupt */
    		hrt_call_reschedule();
    	}
    
    	return OK;
    }
    
    /**
     * Fetch a never-wrapping absolute time value in microseconds from
     * some arbitrary epoch shortly after system start.
     */
    hrt_abstime
    hrt_absolute_time(void)
    {
    	hrt_abstime	abstime;
    	uint32_t	count;
    	irqstate_t	flags;
    
    	/*
    	 * Counter state.  Marked volatile as they may change
    	 * inside this routine but outside the irqsave/restore
    	 * pair.  Discourage the compiler from moving loads/stores
    	 * to these outside of the protected range.
    	 */
    	static volatile hrt_abstime base_time;
    	static volatile uint32_t last_count;
    
    	/* prevent re-entry */
    	flags = enter_critical_section();
    
    	/* get the current counter value */
    	count = rCNT;
    
    	/*
    	 * Determine whether the counter has wrapped since the
    	 * last time we're called.
    	 *
    	 * This simple test is sufficient due to the guarantee that
    	 * we are always called at least once per counter period.
    	 */
    	if (count < last_count) {
    		base_time += HRT_COUNTER_PERIOD;
    	}
    
    	/* save the count for next time */
    	last_count = count;
    
    	/* compute the current time */
    	abstime = HRT_COUNTER_SCALE(base_time + count);
    
    	leave_critical_section(flags);
    
    	return abstime;
    }
    
    /**
     * Convert a timespec to absolute time
     */
    hrt_abstime
    ts_to_abstime(struct timespec *ts)
    {
    	hrt_abstime	result;
    
    	result = (hrt_abstime)(ts->tv_sec) * 1000000;
    	result += ts->tv_nsec / 1000;
    
    	return result;
    }
    
    /**
     * Convert absolute time to a timespec.
     */
    void
    abstime_to_ts(struct timespec *ts, hrt_abstime abstime)
    {
    	ts->tv_sec = abstime / 1000000;
    	abstime -= ts->tv_sec * 1000000;
    	ts->tv_nsec = abstime * 1000;
    }
    
    /**
     * Compare a time value with the current time.
     */
    hrt_abstime
    hrt_elapsed_time(const volatile hrt_abstime *then)
    {
    	irqstate_t flags = enter_critical_section();
    
    	hrt_abstime delta = hrt_absolute_time() - *then;
    
    	leave_critical_section(flags);
    
    	return delta;
    }
    
    /**
     * Store the absolute time in an interrupt-safe fashion
     */
    hrt_abstime
    hrt_store_absolute_time(volatile hrt_abstime *now)
    {
    	irqstate_t flags = enter_critical_section();
    
    	hrt_abstime ts = hrt_absolute_time();
    
    	leave_critical_section(flags);
    
    	return ts;
    }
    
    /**
     * Initialise the high-resolution timing module.
     */
    void
    hrt_init(void)
    {
    	sq_init(&callout_queue);
    	hrt_tim_init();
    
    #ifdef HRT_PPM_CHANNEL
    	/* configure the PPM input pin */
    	px4_arch_configgpio(GPIO_PPM_IN);
    #endif
    }
    
    /**
     * Call callout(arg) after interval has elapsed.
     */
    void
    hrt_call_after(struct hrt_call *entry, hrt_abstime delay, hrt_callout callout, void *arg)
    {
    	hrt_call_internal(entry,
    			  hrt_absolute_time() + delay,
    			  0,
    			  callout,
    			  arg);
    }
    
    /**
     * Call callout(arg) at calltime.
     */
    void
    hrt_call_at(struct hrt_call *entry, hrt_abstime calltime, hrt_callout callout, void *arg)
    {
    	hrt_call_internal(entry, calltime, 0, callout, arg);
    }
    
    /**
     * Call callout(arg) every period.
     */
    void
    hrt_call_every(struct hrt_call *entry, hrt_abstime delay, hrt_abstime interval, hrt_callout callout, void *arg)
    {
    	hrt_call_internal(entry,
    			  hrt_absolute_time() + delay,
    			  interval,
    			  callout,
    			  arg);
    }
    
    static void
    hrt_call_internal(struct hrt_call *entry, hrt_abstime deadline, hrt_abstime interval, hrt_callout callout, void *arg)
    {
    	irqstate_t flags = enter_critical_section();
    
    	/* if the entry is currently queued, remove it */
    	/* note that we are using a potentially uninitialised
    	   entry->link here, but it is safe as sq_rem() doesn't
    	   dereference the passed node unless it is found in the
    	   list. So we potentially waste a bit of time searching the
    	   queue for the uninitialised entry->link but we don't do
    	   anything actually unsafe.
    	*/
    	if (entry->deadline != 0) {
    		sq_rem(&entry->link, &callout_queue);
    	}
    
    	entry->deadline = deadline;
    	entry->period = interval;
    	entry->callout = callout;
    	entry->arg = arg;
    
    	hrt_call_enter(entry);
    
    	leave_critical_section(flags);
    }
    
    /**
     * If this returns true, the call has been invoked and removed from the callout list.
     *
     * Always returns false for repeating callouts.
     */
    bool
    hrt_called(struct hrt_call *entry)
    {
    	return (entry->deadline == 0);
    }
    
    /**
     * Remove the entry from the callout list.
     */
    void
    hrt_cancel(struct hrt_call *entry)
    {
    	irqstate_t flags = enter_critical_section();
    
    	sq_rem(&entry->link, &callout_queue);
    	entry->deadline = 0;
    
    	/* if this is a periodic call being removed by the callout, prevent it from
    	 * being re-entered when the callout returns.
    	 */
    	entry->period = 0;
    
    	leave_critical_section(flags);
    }
    
    static void
    hrt_call_enter(struct hrt_call *entry)
    {
    	struct hrt_call	*call, *next;
    
    	call = (struct hrt_call *)sq_peek(&callout_queue);
    
    	if ((call == NULL) || (entry->deadline < call->deadline)) {
    		sq_addfirst(&entry->link, &callout_queue);
    		hrtinfo("call enter at head, reschedule
    "); /* we changed the next deadline, reschedule the timer event */ hrt_call_reschedule(); } else { do { next = (struct hrt_call *)sq_next(&call->link); if ((next == NULL) || (entry->deadline < next->deadline)) { hrtinfo("call enter after head
    "); sq_addafter(&call->link, &entry->link, &callout_queue); break; } } while ((call = next) != NULL); } hrtinfo("scheduled
    "); } static void hrt_call_invoke(void) { struct hrt_call *call; hrt_abstime deadline; while (true) { /* get the current time */ hrt_abstime now = hrt_absolute_time(); call = (struct hrt_call *)sq_peek(&callout_queue); if (call == NULL) { break; } if (call->deadline > now) { break; } sq_rem(&call->link, &callout_queue); hrtinfo("call pop
    "); /* save the intended deadline for periodic calls */ deadline = call->deadline; /* zero the deadline, as the call has occurred */ call->deadline = 0; /* invoke the callout (if there is one) */ if (call->callout) { hrtinfo("call %p: %p(%p)
    ", call, call->callout, call->arg); call->callout(call->arg); } /* if the callout has a non-zero period, it has to be re-entered */ if (call->period != 0) { // re-check call->deadline to allow for // callouts to re-schedule themselves // using hrt_call_delay() if (call->deadline <= now) { call->deadline = deadline + call->period; } hrt_call_enter(call); } } } /** * Reschedule the next timer interrupt. * * This routine must be called with interrupts disabled. */ static void hrt_call_reschedule() { hrt_abstime now = hrt_absolute_time(); struct hrt_call *next = (struct hrt_call *)sq_peek(&callout_queue); hrt_abstime deadline = now + HRT_INTERVAL_MAX; /* * Determine what the next deadline will be. * * Note that we ensure that this will be within the counter * period, so that when we truncate all but the low 16 bits * the next time the compare matches it will be the deadline * we want. * * It is important for accurate timekeeping that the compare * interrupt fires sufficiently often that the base_time update in * hrt_absolute_time runs at least once per timer period. */ if (next != NULL) { hrtinfo("entry in queue
    "); if (next->deadline <= (now + HRT_INTERVAL_MIN)) { hrtinfo("pre-expired
    "); /* set a minimal deadline so that we call ASAP */ deadline = now + HRT_INTERVAL_MIN; } else if (next->deadline < deadline) { hrtinfo("due soon
    "); deadline = next->deadline; } } hrtinfo("schedule for %u at %u
    ", (unsigned)(deadline & 0xffffffff), (unsigned)(now & 0xffffffff)); /* set the new compare value and remember it for latency tracking */ rCCR_HRT = latency_baseline = deadline & 0xffff; } static void hrt_latency_update(void) { uint16_t latency = latency_actual - latency_baseline; unsigned index; /* bounded buckets */ for (index = 0; index < LATENCY_BUCKET_COUNT; index++) { if (latency <= latency_buckets[index]) { latency_counters[index]++; return; } } /* catch-all at the end */ latency_counters[index]++; } void hrt_call_init(struct hrt_call *entry) { memset(entry, 0, sizeof(*entry)); } void hrt_call_delay(struct hrt_call *entry, hrt_abstime delay) { entry->deadline = hrt_absolute_time() + delay; } #endif /* HRT_TIMER */

    移植topic


    PX 4のメッセージはpythonで自動的に生成されますが、結果だけに注目すればいいので、最終的に生成されたヘッダファイルに従って作成すればOKです.ヘッダファイルの下に置いて、下にコードを貼ります.
    /****************************************************************************
     *
     *   Copyright (C) 2013-2016 PX4 Development Team. All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in
     *    the documentation and/or other materials provided with the
     *    distribution.
     * 3. Neither the name PX4 nor the names of its contributors may be
     *    used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     *
     ****************************************************************************/
     
    #pragma once
     
    #include 
    #ifdef __cplusplus
    #include 
    #else
    #include 
    #endif
     
    #include "../uorb/uORB.h"
     
     
    #ifndef __cplusplus
    #define RELATIVE_TIMESTAMP_INVALID 2147483647
     
    #endif
     
     
    #ifdef __cplusplus
    struct __EXPORT sensor_combined_s {
    #else
    struct sensor_combined_s {
    #endif
        uint64_t timestamp; // required for logger
        float gyro_rad[3];
        uint32_t gyro_integral_dt;
        int32_t accelerometer_timestamp_relative;
        float accelerometer_m_s2[3];
        uint32_t accelerometer_integral_dt;
        int32_t magnetometer_timestamp_relative;
        float magnetometer_ga[3];
        int32_t baro_timestamp_relative;
        float baro_alt_meter;
        float baro_temp_celcius;
     
    #ifdef __cplusplus
        static constexpr int32_t RELATIVE_TIMESTAMP_INVALID = 2147483647;
     
    #endif
    };
     
    /* register this as object request broker structure */
    ORB_DEFINE(sensor_combined, struct sensor_combined_s,0,0);
    ORB_DECLARE(sensor_combined);
    
    

    ここでは基本的に成功しましたが、最終的なファイル構造はこうです.
    $ tree -L 2             
    .
    ├── device
    │   ├── CDev.cxx
    │   ├── CDev.hpp
    │   ├── cdev_platform.cxx
    │   ├── cdev_platform.hpp
    │   ├── device.h
    │   ├── Device.hpp
    │   ├── drv_device.h
    │   └── drv_orb_dev.h
    ├── Kconfig
    ├── Make.defs
    ├── Makefile
    ├── topic
    │   └── sensor_combined.h
    └── uorb
        ├── Kconfig
        ├── Make.defs
        ├── Make.dep
        ├── Makefile
        ├── ORBMap.hpp
        ├── ORBSet.hpp
        ├── Publication.cxx
        ├── Publication.hpp
        ├── Subscription.cxx
        ├── Subscription.hpp
        ├── uORBCommon.hpp
        ├── uORBCommunicator.hpp
        ├── uORB.cxx
        ├── uORBDevices.cxx
        ├── uORBDevices.hpp
        ├── uORB.h
        ├── uORBMain.cxx
        ├── uORBManager.cxx
        ├── uORBManager.hpp
        ├── uORBTopics.h
        ├── uORBUtils.cxx
        └── uORBUtils.hpp
    
    3 directories, 34 files
    

    最後にmain関数を貼ります.
    /****************************************************************************
     *
     *   Copyright (c) 2012-2015 PX4 Development Team. All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in
     *    the documentation and/or other materials provided with the
     *    distribution.
     * 3. Neither the name PX4 nor the names of its contributors may be
     *    used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     *
     ****************************************************************************/
    #include 
    #include 
    
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    
    #include "platform/cxxinitialize.h"
    
    
    
    #include "uORBDevices.hpp"
    #include "uORBManager.hpp"
    #include "uORB.h"
    #include "uORBCommon.hpp"
    
    extern "C" { int uorb_main(int argc, char *argv[]); }
    
    static uORB::DeviceMaster *g_dev = nullptr;
    static void usage()
    {
    	printf("uorb communication
    "); printf("start
    "); printf("Print topic statistics
    "); printf("Monitor topic publication rates
    "); printf("print all instead of only currently publishing topics
    "); printf(" [] topic(s) to match (implies -a)
    "); } int uorb_main(int argc, char *argv[]) { if (argc < 2) { usage(); return -EINVAL; } /* * Start/load the driver. */ if (!strcmp(argv[1], "start")) { if (g_dev != nullptr) { syslog(LOG_INFO,"already loaded"); /* user wanted to start uorb, its already running, no error */ return 0; } if (!uORB::Manager::initialize()) { syslog(LOG_INFO,"uorb manager alloc failed"); return -ENOMEM; } /* create the driver */ g_dev = uORB::Manager::get_instance()->get_device_master(); if (g_dev == nullptr) { return -errno; } return OK; } /* * Print driver information. */ if (!strcmp(argv[1], "status")) { if (g_dev != nullptr) { g_dev->printStatistics(true); } else { syslog(LOG_INFO,"uorb is not running
    "); } return OK; } if (!strcmp(argv[1], "top")) { if (g_dev != nullptr) { g_dev->showTop(argv + 2, argc - 2); } else { syslog(LOG_INFO,"uorb is not running
    "); } return OK; } usage(); return -EINVAL; }

    これで移植の仕事は終わりました.この文章はただ1種の移植の構想を提供しただけで、きっと多くの地方が最適化して改正する価値があって、交流の指摘を歓迎します.