日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PX4模块设计之四十一:I2C/SPI Bus Instance基础知识

發布時間:2024/3/26 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PX4模块设计之四十一:I2C/SPI Bus Instance基础知识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PX4模塊設計之四十一:I2C/SPI Bus Instance基礎知識

  • 1. 基礎知識
  • 2. 基礎類和定義
    • 2.1 ListNode類
    • 2.2 List類
    • 2.3 BusCLIArguments類
    • 2.4 BusInstanceIterator類
    • 2.5 I2CSPIInstance類
    • 2.6 I2CSPIDriverBase類
    • 2.7 I2CSPIDriver類
    • 2.8 I2C/SPI總線選項
  • 3. 總結
  • 4. 參考資料

1. 基礎知識

  • ListNode類
  • List類
  • BusCLIArguments類
  • BusInstanceIterator類
  • I2CSPIInstance類
  • I2CSPIDriverBase類
  • I2CSPIDriver類
  • I2C/SPI總線選項
  • 2. 基礎類和定義

    2.1 ListNode類

    主要功能描述:

  • 采用類模板擴展ListNode應用范圍
  • 通過 setSibling 設置成員變量_list_node_sibling
  • 通過 getSibling 獲取成員變量_list_node_sibling
  • 注:這個類類似于C語言單向鏈表的一個節點結構聲明。

    class ListNode

    template<class T> class ListNode { public:void setSibling(T sibling) { _list_node_sibling = sibling; }const T getSibling() const { return _list_node_sibling; }protected:T _list_node_sibling{nullptr};};

    2.2 List類

    主要功能描述:

  • 基于ListNode類實現了單鏈表功能
  • 支持新增一個ListNode操作: void add(T newNode)
  • 支持刪除一個ListNode操作: bool remove(T removeNode)/void deleteNode(T node)
  • 支持列表是否為空判斷: bool empty()
  • 支持列表清空操作: void clear()
  • 支持列表元素數量獲取: size_t size()
  • 支持列表頭元素獲取: const T getHead()
  • 支持Iterator操作: Iterator begin()/Iterator end()
  • class List

    template<class T> class List { public:void add(T newNode){if (_head == nullptr) {// list is empty, add as head_head = newNode;return;} else {// find last node and add to endT node = _head;while (node != nullptr) {if (node->getSibling() == nullptr) {// found last node, now add newNodenode->setSibling(newNode);return;}node = node->getSibling();}}}bool remove(T removeNode){if (removeNode == nullptr) {return false;}// base caseif (removeNode == _head) {if (_head != nullptr) {_head = _head->getSibling();}removeNode->setSibling(nullptr);return true;}for (T node = getHead(); node != nullptr; node = node->getSibling()) {// is sibling the node to remove?if (node->getSibling() == removeNode) {// replace siblingif (node->getSibling() != nullptr) {node->setSibling(node->getSibling()->getSibling());} else {node->setSibling(nullptr);}removeNode->setSibling(nullptr);return true;}}return false;}struct Iterator {T node;explicit Iterator(T v) : node(v) {}operator T() const { return node; }operator T &() { return node; }const T &operator* () const { return node; }Iterator &operator++ (){if (node) {node = node->getSibling();}return *this;}};Iterator begin() { return Iterator(getHead()); }Iterator end() { return Iterator(nullptr); }const T getHead() const { return _head; }bool empty() const { return getHead() == nullptr; }size_t size() const{size_t sz = 0;for (auto node = getHead(); node != nullptr; node = node->getSibling()) {sz++;}return sz;}void deleteNode(T node){if (remove(node)) {// only delete if node was successfully removeddelete node;}}void clear(){auto node = getHead();while (node != nullptr) {auto next = node->getSibling();delete node;node = next;}_head = nullptr;}protected:T _head{nullptr}; };

    2.3 BusCLIArguments類

    命令行參數配置總線設備。

    主要功能描述:

  • 支持總線參數命令行解析: parseDefaultArguments
  • 支持總線參數檢查: validateConfiguration
  • 總線參數類型:I2C(_i2c_support) or SPI(_spi_support)
  • 支持總線選項: I2C/SPI 內部/外部(bus_option)
  • 內部總線號(requested_bus)
  • 支持總線工作頻率設置(bus_frequency)
  • 支持靜默啟動功能(quiet_start) //do not print a message when startup fails
  • 【代碼中未見相關功能】支持總線PNP動態功能???(keep_running) //eep driver running even if no device is detected on startup
  • 支持是否需要keep_running功能(support_keep_running) //true if keep_running (see above) is supported
  • 支持硬件mount方向修正(rotation) //sensor rotation (MAV_SENSOR_ROTATION_* or distance_sensor_s::ROTATION_*)
  • 支持設備相關自定義參數(custom1/custom2/custom_data) //driver-specific custom argument
  • I2C 總線
    I2C Slave地址(i2c_address)
    I2C默認頻率(default_i2c_frequency)
  • SPI 總線
    SPI芯片選擇(chipselect)
    SPI工作模式(spi_mode)
    SPI默認頻率(default_spi_frequency)
  • class BusCLIArguments

    class BusCLIArguments { public:BusCLIArguments(bool i2c_support, bool spi_support) #if defined(CONFIG_I2C) || defined(CONFIG_SPI): #endif // CONFIG_I2C || CONFIG_SPI #if defined(CONFIG_I2C)_i2c_support(i2c_support) #endif // CONFIG_I2C #if defined(CONFIG_I2C) && defined(CONFIG_SPI), #endif // CONFIG_I2C && CONFIG_SPI #if defined(CONFIG_SPI)_spi_support(spi_support) #endif // CONFIG_SPI{}/*** Parse CLI arguments (for drivers that don't need any custom arguments, otherwise getopt() should be used)* @return command (e.g. "start") or nullptr on error or unknown argument*/const char *parseDefaultArguments(int argc, char *argv[]);/*** Like px4_getopt(), but adds and handles i2c/spi driver-specific arguments*/int getOpt(int argc, char *argv[], const char *options);/*** returns the current optional argument (for options like 'T:'), or the command (e.g. "start")* @return nullptr or argument/command*/const char *optArg() const { return _optarg; }I2CSPIBusOption bus_option{I2CSPIBusOption::All};int requested_bus{-1};int bus_frequency{0}; #if defined(CONFIG_SPI)int chipselect {-1};spi_mode_e spi_mode{SPIDEV_MODE3}; #endif // CONFIG_SPI #if defined(CONFIG_I2C)uint8_t i2c_address {0}; ///< I2C address (a driver must set the default address) #endif // CONFIG_I2Cbool quiet_start {false}; ///< do not print a message when startup failsbool keep_running{false}; ///< keep driver running even if no device is detected on startupRotation rotation{ROTATION_NONE}; ///< sensor rotation (MAV_SENSOR_ROTATION_* or distance_sensor_s::ROTATION_*)int custom1{0}; ///< driver-specific custom argumentint custom2{0}; ///< driver-specific custom argumentvoid *custom_data{nullptr}; ///< driver-specific custom argument// driver defaults, if not specified via CLI #if defined(CONFIG_SPI)int default_spi_frequency {-1}; ///< default spi bus frequency (driver needs to set this) [Hz] #endif // CONFIG_SPI #if defined(CONFIG_I2C)int default_i2c_frequency {-1}; ///< default i2c bus frequency (driver needs to set this) [Hz] #endif // CONFIG_I2Cbool support_keep_running{false}; ///< true if keep_running (see above) is supportedprivate:bool validateConfiguration();char _options[32] {};int _optind{1};const char *_optarg{nullptr}; #if defined(CONFIG_I2C)const bool _i2c_support; #endif // CONFIG_I2C #if defined(CONFIG_SPI)const bool _spi_support; #endif // CONFIG_SPI };

    2.4 BusInstanceIterator類

    使用給定的過濾器選項迭代運行實例和/或配置的I2C/SPI總線。

    主要功能描述:

  • 支持I2C/SPI總線配置
  • 支持I2C/SPI總線設備添加
  • 支持I2C/SPI總線設備移除
  • 支持I2C/SPI總線設備相關屬性的獲取
  • class BusInstanceIterator

    class BusInstanceIterator { public:BusInstanceIterator(const char *module_name, const BusCLIArguments &cli_arguments, uint16_t devid_driver_index);~BusInstanceIterator();I2CSPIBusOption configuredBusOption() const { return _bus_option; }int runningInstancesCount() const;bool next();I2CSPIInstance *instance() const;void removeInstance();board_bus_types busType() const;int bus() const;uint32_t devid() const;#if defined(CONFIG_SPI)spi_drdy_gpio_t DRDYGPIO() const; #endif // CONFIG_SPIbool external() const;int externalBusIndex() const;int busDeviceIndex() const;void addInstance(I2CSPIInstance *instance);#if defined(CONFIG_I2C)static I2CBusIterator::FilterType i2cFilter(I2CSPIBusOption bus_option); #endif // CONFIG_I2C #if defined(CONFIG_SPI)static SPIBusIterator::FilterType spiFilter(I2CSPIBusOption bus_option); #endif // CONFIG_SPIconst char *moduleName() const { return _module_name; }uint16_t devidDriverIndex() const { return _devid_driver_index; }private:const char *_module_name;const I2CSPIBusOption _bus_option;const uint16_t _devid_driver_index; #if defined(CONFIG_I2C)const uint8_t _i2c_address; #endif // CONFIG_I2C #if defined(CONFIG_SPI)SPIBusIterator _spi_bus_iterator; #endif // CONFIG_SPI #if defined(CONFIG_I2C)I2CBusIterator _i2c_bus_iterator; #endif // CONFIG_I2CList<I2CSPIInstance *>::Iterator _current_instance; };

    2.5 I2CSPIInstance類

    I2CSPI實例類對象定義。

    主要功能描述:

  • 支持I2C/SPI總線實例對象類聲明
  • 支持I2C/SPI總線類對象BusInstanceIterator/I2CSPIDriverBase友元類
  • class I2CSPIInstance

    class I2CSPIInstance : public ListNode<I2CSPIInstance *> { public:virtual ~I2CSPIInstance() = default; #if defined(CONFIG_I2C)virtual int8_t get_i2c_address() {return _i2c_address;} #endif // CONFIG_I2C private:I2CSPIInstance(const I2CSPIDriverConfig &config): _module_name(config.module_name), _bus_option(config.bus_option), _bus(config.bus),_devid_driver_index(config.devid_driver_index), _bus_device_index(config.bus_device_index) #if defined(CONFIG_I2C), _i2c_address(config.i2c_address) #endif // CONFIG_I2C{}friend class BusInstanceIterator;friend class I2CSPIDriverBase;const char *_module_name;const I2CSPIBusOption _bus_option;const int _bus;const uint16_t _devid_driver_index;const int8_t _bus_device_index; #if defined(CONFIG_I2C)const int8_t _i2c_address; ///< I2C address (optional) #endif // CONFIG_I2C };

    2.6 I2CSPIDriverBase類

    I2CSPI驅動基礎功能類對象定義。

    主要功能描述:

  • 支持I2C/SPI驅動基礎功能模塊啟動
  • 支持I2C/SPI驅動基礎功能模塊停止
  • 支持I2C/SPI驅動基礎功能模塊狀態查詢
  • class I2CSPIDriverBase

    class I2CSPIDriverBase : public px4::ScheduledWorkItem, public I2CSPIInstance { public:I2CSPIDriverBase(const I2CSPIDriverConfig &config): ScheduledWorkItem(config.module_name, config.wq_config),I2CSPIInstance(config) {}static int module_stop(BusInstanceIterator &iterator);static int module_status(BusInstanceIterator &iterator);static int module_custom_method(const BusCLIArguments &cli, BusInstanceIterator &iterator,bool run_on_work_queue = true);using instantiate_method = I2CSPIDriverBase * (*)(const I2CSPIDriverConfig &config, int runtime_instance); protected:virtual ~I2CSPIDriverBase() = default;virtual void print_status();virtual void custom_method(const BusCLIArguments &cli) {}/*** Exiting the module. A driver can override this, for example to unregister interrupt callbacks.* This will be called from the work queue.* A module overriding this, needs to call I2CSPIDriverBase::exit_and_cleanup() as the very last statement.*/virtual void exit_and_cleanup() { ScheduleClear(); _task_exited.store(true); }bool should_exit() const { return _task_should_exit.load(); }static int module_start(const BusCLIArguments &cli, BusInstanceIterator &iterator, void(*print_usage)(),instantiate_method instantiate);private:static void custom_method_trampoline(void *argument);void request_stop_and_wait();px4::atomic_bool _task_should_exit{false};px4::atomic_bool _task_exited{false}; };

    2.7 I2CSPIDriver類

    I2CSPI驅動類對象定義。

    主要功能描述:

  • 支持驅動定制啟動
  • 支持驅動定義業務運行邏輯
  • class I2CSPIDriver

    template<class T> class I2CSPIDriver : public I2CSPIDriverBase { public:static int module_start(const BusCLIArguments &cli, BusInstanceIterator &iterator){return I2CSPIDriverBase::module_start(cli, iterator, &T::print_usage, InstantiateHelper<T>::m);}protected:I2CSPIDriver(const I2CSPIDriverConfig &config): I2CSPIDriverBase(config) {}virtual ~I2CSPIDriver() = default;// *INDENT-OFF* remove once there's astyle >3.1 in CIvoid Run() final{static_cast<T *>(this)->RunImpl();if (should_exit()) {exit_and_cleanup();}}// *INDENT-ON* private:// SFINAE to use R::instantiate if it exists, and R::instantiate_default otherwisetemplate <typename R>class InstantiateHelper{template <typename C>static constexpr I2CSPIDriverBase::instantiate_method get(decltype(&C::instantiate)) { return &C::instantiate; }template <typename C>static constexpr I2CSPIDriverBase::instantiate_method get(...) { return &C::instantiate_default; }public:static constexpr I2CSPIDriverBase::instantiate_method m = get<R>(0);};static I2CSPIDriverBase *instantiate_default(const I2CSPIDriverConfig &config, int runtime_instance){T *instance = new T(config);if (!instance) {PX4_ERR("alloc failed");return nullptr;}if (OK != instance->init()) {delete instance;return nullptr;}return instance;} };

    2.8 I2C/SPI總線選項

    PX4系統的I2C/SPI總線分為I2C內部和外部,以及SPI內部和外部四大類。

    enum class I2CSPIBusOption : uint8_t {All = 0, ///< select all runnning instances #if defined(CONFIG_I2C)I2CInternal,I2CExternal, #endif // CONFIG_I2C #if defined(CONFIG_SPI)SPIInternal,SPIExternal, #endif // CONFIG_SPI };

    3. 總結

    注:暫時先整理這些內容,后續隨著代碼閱讀的增加,再補充完善。

    4. 參考資料

    【1】PX4開源軟件框架簡明簡介
    【2】PX4模塊設計之十二:High Resolution Timer設計
    【3】PX4模塊設計之十三:WorkQueue設計

    總結

    以上是生活随笔為你收集整理的PX4模块设计之四十一:I2C/SPI Bus Instance基础知识的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。