Fluoride Module

25 年 11 月 12 日 星期三 (已编辑)
452 字
3 分钟
fluoride-module.excalidraw
fluoride-module.excalidraw

定义 module.h

module.h 中定义了模块生命周期操作. 核心 struct module_t 声明了模块定义, 每个模块通过 module_t 提供对应操作. 同时定义了调用模块生命周期的函数:

system/btcore/include/module.hc
typedef future_t* (*module_lifecycle_fn)(void);

typedef struct {
  const char* name{nullptr};
  module_lifecycle_fn init{nullptr};
  module_lifecycle_fn start_up{nullptr};
  module_lifecycle_fn shut_down{nullptr};
  module_lifecycle_fn clean_up{nullptr};
  const char* dependencies[BTCORE_MAX_MODULE_DEPENDENCIES]{nullptr};
} module_t;

bool module_init(const module_t* module);
bool module_start_up(const module_t* module);
void module_shut_down(const module_t* module);
void module_clean_up(const module_t* module);

实现 module.cc

module_init, module_start_up, module_shut_down, module_clean_up 实现流程都类似, 以 module_init 为例, 整体流程如下:

  1. 检查 module 状态
  2. 调用 call_lifecycle_function, 调用失败返回false
  3. 修改 module 状态
system/btcore/src/module.ccc
bool module_init(const module_t* module) {
  log::assert_that(module != NULL, "assert failed: module != NULL");
  log::assert_that(get_module_state(module) == MODULE_STATE_NONE,
                   "assert failed: get_module_state(module) == MODULE_STATE_NONE");

  if (!call_lifecycle_function(module->init)) {
    log::error("Failed to initialize module \"{}\"", module->name);
    return false;
  }

  set_module_state(module, MODULE_STATE_INITIALIZED);
  return true;
}

call_lifecycle_function 也很清晰, 就是同步等待相应的生命周期函数执行完成:

  1. NULL 表示该生命周期函数不需要执行, 返回true
  2. 调用生命周期函数, 如果返回的 future 为空表示同步执行完成
  3. 通过 future_await, 等待执行完成
filec
static bool call_lifecycle_function(module_lifecycle_fn function) {
  // A NULL lifecycle function means it isn't needed, so assume success
  if (!function) {
    return true;
  }

  future_t* future = function();

  // A NULL future means synchronous success
  if (!future) {
    return true;
  }

  // Otherwise fall back to the future
  return future_await(future);
}

module.cc 实现的细节:

  • enum module_state_t 定义模块的状态
  • metadata 用于保存每个模块当前的状态
  • metadata_mutex 互斥量, 保证模块状态一致性
  • get_module_state, set_module_state, is_module_started 封装了状态相关操作.
system/btcore/src/module.ccc
typedef enum {
  MODULE_STATE_NONE = 0,
  MODULE_STATE_INITIALIZED = 1,
  MODULE_STATE_STARTED = 2
} module_state_t;

static std::unordered_map<const module_t*, module_state_t> metadata;

static std::mutex metadata_mutex;

static module_state_t get_module_state(const module_t* module) {
  std::lock_guard<std::mutex> lock(metadata_mutex);
  auto map_ptr = metadata.find(module);

  return (map_ptr != metadata.end()) ? map_ptr->second : MODULE_STATE_NONE;
}

static void set_module_state(const module_t* module, module_state_t state) {
  std::lock_guard<std::mutex> lock(metadata_mutex);
  metadata[module] = state;
}

bool is_module_started(const module_t* module) {
  std::lock_guard<std::mutex> lock(metadata_mutex);
  auto map_ptr = metadata.find(module);
  return map_ptr != metadata.end() && map_ptr->second == MODULE_STATE_STARTED;
}

文章标题:Fluoride Module

文章作者:zabbits

文章链接:https://zabbits.com/posts/bluetooth/fluoride_module[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。