SCP-Firmware 核心代码
queue处理片段
scp-firmware/framework/src/fwk_thread.cnoreturn void __fwk_thread_run(void)
{for (;;) {while (!fwk_list_is_empty(&ctx.event_queue))process_next_event();process_isr();fwk_log_unbuffer();}
}
scp-firmware在完成了所有的初始化操作后,执行的就是这个循环,然后永不退出。初看这可能不是很理解,这里面有三个重要的链表: free_event_queue, event_queue, isr_event_queue 所有的操作都是围绕这三个队列展开。
这三个队列在这里进行初始化,传入的event_count为64个。
int __fwk_thread_init(size_t event_count)
{struct fwk_event *event_table, *event;event_table = fwk_mm_calloc(event_count, sizeof(struct fwk_event));/* All the event structures are free to be used. */fwk_list_init(&ctx.free_event_queue);fwk_list_init(&ctx.event_queue);fwk_list_init(&ctx.isr_event_queue);for (event = event_table; event < (event_table + event_count); event++)fwk_list_push_tail(&ctx.free_event_queue, &event->slist_node);ctx.initialized = true;return FWK_SUCCESS;
}
所有的队列元素初始在 free_event_queue 当中,正常是收到ACPU发送的中断,然后从free中申请queue,插入到 isr_event_queue 队列当中。然后再通过 process_isr() 函数将 isr_event_queue 挪到 event_queue 当中。process_next_event() 处理 event_queue 当中数据,然后再返回给 free_event_queue,这就是一个完整的流程。当然一个操作可能不止是一个event_queue能够完成的,常规可能会拆成多个 queue,这要看具体场景。
module_table 结构体数组
struct fwk_module *module_table[FWK_MODULE_IDX_COUNT];struct fwk_module {/*! Module name */const char *name;/*! Module type */enum fwk_module_type type;/*! Number of APIs defined by the module */unsigned int api_count;/*! Number of events defined by the module */unsigned int event_count;#ifdef BUILD_HAS_NOTIFICATION/*! Number of notifications defined by the module */unsigned int notification_count;#endifint (*init)(fwk_id_t module_id, unsigned int element_count,const void *data);int (*element_init)(fwk_id_t element_id, unsigned int sub_element_count,const void *data);int (*post_init)(fwk_id_t module_id);int (*bind)(fwk_id_t id, unsigned int round);int (*start)(fwk_id_t id);int (*process_bind_request)(fwk_id_t source_id, fwk_id_t target_id,fwk_id_t api_id, const void **api);int (*process_event)(const struct fwk_event *event,struct fwk_event *resp_event);int (*process_notification)(const struct fwk_event *event,struct fwk_event *resp_event);
};
这个结构体定义了当前产品支持的所有模块(模块可以理解为Linux里面的驱动),其中包含有多个函数,这个函数是后面要说的,源代码中有很多解释,我为了方便就没有附上来,有兴趣可以自己去看看。
我们经常会在 product 目录下面定义相关特定的module内容,系统初始化的时候会去扫描该结构体,然后一一进行初始化。
module的含义,熟悉Linux的人可以理解它是一个简单的driver,然后系统还有一个elements概念,可以理解是驱动的一个实例。一个module里面可能有很多elements,所以可以看到module结构体里面还有elements的概念。后面会详细说。
static int init_modules(void)
{int status;unsigned int module_idx;struct fwk_module_ctx *module_ctx;for (module_idx = 0; module_idx < FWK_MODULE_IDX_COUNT; module_idx++) {module_ctx = &ctx.module_ctx_table[module_idx];module_ctx->id = FWK_ID_MODULE(module_idx);status = init_module(module_ctx, module_table[module_idx],module_config_table[module_idx]);if (status != FWK_SUCCESS) {FWK_LOG_CRIT(err_msg_line, status, __func__, __LINE__);return status;}}return FWK_SUCCESS;
}
从代码中我们还发现了另外一个数组 module_ctx_table,从名字中不难发现,其为module的上下文结构体。它和module_table一一对应关系,可以这么理解:系统各个module都有自己的一个上下文执行环境,像Linux的进程,但是又不能那么重型弄个进程上下文,所以就简单用个结构体来做这个事情(我看的代码少,感觉这确实有意思)。这里也顺带贴一下上下文的结构体
struct fwk_module_ctx {/* Module identifier */fwk_id_t id;/* Module state */enum fwk_module_state state;/* Module description */const struct fwk_module *desc;/* Module configuration */const struct fwk_module_config *config;/* Number of elements */size_t element_count;/* Table of element contexts */struct fwk_element_ctx *element_ctx_table;/* Module thread context */struct __fwk_thread_ctx *thread_ctx;#ifdef BUILD_HAS_NOTIFICATION/** Table of notification subscription lists. One list per type of* notification defined by the module.*/struct fwk_dlist *subscription_dlist_table;#endif/* List of delayed response events */struct fwk_slist delayed_response_list;
};
SCP-Firmware 核心代码相关推荐
- 利用WxJava实现PC网站集成微信登录功能,核心代码竟然不超过10行
最近网站PC端集成微信扫码登录,踩了不少坑,在此记录下实现过程和注意事项. 本文目录 一.微信开放平台操作步骤1.创建"网站应用"2.获取AppID和AppSecret二.开发指南 ...
- 融资 2000 万美元后,他竟将核心代码全开源,这……能行吗?
立即报名:https://t.csdnimg.cn/KqnS 有这么一位"任性"的技术创业者: 2017 年,50 岁开始第三次创业,踏足自己从未深入涉及过的物联网大数据平台,敲下 ...
- 太牛了!30 年开源老兵,10 年躬耕 OpenStack,开源 1000 万行核心代码!
受访者 | Jonathan Bryce 记者 | 伍杏玲 出品 | CSDN(ID:CSDNnews) 万物互联时代下,我们的一切都在依赖计算基础设施,科学.金融.政府.教育.通信和医疗保健依赖现代 ...
- asp.net的cms 核心代码篇
好像开源有点多余,核心代码就下面这些. 1 using System;2 using System.Collections;3 using System.Collections.Generic;4 u ...
- 构建dubbo分布式平台-maven构建ant-framework核心代码annotation
今天重点讲解的是ant-framework核心代码的编写过程. 其中ant-framework是ant分布式框架的基础核心框架,其中包括CRUD,MVC等一系列基类和模板.另外定义了spring,my ...
- ML之LGBMRegressor(Competition):2018年全国大学生计算机技能应用大赛《住房月租金预测大数据赛》——设计思路以及核心代码—191017再次更新
ML之LGBMRegressor(Competition):2018年全国大学生计算机技能应用大赛<住房月租金预测大数据赛>--设计思路以及核心代码-191017再次更新 目录 竞赛相关信 ...
- 淘宝店铺图片数据迁移核心代码
核心代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys ...
- OceanBase首次阐述战略:继续坚持自研开放之路 开源300万行核心代码
简介:在数据库OceanBase3.0峰会上,蚂蚁集团自主研发的分布式数据库OceanBase首次从技术.商业和生态三个维度对未来发展战略进行了系统性阐述.同时,OceanBase宣布正式开源,并成立 ...
- python 重写断言_历时四年,Dropbox 用 Rust 重写同步引擎核心代码
开源 GO 语言工具库.研究 iOS 和 Android 的 C++ 跨平台开发,花费五年时间从云平台向数据中心反向迁移-Dropbox 从未停止对技术的"折腾".如今,这家公司又 ...
- Java 线程池框架核心代码分析
转载自 Java 线程池框架核心代码分析 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executo ...
最新文章
- 广度优先搜索(BreadthFirstSearch) 迪克斯特拉算法 (Dijkstra's algorithm)
- python如何判断两个数组完全相等?
- Java正则表达式应用详解
- .NET Core 3.0 部署在docker上运行
- CF5E-Bindian Signalizing【单调栈】
- HTML和css学术报告,清华大学 张超 副教授访问我院并做学术报告
- 8086-汇编-模块化程序设计
- 汽车防撞之FMCW(调频连续波)原理
- 5G移动通信 笔记 - 5G接入网架构
- Linux面试题史上最全总结
- block unicast机制
- ant design DatePicker时间组件 本地中文 发布后变成英文
- Mac电脑批量修改图片名称
- 任意重循环(循环阶数不定、循环层数不定)
- ios合并两张图片(叠加两张图片 重合两张图片)
- KD2684S绕组匝间故障检测仪
- IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! 解决办法
- 服务器v3 v4性能,至强E5 v4性能表现测试
- HashKey2019数字资产全球峰会将于3月21日在香港召开
- java防止电脑锁屏的网页_关于windows防止锁屏小程序