当前位置:网站首页>PX4模块设计之十三:WorkQueue设计
PX4模块设计之十三:WorkQueue设计
2022-07-27 19:56:00 【lida2003】
PX4模块设计之十三:WorkQueue设计
1. WorkQueue启动
WorkQueue是PX4飞控软件的Common(公共)组件,通过函数px4::WorkQueueManagerStart开始启动的,这之前请参考PX4模块设计之十:PX4启动过程。
board_app_initialize
└──> px4_platform_init
└──> px4::WorkQueueManagerStart
注1:Nuttx系统是支持WorkQueue的。但是PX4在common(公共)组件层实现了类似的WorkQueue的功能,而没有直接采用Nuttx系统的WorkQueue。这里初步怀疑还是历史时间上导致的这个结果。
注2:Nuttx第一版本是在2007年发布,开始支持2-3个MCU((i.e. 8051 and ARM7);PX4-AutoPilot是2009年开始的项目,2013年ETH Zurich (苏黎世联邦理工大学)的计算机视觉与几何实验室 Lorenz Meier ,发布了第一代实验版本: 双飞控处理器PX4FMU/PX4IO硬件。
所以综上所述,鉴于以下原因
1)其历史原因,PX4-AutoPilot的公共组件WorkQueue独立实现;
2)飞控模式采用C++类继承进行开发和管理;
3)uORB消息组件采用C++类进行管理;
4)HRT高精度定时采集触发管理;
WorkQueue的整体管理上结合了上述历史原因,将C/C++设计,类,继承,以及内核态/用户态。整体感觉异常复杂,这部分内容实在不太敢恭维!!!(—AnyWay, 历史原因吧!!!—)
2. WorkQueue接口
2.1 基本接口
最为基本的WorkQueue管理接口并不负责,主要就是Start/Stop/Status三个。
int WorkQueueManagerStart() //WorkQueue管理启动任务
int WorkQueueManagerStop() //作为基础组件这个基本不需要Stop,至少目前代码上没有看到有Stop的地方。
int WorkQueueManagerStatus() //WorkQueue状态查询
2.2 辅助接口
const wq_config_t & device_bus_to_wq(uint32_t device_id_int) //device_bus 转 wq配置
const wq_config_t & serial_port_to_wq(const char *serial) //serial_port 转 wq配置
const wq_config_t & ins_instance_to_wq(uint8_t instance) //instance 转 wq配置
static WorkQueue * FindWorkQueueByName(const char *name) //通过名字查WorkQueue
WorkQueue * WorkQueueFindOrCreate(const wq_config_t &new_wq) //查找或者创建WorkQueue
2.3 WorkQueue任务函数
WorkQueue目前是支持Flat和Protected Build两种编译模式,不同编译模式下最显著的差异就是Flat Build下采用pthread_create建立任务,而Protected Build下采用px4_task_spawn_cmd建立任务。
2.3.1 Flat Build
static void * WorkQueueRunner(void *context)
2.3.2 Protected Build
该函数内部实现会再次调用Flat Build的函数(此时运行的代码空间将会是内核态)。
inline static int WorkQueueRunner(int argc, char *argv[])
2.4 重点接口分析
2.4.1 WorkQueueManagerStart
WorkQueueManagerStart
├──> <_wq_manager_should_exit.load() && (_wq_manager_create_queue == nullptr)>
│ ├──> _wq_manager_should_exit.store(false);
│ ├──> int task_id = px4_task_spawn_cmd("wq:manager",SCHED_DEFAULT,SCHED_PRIORITY_MAX,PX4_STACK_ADJUSTED(1280),(px4_main_t)&WorkQueueManagerRun,nullptr);
│ └──> <task_id < 0>
│ ├──> _wq_manager_should_exit.store(true);
│ ├──> PX4_ERR("task start failed (%i)", task_id);
│ └──> return -errno;
├──> else
│ ├──> PX4_WARN("already running");
│ └──> return PX4_ERROR;
└──> return PX4_OK;
2.4.2 WorkQueueManagerRun
WorkQueueManagerRun
├──> _wq_manager_wqs_list = new BlockingList<WorkQueue *>();
├──> _wq_manager_create_queue = new BlockingQueue<const wq_config_t *, 1>();
├──> <while (!_wq_manager_should_exit.load())>
│ ├──> const wq_config_t *wq = _wq_manager_create_queue->pop(); //当没有work queue的时候,管理任务始终阻塞在这里。
│ └──> <wq != nullptr> //不应该是空,容错以防段错误,里面是建立新的work queue
│ ├──> [stack, priority, etc] //略。。。。
│ ├──> [Flat Build, pthread_create WorkQueueRunner]
│ ├──> [Protected Build, px4_task_spawn_cmd WorkQueueRunner]
│ ├──> <pid > 0>
│ │ └──> PX4_DEBUG("starting: %s, priority: %d, stack: %zu bytes", wq->name, sched_priority, stacksize);
│ └──> <else>
│ └──> PX4_ERR("failed to create thread for %s (%i): %s", wq->name, pid, strerror(pid));
└──> return 0;
2.4.3 WorkQueueRunner
WorkQueueRunner
├──> wq_config_t *config = static_cast<wq_config_t *>(context);
├──> WorkQueue wq(*config);
├──> _wq_manager_wqs_list->add(&wq); // add to work queue list
├──> wq.Run(); // 这里就是
├──> _wq_manager_wqs_list->remove(&wq); // remove from work queue list
└──> return nullptr;
2.4.4 WorkQueue::Run
WorkQueue::Run
├──> <while (!should_exit())>
│ ├──> do {} while (px4_sem_wait(&_process_lock) != 0); // loop as the wait may be interrupted by a signal
│ ├──> work_lock();
│ └──> <while (!_q.empty())>
│ ├──> WorkItem *work = _q.pop();
│ ├──> work_unlock(); // unlock work queue to run (item may requeue itself)
│ ├──> work->RunPreamble();
│ ├──> work->Run(); // 真实需要执行的Run函数,通常是继承WorkItem的对象
│ ├──> work_lock(); // re-lock
│ └──> work_unlock();
└──> PX4_DEBUG("%s: exiting", _config.name);
2.4.5 WorkQueueFindOrCreate
WorkQueueFindOrCreate
├──> <_wq_manager_create_queue == nullptr>
│ ├──> PX4_ERR("not running");
│ └──> return nullptr;
├──> WorkQueue *wq = FindWorkQueueByName(new_wq.name); // search list for existing work queue
├──> <wq == nullptr>
│ ├──> _wq_manager_create_queue->push(&new_wq); //这里很重要,只有push了,WorkQueueManagerRun里面才能执行下去。
│ ├──> _uint64_t t = 0;
│ └──> _<while (wq == nullptr && t < 10_s)> // we wait until new wq is created, then return
│ ├──> t += 1_ms;
│ ├──> px4_usleep(1_ms);
│ ├──> wq = FindWorkQueueByName(new_wq.name);
│ └──> <wq == nullptr>
│ └──> PX4_ERR("failed to create %s", new_wq.name);
└──> return wq;
3. 总结
工作队列,其实并不负责。而PX4的工作队列为什么看起来复杂,主要是工作队列和实际的业务耦合。这里我们还没有将uORB的订阅内容放到里面,如果结合这部分,再加上多个继承业务的相互切换等内容,就看似更加复杂了。
所以我们尤其强调设计需要松耦合,尽量模块化,明确接口设计,明确框架设计。
4. 参考资料
【1】PX4开源软件框架简明简介
【2】Nuttx WorkQueue
边栏推荐
猜你喜欢

解决ip地址访问末位奇数通偶数不通,或者偶数通奇数不通的问题(云加密机连接云服务器时遇到的问题,全程记录,希望能给大佬们灵感)

舌簧继电器

Project management tool Zen

Cy3荧光标记抗体/蛋白试剂盒 (10~100mg标记量)

If there is no reference ground at all, guess if you can control the impedance?

极化继电器

Hill sort of seven sorts

Quartus:Instantiation of ‘sdram_model_plus‘ failed. The design unit was not found.

电磁继电器
In depth understanding of redis master-slave principle
随机推荐
Time relay
The ordinary way of chasing source code
时间继电器
SSM integration process
RN搜索高亮显示
Relationship between DBM and VPP and Vpeak
What is private traffic?
It is said that Huawei will cut the order again! Supply chain manufacturers are more difficult
Shandong football match
ADI、世健、骏龙科技共同捐赠230万元助力湖北抗疫
[untitled]
Video human behavior detection
The follow-up is coming. Whether it's OK without reference, let's make it clear to everyone at once!
Credit default prediction based on simplified scorecard, smote sampling and random forest
Leetcode-152- product maximum subarray
Two dimensional code generation based on MCU and two dimensional code display on ink screen
If there is no reference ground at all, guess if you can control the impedance?
2021 Fujian Vocational College skills competition (secondary vocational group) network security competition assignment
HC32F4A0 时钟控制
Cocos: simple application of ccpdistance function and the function of eyeball rotating in orbit with fingers