当前位置:网站首页>Embedded software architecture design - message interaction
Embedded software architecture design - message interaction
2022-07-05 13:48:00 【Illusory private school】
High quality resource sharing
Learning route guidance ( Click unlock ) | Knowledge orientation | Crowd positioning |
---|---|---|
🧡 Python Actual wechat ordering applet 🧡 | Progressive class | This course is python flask+ Perfect combination of wechat applet , From the deployment of Tencent to the launch of the project , Create a full stack ordering system . |
Python Quantitative trading practice | beginner | Take you hand in hand to create an easy to expand 、 More secure 、 More efficient quantitative trading system |
1、 Preface
Familiarity Task scheduling 、 Program layering and Modular programming About software architecture 、 After layering and module design , except Function call design Except for the situation in , And how to interact with messages before encountering modules of the same layer , Usually between application layers .
For example, a device includes human-computer interaction application layer modules through architecture design ( Generally, it will call function driver modules such as keys and display screen ) And communication application layer module ( Generally call serial port 、CAN And the Internet ESP8266 And other function driver modules ), If two modules in the same layer need to transmit data to each other , Generally, they call the interfaces provided by their respective header files ( Try not to use global variables in the interface provided by the module , Prevent other modules from modifying without authorization ), This creates coupling .
2、 Solutions
foregoing circumstances , The implementation of callback function can also be used for module decoupling , But new content needs to be introduced , Common module, i.e Commoon layer ( Contains third-party libraries ).
Common modules mainly have type definitions that each module needs to use 、 Structure definition 、 General function or common macro definition, etc ( Functions that usually belong to the basic class , It will not be affected by functional requirements and different platforms ).
Based on common modules , In order to solve the data interaction before each module , The function of the basic class can be realized through the common module to achieve the purpose of decoupling the modules of each application layer .
Message queue reference mode , Can realize a producer / Consumer function modules ( This can be called Observer mode , That is, there are observers and observers ), That is, the first mock exam module updates data. , Other modules can be notified and updated at the first time ( The callback function is used to realize )
Look at the picture :
Callback Is a pointer array variable , Each array member is a variable of function pointer type , By function Notify_Attach Got the application layer code function OnSaveParam(…) and OnUpdateParam(…) Function address of , Then the human-computer interaction module calls Notify_EventNotify, To call Callback , Call mode and direct call OnFunction(…) There are some differences , Because it's an array , All the needs [ ] Take the function address , In order to ensure the safe operation of the system , Make sure... Before calling Callback[i] Not for NULL, Otherwise, it will cause program exceptions .
From the above , Some people may feel that this treatment is complicated , Doesn't it smell good to call directly ?( The above human-computer interaction module belongs to the observed , Parameters and other modules belong to the observer )
There are several advantages :
- Avoid calling each other , Decoupling can be completed
- Even if The observer One of the modules was removed , You don't have to modify it Observed perhaps Other observers Code , Make sure the system is stable
- Add a new one The observer modular , It doesn't need to be modified Observed Code , Make sure the system is stable
Of course, this method also has disadvantages :
- If there are too many callback functions , Or one of them The observer The callback function of takes a long time to execute , It will certainly affect other observers Notification time of the module , Even influence Observed Normal operation of the module
- If The observer and Observed There is a circular dependency between , Will cause them to call , Cause the system to crash
Avoid the way :
- In the callback function, we must ensure that the execution time is short , Can't have functions that take a long time to execute , Even delay ( Generally, the callback can handle data update and other short-time execution , The data that needs to be processed after updating can be executed in the main loop )
- In the observer callback function, try to avoid executing the callback function of other observers , Prevent circular calls
3、 Sample code
Event notification module header file
copy
#ifndef \_NOTIFY\_H\_
#define \_NOTIFY\_H\_
#include
/**
* @brief Application module ID Enumeration Definition
*
*/
typedef enum
{
NOTIFY_ID_HMI = 0, // Human computer interaction module
NOTIFY_ID_SYS_PARAM, // Parameter management module
NOTIFY_ID_TOTAL
} NotifyId_e;
/**
* @brief Event type enumeration definition
*
*/
typedef enum
{
NOTIFY_EVENT_PARAM_UPDATE, // Parameter update event , Corresponding structures PrramUpdateInfo\_t
NOTIFY_EVENT_TOTAL
} NotifyEvent_e;
typedef struct
{
uint16\_t addr;
uint32\_t param;
}PrramUpdateInfo_t;
typedef int (*EventNotifyCB)(NotifyId\_e id, NotifyEvent\_e eEvent, const void *pData, uint32\_t length);
extern void Notify\_Init(void);
extern int Notify\_Attach(NotifyId\_e id, NotifyEvent\_e eEvent, EventNotifyCB pfnCallback);
extern int Notify\_Detach(NotifyId\_e id, NotifyEvent\_e eEvent);
extern int Notify\_EventNotify(NotifyId\_e id, NotifyEvent\_e eEvent, const void *pData, uint32\_t length);
#endif /* \_NOTIFY\_H\_ */ Fold
Event notification module source file :
copy
#include "notify.h"
#include
static EventNotifyCB sg_pfnCallback[NOTIFY_ID_TOTAL][NOTIFY_EVENT_TOTAL];
/**
* @brief Event initialization
*
*/
void Notify\_Init(void)
{
memset(sg_pfnCallback, 0, sizeof(sg_pfnCallback));
}
/**
* @brief Add event listening notification
*
* @param[in] id Application module ID
* @param[in] eEvent event
* @param[in] pfnCallback Callback function
* @return 0, success ; -1, Failure
*/
int Notify\_Attach(NotifyId_e id, NotifyEvent_e eEvent, EventNotifyCB pfnCallback)
{
if (id >= 0 && id < NOTIFY_ID_TOTAL && eEvent < NOTIFY_EVENT_TOTAL)
{
sg_pfnCallback[id][eEvent] = pfnCallback;
return 0;
}
return -1;
}
/**
* @brief Delete event listening notification
*
* @param[in] id Application module ID
* @param[in] eEvent event
* @return 0, success ; -1, Failure
*/
int Notify\_Detach(NotifyId_e id, NotifyEvent_e eEvent)
{
if (id >= 0 && id < NOTIFY_ID_TOTAL && eEvent < NOTIFY_EVENT_TOTAL)
{
sg_pfnCallback[id][eEvent] = 0;
return 0;
}
return -1;
}
/**
* @brief Event notification
*
* @param[in] id Application module ID
* @param[in] eEvent Event type
* @param[in] pData The message content
* @param[in] length The length of the message
* @return 0, success ; -1, Failure
*/
int Notify\_EventNotify(NotifyId_e id, NotifyEvent_e eEvent, const void *pData, uint32_t length)
{
int i;
if (eEvent < NOTIFY_EVENT_TOTAL)
{
for (i = 0; i < NOTIFY_ID_TOTAL; i++)
{
if (sg_pfnCallback[i][eEvent] != 0)
{
sg_pfnCallback[i][eEvent](id, eEvent, pData, length);
}
}
return 0;
}
return -1;
} Fold
Parameter application layer module :
copy
#include "notify.h"
static int Param\_OnNotifyProc(NotifyId\_e id, NotifyEvent\_e eEvent, const void *pData, uint32\_t length);
void Param\_Init(void)
{
Notify\_Attach(NOTIFY_ID_SYS_PARAM, NOTIFY_EVENT_PARAM_UPDATE, Param_OnNotifyProc);
}
// Event callback processing
int Param\_OnNotifyProc(NotifyId\_e id, NotifyEvent\_e eEvent, const void *pData, uint32\_t length)
{
switch (eEvent)
{
case NOTIFY_EVENT_PARAM_UPDATE:
{
PrramUpdateInfo_t *pInfo = (PrramUpdateInfo_t *)pData;
SaveParam(pInfo->addr, pInfo->param);// Save parameters
}
break;
default:
break;
}
return 0;
}
Human computer interaction application layer module
copy
#include "notify.h"
void Hmi\_Init(void)
{
}
// Parameters need to be saved
int Hmi\_SaveProc(void)
{
ParamUpdateInfo_t info;
info.addr = 5;
info.param = 20;
Notify\_EventNotify(NOTIFY_ID_HMI, NOTIFY_EVENT_HMI_UPDATE, &info, sizeof(ParamUpdateInfo_t));
}
边栏推荐
- Prefix, infix, suffix expression "recommended collection"
- Ordering system based on wechat applet
- Basic characteristics and isolation level of transactions
- 【 script secret pour l'utilisation de MySQL 】 un jeu en ligne sur l'heure et le type de date de MySQL et les fonctions d'exploitation connexes (3)
- [daily question] 1200 Minimum absolute difference
- Zhubo Huangyu: it's really bad not to understand these gold frying skills
- ETCD数据库源码分析——集群间网络层客户端peerRt
- Interviewer soul torture: why does the code specification require SQL statements not to have too many joins?
- 个人组件 - 消息提示
- TortoiseSVN使用情形、安装与使用
猜你喜欢
随机推荐
Personal component - message prompt
What is a network port
2022年机修钳工(高级)考试题模拟考试题库模拟考试平台操作
【云资源】云资源安全管理用什么软件好?为什么?
Win10——轻量级小工具
PHP basic syntax
Flutter 3.0更新后如何应用到小程序开发中
Assembly language - Beginner's introduction
今年上半年,通信行业发生了哪些事?
Self built shooting range 2022
Integer ==比较会自动拆箱 该变量不能赋值为空
aspx 简单的用户登录
Datapipeline was selected into the 2022 digital intelligence atlas and database development report of China Academy of communications and communications
ELK 企业级日志分析系统
When using Tencent cloud for the first time, you can only use webshell connection instead of SSH connection.
Solve the problem of "unable to open source file" xx.h "in the custom header file on vs from the source
STM32 reverse entry
嵌入式软件架构设计-消息交互
Summary and arrangement of JPA specifications
These 18 websites can make your page background cool