Apple Silicon MacでST-LINK Bridge SDK (C++) を動作させる方法
ST-LINK V3のBridge機能(I2C/SPI/GPIO等)をC++で制御するためのSDKを、macOS(M1/M2/M3)環境でビルド・実行する際のトラブルシューティングと最終構成をまとめます。
1. 発生した主な問題
-
リンクエラー:
STLinkInterface::EnumDevices等のシンボルが見つからない(.cppファイルの不足)。 - 実行時エラー (Status 2): ライブラリは存在するが、実行時に動的ロードができていない。
-
依存ライブラリ不足:
libSTLinkUSBDriver.dylibがlibusbを見つけられずクラッシュする。
2. 最終的なプロジェクト構成
プロジェクトルートに必要なライブラリ(.dylib)と、SDKのソースコード(sharedStlk)を配置します。
.
├── CMakeLists.txt
├── main.cpp
├── device_number.cpp
├── libSTLinkUSBDriver.dylib
├── libusb-1.0.0.dylib
└── sharedStlk/
├── bridge/ (bridge.cpp, bridge.h ...)
├── common/ (stlink_interface.cpp, stlink_interface.h ...)
└── error/ (ErrLog.cpp, ErrLog.h ...)
3. CMakeLists.txt の最終形
SDKのラッパー部分(.cpp)をすべてコンパイル対象に含め、ライブラリをリンクします。
cmake_minimum_required(VERSION 3.20) # 4.1は互換性を考慮し3.20以上を推奨
project(STLink_bridge)
set(CMAKE_CXX_STANDARD 20)
# 1. パスとライブラリの設定
set(ST_INCLUDE_DIR "./sharedStlk")
set(ST_LIBRARY
"${CMAKE_CURRENT_SOURCE_DIR}/libSTLinkUSBDriver.dylib"
"${CMAKE_CURRENT_SOURCE_DIR}/libusb-1.0.0.dylib"
)
# 2. ヘッダー検索パスの設定
include_directories(
${ST_INCLUDE_DIR}/bridge
${ST_INCLUDE_DIR}/common
${ST_INCLUDE_DIR}/error
)
# 3. SDKのラッパーソースコードをすべて取得
file(GLOB_RECURSE ST_SOURCES "${ST_INCLUDE_DIR}/*.cpp")
# 4. 実行ファイルの作成
add_executable(${PROJECT_NAME}
main.cpp
device_number.cpp
${ST_SOURCES}
)
# 5. ライブラリのリンク
target_link_libraries(${PROJECT_NAME} PRIVATE ${ST_LIBRARY})
4. 実行コードの実装 (device_number.cpp)
最大の解決策は、LoadStlinkLibrary() を呼び出して .dylib を明示的にロードすることです。
/**
* @file device_number.cpp
* @brief ST-LINK デバイスのスキャンと認識テスト
*/
#include <iostream>
#include "stlink_interface.h"
int main() {
uint32_t numDevices = 0;
// 1. インターフェースのインスタンスを作成
STLinkInterface stLinkIf;
// 2. ライブラリを動的にロード (ここが解決の鍵)
// ※ 絶対パスで指定することで、実行時の DLL_ERR (Status 2) を回避します
stLinkIf.LoadStlinkLibrary("/Users/curesaba/Desktop/stm32/STLink-bridge/libSTLinkUSBDriver.dylib");
// 3. デバイスをスキャン (第2引数 true でリフレッシュ強制)
STLinkIf_StatusT status = stLinkIf.EnumDevices(&numDevices, true);
if (status != STLINKIF_NO_ERR) {
std::cerr << "スキャン中にエラーが発生しました。Status: " << (int)status << std::endl;
return -1;
}
// 4. 結果表示
if (numDevices == 0) {
std::cout << "ST-LINKが見つかりません。USB接続またはOSの認識を確認してください。" << std::endl;
} else {
std::cout << numDevices << " 台の ST-LINK を発見しました。" << std::endl;
}
return 0;
}
5. 解決のポイントまとめ
- ソースコードの追加: SDKはライブラリ(dylib)だけでなく、それを制御するラッパー(cpp)を一緒にビルドして初めて機能する。
-
動的ロード:
LoadStlinkLibraryを呼ばないと内部の関数ポインタが空のままになり、EnumDevicesが失敗する。