Bluetoothプロトコルスタック(7つ、他のプラットフォームに移植)

このセクションでは、さまざまなハードウェアプラットフォームに合わせて調整する必要があるBTstackコンポーネントに焦点を当てます。

時間抽象化レイヤー

BTstackには、納期を理解する方法が必要です。btstack_run_loop_embedded.cは、2つの異なるモード(システムマークまたはミリ秒単位のシステムクロック)をサポートします。2番目の範囲のBluetoothタイムアウトのみを処理する必要があるため、BTstackのタイミング要件は非常に低くなっています。

ティックハードウェアの抽象化

プラットフォームがシステムクロックを必要としない場合、またはシステムクロックが既にある場合(これはARM CortexデバイスのCMSISのデフォルト設定であるため)、それを使用して、BTStackの時間の抽象化をinclude / btstack / hal_tick.h>に実装できます。

これには、btstack_config.hでHAVE_EMBEDDED_TICKを定義する必要があります。

#define HAVE_EMBEDDED_TICK

次に、hal_tick_init関数とhal_tick_set_handler関数を実装する必要があります。これらは、実行ループの初期化中に呼び出されます。

void hal_tick_init(void);

void hal_tick_set_handler(void(* tick_handler)(void));

int hal_tick_get_tick_period_in_ms(void);

BTstackがhal_tick_init()およびhal_tick_set_handler(tick_handler)を呼び出した後、tick_handlerがhal_tick_get_tick_period_in_ms()ミリ秒ごとに呼び出されることが予想されます。

時間MSハードウェアの抽象化

プラットフォームにすでにシステムクロックがあるか、そのようなクロックを提供する方が便利な場合は、インクルード/ btstack / hal_time_ms.hでTime MS Hardware Abstractionを使用できます。

これには、btstack_config.hでHAVE_EMBEDDED_TIME_MSを定義する必要があります。

#define HAVE_EMBEDDED_TIME_MS

次に、関数hal_time_ms()を実装する必要があります。これは、BTstackの実行ループから呼び出され、将来のタイマーを設定するときに呼び出されます。時間をミリ秒単位で返す必要があります。

uint32_t hal_time_ms(void);

Bluetoothハードウェア制御API

Bluetoothハードウェア制御APIは、HCIレイヤー用のカスタム初期化スクリプト、ベンダー固有のボーレート変更コマンド、およびシステム電源通知を提供できます。Bluetoothモジュールの電源モードを制御するためにも使用されます。つまり、オン/オフを切り替えて、スリープモードに入ります。さらに、Bluetoothモジュールがハードウェアエラーを報告したときに呼び出されるエラーハンドラーhw_errorも提供します。コールバックにより、この障害の永続的な記録またはシグナリングが可能になります。

一般に、struct btstack_control_tは、Bluetooth仕様でカバーされていない一般的な機能をカプセル化します。たとえば、btstack_chipset_cc256x_in-stance関数は、CC256xチップセットに適した制御構造へのポインターを返します。

人間とコンピューターの相互作用の実装

組み込みシステムでは、BluetoothモジュールはUSBまたはUARTポートを介して接続できます。BTstackは、ホストとBluetoothモジュール間でHCIコマンド、イベント、およびデータを送信するための3つのUARTベースのプロトコルを実装します。HCIUARTトランスミッションレイヤー(H4)、eHCILLをサポートするH4、およびTexas Instrumentsの軽量で低消費電力の変更本体、および3線式UART送信層(H5)。

HCI UART送信層(H4)

ほとんどの組み込みUARTインターフェイスはバイトレベルで動作し、バイトを受信するとプロセッサ割り込みを生成します。割り込みハンドラーで、パブリックUARTドライバーは受信したデータをリングバッファーに入れ、フラグを設定してさらに処理するか、上位レベルのコード(この場合はBluetoothスタック)に通知します。

Bluetooth通信はデータパケットに基づいており、1つのデータパケットには最大1021バイトを含めることができます。バイトごとにBluetoothスタックのデータ受信ハンドラーを呼び出すと、不要なオーバーヘッドが発生します。これを回避するには、Bluetoothデータパケットを複数のブロックとして読み取ることができます。読み取るブロックの量は事前にわかっています。可能であれば、これらのブロック読み取りにはオンチップDMAモジュールを使用することをお勧めします。

BTstack UARTハードウェアアブストラクションレイヤーAPIはこの設計方法を反映しており、基になるUARTドライバーは次のAPIを実装する必要があります。

void hal_uart_dma_init(void);

void hal_uart_dma_set_block_received(void(* block_handler)(void));

void hal_uart_dma_set_block_sent(void(* block_handler)(void));

int hal_uart_dma_set_baud(uint32_t baud);

void hal_uart_dma_send_block(const uint8_t * buffer、uint16_t len);

void hal_uart_dma_receive_block(uint8_t * buffer、uint16_t len);

組み込みシステムの主なHCI H4実装は、hci_h4_transport-_dma関数です。この関数は、次のシーケンスを呼び出します:hal_uart_dma_init、hal_uart_dma_set_block_received、およびhal_uart_dma_set_block_sent関数。このシーケンスでは、HCIレイヤーはhal_uart-_dma_receive_block関数を呼び出してパケット処理を開始します。HAL実装は、要求されたバイト数を読み取り、要求された量のデータを受信したときにRTSラインを介して着信データを停止し、ハンドラーを呼び出す必要があります。このようにして、HAL実装は普遍的なままであり、各HCIパケットは3つのコールバックのみを必要とします。

H4はeHCILLをサポート

標準のH4プロトコルインターフェイスを使用すると、ホストもベースバンドコントローラーもスリープモードに入ることができません。公式のH5プロトコルに加えて、さまざまなチップベンダーが独自のソリューションを提案しています。Texas Instruments(TI)eHCILLのサポートにより、ホストおよびベースバンドコントローラーは、HCI H4トランスポート層との同期を失うことなく、独立してスリープモードに入ることができます。IRQ駆動のブロックRXおよびTXに加えて、eHCILLはCTS割り込みをコールバックする必要もあります。

void hal_uart_dma_set_cts_irq_handler(void(* cts_irq_handler)(void));

void hal_uart_dma_set_sleep(uint8_t sleep);

H5

H5はSLIPプロトコルを使用してデータパケットを送信し、再送信によりデータパケットの損失とビットエラーを処理します。パケット損失から回復できるため、どちらの側も同期を失うことなくスリープモードに入ることができます。

H5でのハードウェアフロー制御の使用はオプションですが、BTstackはパケットバッファリングを回避するためにハードウェアフロー制御を使用するため、RTS / CTSでのみH5を使用することをお勧めします。

移行の場合、実装は上記の従来のH4プロトコルに従います。

永続ストレージAPI

組み込みシステムでは、デバイスのタイプごとに独自の機能、機能、制限があるため、リンクキーやリモートデバイス名などのデータを保存する一般的な方法はありません。永続ストレージAPIは、特定のシステムに特定のドライバーを実装するためのインターフェースを提供します。

リンクキーDB

例として、テスト目的で、BTstackはメモリのみの実装btstack_link_key_db_memoryを提供します。実装は、以下のリストのインターフェースに準拠する必要あります。

typedef struct {

//管理

void(* open)();

void(* close)();

 

//リンクキー

int(* get_link_key)(bd_addr_t bd_addr、link_key_t link_key);

void(* put_link_key)(bd_addr_t bd_addr、link_key_t key);

void(* delete_link_key)(bd_addr_t bd_addr);

} btstack_link_key_db_t;

 

 

105件の元の記事を公開 30のような 16万人以上の訪問者

おすすめ

転載: blog.csdn.net/happygrilclh/article/details/100743632