C/C++编程-分层模块化-数据交互

zchs_protocol
vincepipegrab

对于zchs_protocol协议模块和下面的三个运动部件模块之间的交互问题。


实习方式

  • 变量

无系统:跨模块的全局变量
有系统:信号量等

  • 函数接口

方式选择优缺点说明

关于变量

  • 无系统
    例如,在zchs_protocol中定义serial_send_state:0没有数据发送,1有数据发送。
    需要分别在三个运动部件模块中分别置位此标志变量,然后在zchs_protocol中实现发送函数(检测此标志,然后发送)。
    但是这这其中存在的问题是,如果vince模块已经将serial_send_state置1,有vince的数据要发送。那么又有pipe或者grab模块也要置位此位,要申请串口发送数据。那么zchs_protocol就不知道要发送谁的了。说白了,就是需要明确三个底层模块的发送顺序。
    发送顺序又有两种实现方式:变量和逻辑控制
    变量最简单的就是,每个运动模块都在自己模块内置位,清位serial_send_state。每次置位serial_send_state前,都检测是否为1,如果为1,则放弃此次发送,等待下一次轮询到自己模块有没有数据要发送。
  • 有系统
    利用信号量,实现上面逻辑业务逻辑

关于函数接口

在zchs_protocol中定义一个serial_send()接口函数,由三个运动部件调用。
但是一样面对,不知道vince调用此函数的时候,pipe和grab有没有调用。这样的问题。
同样需要标志变量或者逻辑控制,实现**“发送接口”**这个共享资源问题。
其实,裸机没有任务中断调度,已经通过逻辑控制解决了这个问题。即,不可能vince在通过zchs_protocol发送数据的时候,pipe和grab也有数据同时申请发送。
但是,由系统的时候,就需要依旧需要信号量去解决这个问题。
综上,对于变量,裸机和系统都适用。
对于接口函数,裸机适用,系统不适用。
所以,变量实现方式更占优势。
优势:适用普遍,有利移植

zchs_protocol

uint8_t s_state=0;

if(s_state==1)

{

serial_send();

s_state=0;

}

vince

if(v_sate==1)

{

if(s_state!=1)

{s_state=1;v_state=0;}

}

pipe

if(p_sate==1)

{

if(s_state!=1)

{s_state=1;p_state=0;}

}

grab

if(g_sate==1)

{

if(s_state!=1)

{s_state=1;g_state=0;}

}

zchs_protocol
poll()
{
	check_sub_send();
	switch(state)
	{
	ready:break;
	recive:break;
	send:break;
	idle:break;
	}
}

上面的描述虽然有些道理,但是经过一些日子的磨炼,现在又感觉有些肤浅。这是有了新的感悟。现描述如下:

模块的堆叠

我们经常在一些让人崇拜的官网上看到下面这样的软件图解:

APP
drive_adrive_bdrive_c
三个下层托起一个上层
或者
APP_AAPP_BAPP_C
drive
一个下层驱动供三个上层调用

这是软件的整体划分,由下而上的堆叠,这个我自然很容易了解了,其作用也是一样很容易理解了。但是,若想切身的体会却是不容易。应该还是要去大公司工作,并且有着坚实的基础,才会有着切身的体会。
体会就是:即使上层领导根据项目需求,划分好模块了,那么又如何保证软件的书写、构造完美遵循这个堆叠结构呢?
这里面有大量的工作。我技术不够好、层次不够高,也是说不好的。但是却有着下一些切身体会。

1,模块之间的交互方式:数据交互、函数接口、全局变量。

这些实现方式,就像数学中的“加减乘除”是基本的要素,需要我们自己的搜寻、借鉴。有哪些方式实现、各个实现方式能达到的效果、其优缺点又是什么都要自己平时一一积累总结。就是模拟电路中,运放电路的基本电路”加法、减法、乘法、除法、积分、微分、vi、iv、低通、高通、带通、跟随、锁相环、、、”等一样。这都是你以后设计电路的基础电路,有了他们,就是数学中你学会了加减乘除,才能去用它们解决各种问题,他们是基础啊!这个基础知识不行,那还谈什么。也像画家手中的“笔、纸、赤、橙、黄、绿、金、蓝、紫墨水”,有了它们,你才能做画,是一样的道理。

然而市面上的教材,却少有提及这个的,教这个的。其实,我一直认为最好的教材,莫过于汇聚了各个高手的操作系统源码。所以,我把整理这些基础素材的来源,总是分为“带系统”和“不带系统”两种实现方式。

带系统的模块间交互方式:

其实网上都有。这里只是告诉大家把这些思想联系起来。
数据交互方式:队列、邮箱。
函数接口:注册(操作集的指针赋值)。
就是rt_thread和Linux中驱动架构中的操作集的函数接口赋值。
struct file_operation fops =
{
.open = xxx_open;
.close = xxx_close;
.read = xxx_read;
.write = xxx_write;
.probe = xxx_probe;
};
全局变量:信号量,互斥锁、事件。

不带系统的模块间交互方式:

函数接口:
在“model_a.c”的“model_a.h”中声明对外的
void a_open(void);
void a_close(void);
void a_read(void);

或者采用extern关键字修饰,在合适的地方声明。
者两种方式,前者对所有上层模块开放,并且include之后夹带其他通用对外开放信息。所以适合带有common属性。而extern则只需要在需要的上层文件中声明就可,并且不带有.h文件中的其他对外common属性。

对于全局变量和数据交互,也是一样考虑。

2,模块堆叠需要遵守的一些规则和考虑

  • 机制和策略(即“输入”和“输出”)
  • 认清模块在软件栈中的位置-
  • 向下依赖, 不要向上依赖
  • 避免同级依赖
  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这些步骤是Javaweb《建设工程监管信息系统》交易流程步骤列表显示模块2的数据库设计和系统架构设计的重要组成部分。具体解释如下: 1. 数据库设计: a. 创建数据库ConstructionDB:这一步骤是指在MySQL或其他数据库管理系统中创建一个名为ConstructionDB的数据库,用于存储与该模块相关的数据。 b. 创建流程步骤定义表(T_flow_step_def):这一步骤是指在ConstructionDB数据库中创建一个名为T_flow_step_def的数据表,用于存储流程步骤的定义和相关信息。这些信息包括步骤名称、步骤编号、步骤描述、步骤创建时、步骤修改时等。 2. 系统架构设计: a. 实现系统项目分层:这一步骤是指根据MVC(Model-View-Controller)的设计模式,将整个系统分为三层:模型层、视图层和控制层。模型层负责处理数据,视图层负责呈现界面,控制层负责协调模型层和视图层的交互。 b. 实现业务逻辑层设计:这一步骤是指在控制层中实现业务逻辑的处理。例如,当用户提交一个表单时,控制层将根据表单数据调用相应的模型层方法,对数据进行处理,并返回相应的结果。 c. 实现数据访问层设计:这一步骤是指在模型层中实现数据的访问和操作。例如,当控制层需要从数据库中获取数据时,模型层将调用相应的数据库方法,对数据进行查询和操作,并返回相应的结果。 以上就是Javaweb《建设工程监管信息系统》交易流程步骤列表显示模块2的数据库设计和系统架构设计的具体步骤。希望能够对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值