当前位置:网站首页>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));
}
边栏推荐
- NFT value and white paper acquisition
- FPGA learning notes: vivado 2019.1 add IP MicroBlaze
- 【公开课预告】:视频质量评价基础与实践
- Liar report query collection network PHP source code
- 嵌入式软件架构设计-消息交互
- 这18个网站能让你的页面背景炫酷起来
- Assembly language - Beginner's introduction
- Integer = = the comparison will unpack automatically. This variable cannot be assigned empty
- leetcode 10. Regular Expression Matching 正则表达式匹配 (困难)
- Network security - Novice introduction
猜你喜欢
Summit review | baowanda - an integrated data security protection system driven by compliance and security
嵌入式软件架构设计-消息交互
【华南理工大学】考研初试复试资料分享
"Baidu Cup" CTF competition in September, web:upload
When using Tencent cloud for the first time, you can only use webshell connection instead of SSH connection.
Attack and defense world web WP
荐号 | 有趣的人都在看什么?
What are the private addresses
【公开课预告】:视频质量评价基础与实践
Ordering system based on wechat applet
随机推荐
Huawei push service content, read notes
Data Lake (VII): Iceberg concept and review what is a data Lake
Nantong online communication group
restTemplate详解
Hide Chinese name
Idea设置方法注释和类注释
【 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)
【公开课预告】:视频质量评价基础与实践
stm32逆向入门
How to divide a large 'tar' archive file into multiple files of a specific size
Personal component - message prompt
:: ffff:192.168.31.101 what address is it?
一网打尽异步神器CompletableFuture
Pancake Bulldog robot V2 (code optimized)
Zhubo Huangyu: these spot gold investment skills are not really bad
asp. Net read TXT file
asp.net 读取txt文件
4年工作经验,多线程间的5种通信方式都说不出来,你敢信?
PHP basic syntax
记录一下在深度学习-一些bug处理