当前位置:网站首页>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));
}
边栏推荐
- Primary code audit [no dolls (modification)] assessment
- Godson 2nd generation burn PMON and reload system
- Ueditor + PHP enables Alibaba cloud OSS upload
- ELK 企业级日志分析系统
- leetcode 10. Regular Expression Matching 正则表达式匹配 (困难)
- How to apply the updated fluent 3.0 to applet development
- What are the private addresses
- JS to determine whether an element exists in the array (four methods)
- redis6主从复制及集群
- ETCD数据库源码分析——rawnode简单封装
猜你喜欢
Jetpack Compose入门到精通
jenkins安装
几款分布式数据库的对比
Win10 - lightweight gadget
Wonderful express | Tencent cloud database June issue
Primary code audit [no dolls (modification)] assessment
Write API documents first or code first?
Ordering system based on wechat applet
Kotlin协程利用CoroutineContext实现网络请求失败后重试逻辑
PHP basic syntax
随机推荐
Integer = = the comparison will unpack automatically. This variable cannot be assigned empty
Hide Chinese name
MySQL if else use case use
什么是网络端口
什么叫做信息安全?包含哪些内容?与网络安全有什么区别?
Clock cycle
Internal JSON-RPC error. {"code":-32000, "message": "execution reverted"} solve the error
Primary code audit [no dolls (modification)] assessment
Nantong online communication group
MySQL - database query - sort query, paging query
C object storage
Don't know these four caching modes, dare you say you understand caching?
What about data leakage? " Watson k'7 moves to eliminate security threats
Jetpack Compose入门到精通
Laravel generate entity
Attack and defense world web WP
2022司钻(钻井)考试题库及模拟考试
Catch all asynchronous artifact completable future
PHP generate Poster
4年工作经验,多线程间的5种通信方式都说不出来,你敢信?