Zf%AZsNAP
zH6y1Coim^0+1YxyNKtlnk(5oqbpe+h$1nBRc6J+n2e|7E_}$N4_u?1B2hfk=_W*Z2
zgkKTjTX2aG--U}}x3eEgl>URcK&d~!n4|r0iLjgD66g-NF5&1!5}kx=7neog5;^!Y
zxW>8cdbminc2<|Jo8j8cWv_!vg!n7CF6FW(;G)^8ooVPtgzIAIIw4(u3D;iE`!HNM
zyNVEBfJ>zIH7TP?xDtOFb4nMbDP$h$f`iL!h{tqMSZV+^j!+1jjK#(gftvBz7*#95
z^S~ugstQ6zc@wS+B}z{yWCx^+G$F!XDP;$x%P-NOl!c`$F42^f9hI)@Bzj!Ra?&*~
zQG5xKKT97wZlD^gz~#YTA8X)u6L-B=y1pY_??nj;^kdTXed+qKbbS?NBzT80uMn>P
zqzN34`PqmlOO2fu74=VJ2jC)IX)G;WuaK_SOV?e}^*-tPq;x$ZT~A8a_oVB`(zOYF
zkx1<_xJ0gkQdW?zmrL~ZQuYz)dR(I4ma>17F8b`Zhr2x0
zed+qOblI?A5;1p6*PwK{q-&jYohMz}r0W9d+Am#~NLO6CQqpyubRCy2s!eNosXFm1
zo^pGa>7q8Xm7^YsQXLmEvyN-5C}kDNyF<#}EM=dOvWKPYpQP+*DSKARP@#-mjlpH)
zMar&}vV&4KJ_{2q!qfHKS;pqH_L(hT*$N60@Gu)fw_e6#nfLmf!^F~C{Ko+yp)l9s
zZvlToLRJF0XmBG5REcXAe>9vmB~|!-W|6!MJ{qzFhg*sup+QPW#xZ%QLqZp2*QU{0
zz+8lLF&pRB1L3BWZQ3t9)cdN}_)M*4`q8*MKKpo%48(XT4i|;CX(QycT;r#jiJ@x%
zhiZZK8m}}tD*y@3ItytWhi+l=;8!>2(3skO-EN3<+-=%CYA~4
-=>iPk2G$*zG!%<&DgZ}TS3G3b>rU8Iahb&Q2nQC0Dm^^
zI1(D-e)C8CyAApXvbaQUf28%B%iWKDrC&12F5Rn=TYF}IeNJiU%JLO
z8Vq-4W(IR>>B9lxIUEBwz#>kEn{J#nVxm@VzTt)&OzA9t5tR2O+>EE16}jEhuvB)i
zf&Qs7)3i8?uTFPbk_g1I0udr%Z4++GqDhD>iy@U|tZ9Vk9IGmWudJ39=^QuyeF6Tt
X0za$FwMX^@tcU1dTu7H#`?CK72)K15
literal 0
HcmV?d00001
diff --git a/build/list.o b/build/list.o
index f195381c37955e6ae780ee9d095ee57cb6df7075..f613a8d0b959eaf51a6e019d7c64be9da308770b 100644
GIT binary patch
literal 4271
zcmcInO>7&-6@J6r5m#DKqDWPiYR6p{ik+qw^%Gf^)i|cDFs5MH7VOGF1qU1ctRy<*
zl30?G>>x#J)d2(ptyKsqQaFgwQx8!uJw!^0x*Q6Labt~RD>+6M-1R!_%BH+1Q0f0=G9m>
zRY}$H_7meU^GPgSF7MY@k9~)DD~%5Ok?;qlo&^wxp?Iv+%-coY_uTwi(S&$|qm8zI
zQ~?g*|1S-^@VUX^u?Aui$NCSg0YZPsdv2%!ByFM%U>xU;3eAh)jh+y?S3QgVZXj>k
z<)JEhCr)}4(NbC)dIKbRW8)2A9JL2cyqWmm$x{uyd#F7^-ZeLF3+i!*pPNmteV$zX
z`%rT2VmP@r+xtNnJN`zd$+g5za`lZJs0OzJsBbSM?;>({wl}#J7UILWm>85%hvc14
zsv#-Q?jU7*#Oqi~>~6QCvYWgc*U&Atu8bysl?s{6Xj>xi>Ssf*eEP-2JZEUqwnek{
z_ybDPjZID;CU(gD@w&t@3M5Y@daETlim%s2t#nCcMiUM&*>NE}BnPnFK#kN5IXrBP$A)7=#z3J`wXM^cqGOGql5#SOr|n{y@iSfs>Zb&DA8JmfF2|{NMTGQg}(egs$9E|wI)Ezaf%KE)d&U)bVR6Wou0b-
zP4n^vPfA?5VhU*Ls(ER4dK#Ey5PtFO^z`LP^QE&>(}@=$0BvfpYL{~hwv{z!(Iove4aG+2^6lIa|OlHNl0{
z4P1)qh31Z&O&v3`LpM`}bpEw+?iTP92Pj~tSjh-jz>=J%mo_PttFi%h{}HAa7SDtw
z50DaAhc0Pysg+Cu>-jDl_aLy#5!xhy^;dB`KSe1b+*6*(@+Fg1IsLGl|`I1M!26
zf%q{$khN^eAq73>-Pc_|BW~+v)7>M-yofOCVoz&PUC|C|T`Up|AHcMuOzF_|3H=-T
zDV;^}&XX`V_IfPEy
z`q9Y?m;mma(K@>`eb4vdj$>>pN;!m%z*KY)`5i8apF)3<)EQ%E`n-t8`lg~Zl6dcr
z&h?RHnAdp?;7Q(9ABKR){`PN4`{@7d1?bjs{vtt~$K&|N{elGtQdjEF^*R`i(kcW8
zA;$jQ5yG0$GR8lfoER+R?1kmA(ZQARF>`Em0L1|TJvTC#vorZBu3VsngSQD5A<@Hx
zj8n;4^X1qgIl_AFerB$vg=?{6kV!S6^iD2leb%{r+T;JrOA>MI;>+kdSo1C2v
zwBWqdHb@1|Pfku4&$zQvDwcCA17&M*0Qc0;apPPym#-M{oY~V^By(w
zzIZhGyi1bTgAotoUxg{m=Ud03lFDle@@-k9Zn;1`i1}cs{YH4`yBe7Ybxdul#sTb^9Tm!z0Ow|f7rTem!P-bocKaqfyc*QBevc22o34gwHw
J9sjQc{tIt6{Luga
literal 4621
zcmbVPU2Ggz6+U-o?(R72U9W#g>?DmQ!AV_+*X!7EoHQYu#7WkQTCA!jLJHc-qUjKTqiQqX=UIy_B
z^1=!Gmmix9BLEx&bdmQ5&)yzX=OJ@(YH<62gRQom>$>A7Nis2{h
zO`a5WKRbf<-bUVx$HS`Rojm1JKCu+`rluqMJl6h}j6i4)<2`jc0=|#6;ckG(J-;&E
z{Kfgg#)pOVk8_2M$1=a5!TX4s6*ewED6D_=0kjiuQ2pM4!fixu&u0o786m!t*94K^
z_21^c^qa7u!p8g{vIYwqZ+-OQ*47r9+eCAlfw>D<%LKIvnAFaD>+dNlpIOYkg7*4r*&Tf<&wxN$M>Z2{Ua;`i+4&61Y
zWJQ4Ez8q8mJoA
zZlM(S8pSk)stFb^R}BXeTB6pl7j==f?UuD@n-$%%UDWW7hJg4owLrg0Y4D$9B9>@X
z8;+|-o2gv1R%L6Fx%LyJbL|6>CoqzPn%LGz_96;0EvS2aRV$5lsb*q(b)nWUu#*{8
zbkf7MV$rHMi^XESR4lihV%=B)wUs%BF1z+)_EY@!{0zH+BU5axwu+|X(71s5>amwm
zCqWxgP+uFSo+f>ZhO<}(b%+ULVRQ-9hgg3Mk3X(yA}3D)V;LJF*b
z?Ip`;*q}Zv&G=211I2OK*jF?c>rEGXc!KqjLmyuD@l)(m
zUaXik(=~z3#A!QGT9*Z|m%f2N##GfbDyZI1mDmfA63d&-9HZqOdqGRvjS4oul9Kvr
zy6Kopz^;1rn>Y_IBhz=*a-GI1u&Fq0WJ)u#KyUx*c$+%ldGoAK`__ACHYw>M2S|(k
z#UAaI4Q~3LnhvdXHWH^pgwhpRpr1UR3tm(sLs37U@%=zXY*3@wG;NH&w~KiG+0+h9
z{iN7911ZLi692-H#@5JCl&30*30@5nSD58{Y=r4$ur4Elc$rc9}lP$D4ML!_D|!V
zThV9#=12I-`$x(Kj0{Yh|=$R!8wH$Q{=&wym10msa)1Ec@#9(d$!_dedp#GRy8G
z@}~?ifPvvnZHob0(Yq7c4{3Zc4a*|P{XKXgop~;HDHV^+{0`Y2p0D@!XuxYmdE1YL
zfOjFv+kQ;>yr(5C=->9k)91yWlEglYK*vvo4=|^i3V+A^u#mDC?GYip5=dATt5Xs8
z7+R-_sM7^n5%(gA(WO~RG=@@3HzkQ33?x0!(wIu^NFdRUkZtKUCAIWqk<0<0Ne-wCkq2iThdb~nJX3l`pMWctq*z#{AHT@Mz;4X?sLhZxS>ZmEhO
ztxCZW1Q&B!e;wp$tkFvAAm2oU)|5oTuVr$hFgmF?N}UvbDbrb@5OG@yzmjoUcISj%
z$T%g)IlIjYK=^e`y^tJw6L(TJ^fIOyRTx>@nP?^`;fanMdKX7;@}zr(GEB4r6h?32
zo#}NC>cUcCw2FfhGa$d^N#sFc^cLP}>W?0$TX4>MwP^94SEbjT!rsR`+GlxqdnCZM
z0pdPF8$~2S797)GVu%s)A(q*SS!yp9EqkHi%SNe0S1M0qIEKAww)|?%vQ1ycyA{Y$
vA6{Eq^U(#zsGH)CQ}k{W;&$O(ZGyw!NogMiv18@vi
diff --git a/build/port_self.o b/build/port_self.o
deleted file mode 100644
index 33c53e0fe4de0f5bba0bb253563ffc8c31cbacab..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 37593
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
F`CtD->Tm!6
diff --git a/config.h b/config.h
index 9850bae..6237f32 100644
--- a/config.h
+++ b/config.h
@@ -9,6 +9,14 @@
#define u32 unsigned int
#define UNUSED(x) (void)(x)
+
+
+#define ERPC_DEBUG_ENABLE 1
+#if(ERPC_DEBUG_ENABLE == 1)
#define ERPC_DEBUG(...) printf(__VA_ARGS__)
-// #define ERPC_DEBUG(...)
+#else
+#define ERPC_DEBUG(...)
+#endif
+
+
#endif /* _CONFIG_H_ */
\ No newline at end of file
diff --git a/crc16.c b/crc16.c
index fd32d26..c125018 100644
--- a/crc16.c
+++ b/crc16.c
@@ -1,6 +1,6 @@
#include "crc16.h"
-static const uint16_t crc16tab[256] = {
+static const u16 crc16tab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108,
0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
@@ -31,38 +31,7 @@ static const uint16_t crc16tab[256] = {
0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
-// uint16_t crc16(const unsigned char *buf, size_t len) {
-// int counter;
-// uint16_t crc = 0;
-// for (counter = 0; counter < (int)len; counter++)
-// crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *buf++) & 0x00FF];
-// return crc;
-// }
-
-u16 cmd_cal_crc16(erpc_cmd_def_t *cmd) {
- u16 crc = 0;
- u32 counter = 0;
- crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.src_id) & 0x00FF];
- crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.dest_id) & 0x00FF];
- crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.msg_len) & 0x00FF];
- crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.type) & 0x00FF];
- crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.port) & 0x00FF];
- for (counter = 0; counter < cmd->head.msg_len; counter++)
- crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->data[counter]) & 0x00FF];
- cmd->crc_16[0] = (u8)(crc >> 8);
- cmd->crc_16[1] = (u8)(crc & 0x00FF);
- return crc;
-}
-/**
- * 检查crc16校验
- * return 0:校验成功
- * return 1:校验失败
- */
-u8 cmd_check_crc16(erpc_cmd_def_t *cmd) {
- u16 crc = cmd_cal_crc16(cmd);
- if (cmd->crc_16[0] != (u8)(crc >> 8) ||
- cmd->crc_16[1] != (u8)(crc & 0x00FF)) {
- return 1;
- }
- return 0;
-}
\ No newline at end of file
+inline u16 crc16_cal(u16 data,u16 crc)
+{
+ return (crc << 8) ^ crc16tab[((crc >> 8) ^ data) & 0x00FF];
+}
diff --git a/crc16.h b/crc16.h
index adb86fb..c722b4e 100644
--- a/crc16.h
+++ b/crc16.h
@@ -8,10 +8,8 @@ extern "C" {
#include
#include
#include "config.h"
-#include "erpc_core.h"
-uint16_t crc16(const unsigned char *buf, size_t len);
-u8 cmd_check_crc16(erpc_cmd_def_t *cmd);
-u16 cmd_cal_crc16(erpc_cmd_def_t *cmd);
+u16 crc16_cal(u16 data,u16 crc);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/erpc_core.c b/erpc_core.c
index 05fb2ee..965dcec 100644
--- a/erpc_core.c
+++ b/erpc_core.c
@@ -1,614 +1,413 @@
#include "erpc_core.h"
-
#include "crc16.h"
-
-/**
- * 操作系统相关
- */
-
-erpc_sleep erpc_sleep_tick = NULL;
-
-static list_t erpc_hw;
-void clean_cache(erpc_hw_cfg_t *hw)
+#include "string.h"
+void cal_crc16(erpc_msg_t *msg)
{
- for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
- {
- hw->rec_cache->state = ERPC_CMD_NO_ERROR;
- }
- for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
- {
- hw->send_cache[i].state = ERPC_CMD_NO_ERROR;
- }
+ u16 crc = 0;
+ crc = crc16_cal(msg->src_id, crc);
+ crc = crc16_cal(msg->dest_id, crc);
+ crc = crc16_cal(msg->type, crc);
+ crc = crc16_cal(msg->len, crc);
+ for (int i = 0; i < msg->len; i++)
+ {
+ crc = crc16_cal(msg->data[i], crc);
+ }
+ msg->crc = crc;
}
-/**
- * 注册 hardware 设备
- * 线程不安全
- */
-u32 erpc_hw_add(erpc_hw_cfg_t *hw)
+u8 check_crc16(erpc_msg_t *msg)
{
- list_t *list = &erpc_hw;
- if (list->data == NULL)
- {
- list->data = (void *)hw;
- clean_cache(hw);
- return ERPC_NO_ERROR;
- }
- list_t *list_node = malloc(sizeof(list_t));
- if (list_node == NULL)
- {
- return ERPC_ERR_MALLOC_ERROR;
- }
- list_node->data = (void *)hw;
- u8 hw_ord = hw->ord;
- // 检查hw是否已经存在
- while (list != NULL)
- {
- erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
- if (hw_cfg->ord == hw_ord)
+ u16 crc = 0;
+ crc = crc16_cal(msg->src_id, crc);
+ crc = crc16_cal(msg->dest_id, crc);
+ crc = crc16_cal(msg->type, crc);
+ crc = crc16_cal(msg->len, crc);
+ for (int i = 0; i < msg->len; i++)
{
- return ERPC_ERR_HW_EXIST;
+ crc = crc16_cal(msg->data[i], crc);
}
- list = list->next;
- }
- list_t *result = list_append(&erpc_hw, hw);
- if (result == NULL)
- {
- return ERPC_ERR_MALLOC_ERROR;
- }
- clean_cache(hw);
- return ERPC_NO_ERROR;
-}
-/**
- * 注册命令列表
- * 线程不安全
- */
-u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list)
-{
- list_t *list = &hw->cmd_list;
- if (list->data == NULL)
- {
- list->data = (void *)cmd_list;
- return ERPC_NO_ERROR;
- }
- list = list_append(&hw->cmd_list, cmd_list);
- if (list == NULL)
- {
- return ERPC_ERR_MALLOC_ERROR;
- }
- return ERPC_NO_ERROR;
-}
-/**
- * 移除 hardware 设备
- * 线程不安全
- */
-u32 erpc_hw_remove(u8 hw)
-{
- list_t *list = &erpc_hw;
- if (list->data == NULL)
- {
- return ERPC_ERR_NOFOND_HW;
- }
- while (list != NULL)
- {
- erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
- if (hw_cfg->ord == hw)
- {
- list_delete(&erpc_hw, list);
- free(list);
- return ERPC_NO_ERROR;
- }
- list = list->next;
- }
- return ERPC_ERR_NOFOND_HW;
-}
-/**
- * 获取 hardware 设备
- */
-erpc_hw_cfg_t *erpc_hw_get(u8 hw)
-{
- list_t *list = &erpc_hw;
- if (list->data == NULL)
- {
- return NULL;
- }
- while (list != NULL)
- {
- erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
- if (hw_cfg->ord == hw)
- {
- return hw_cfg;
- }
- }
- return NULL;
-}
-u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type,
- u8 *data, u16 len)
-{
- CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
- u8 cache_ord = 255;
- // 查找可用的发送缓存
- for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
- {
- if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR)
- {
- // ERPC_DEBUG("find send cache %d\n", i);
- cache_ord = i;
- break;
- }
- }
-
- CHECK_IF_ERROR(cache_ord == 255, ERPC_ERR_SEND_CACHE_FULL);
- // 准备数据
- hw_cfg->send_cache[cache_ord].state = ERPC_CMD_DATA_DEAL;
- erpc_cmd_def_t *cmd =
- (erpc_cmd_def_t *)&hw_cfg->send_cache[cache_ord].data[0];
- cmd->head.dest_id = dest_id;
- cmd->head.port = port;
- cmd->head.msg_len = len;
- if (data == NULL)
- {
- cmd->head.msg_len = 0;
- len = 0;
- }
- cmd->head.type = package_type;
- cmd->head.src_id = hw_cfg->local_id;
- if (len > 0 && data != NULL)
- {
- for (int i = 0; i < len; i++)
- {
- cmd->data[i] = data[i];
- }
- }
- // 计算校验和
- cmd_cal_crc16(cmd);
-
- // 发送数据
- hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND;
- // 等待数据发送完成
- int wait_time = CMD_TIMEOUT;
- while (wait_time > 0)
- {
- if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_OK)
- {
- break;
- }
- if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_DEST_BUSY)
- {
- return ERPC_ERR_DEST_BUSY;
- }
- if (erpc_sleep_tick != NULL)
- {
- erpc_sleep_tick(1);
- }
- wait_time--;
- }
- u32 ret = ERPC_NO_ERROR;
- do
- {
- if (wait_time == 0)
- {
- printf("send timeout,state:%d\n", hw_cfg->send_cache[cache_ord].state);
- ret = ERPC_ERR_SEND_TIMEOUT;
- break;
- }
- if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_ONCE)
- {
- ret = ERPC_ERR_DEST_NO_RESPONSE;
- break;
- }
- if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_REPEAT)
- {
- ret = ERPC_ERR_DEST_NO_RESPONSE;
- break;
- }
- } while (0);
- hw_cfg->send_cache[cache_ord].state = ERPC_CMD_NO_ERROR;
- return ret;
-}
-u32 erpc_boardcast(u16 port, u8 *data, u16 len)
-{
- list_t *list = &erpc_hw;
- if (list->data == NULL)
- {
- return ERPC_ERR_NOFOND_HW;
- }
- while (list != NULL)
- {
- erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
- u8 cache_ord = 255;
- // 查找可用的发送缓存
- for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
- {
- if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR)
- {
- // ERPC_DEBUG("find send cache %d\n", i);
- cache_ord = i;
- break;
- }
- }
- if (cache_ord == 255)
- {
- continue;
- }
- // 准备数据
- hw_cfg->send_cache[cache_ord].state = ERPC_CMD_DATA_DEAL;
- erpc_cmd_def_t *cmd =
- (erpc_cmd_def_t *)&hw_cfg->send_cache[cache_ord].data[0];
- cmd->head.dest_id = ERPC_BOARDCAST_ID;
- cmd->head.port = port;
- cmd->head.src_id = hw_cfg->local_id;
- cmd->head.msg_len = len;
- if (data == NULL)
- {
- cmd->head.msg_len = 0;
- }
- if (len > 0 && data != NULL)
- {
- for (int i = 0; i < len; i++)
- {
- cmd->data[i] = data[i];
- }
- }
- // 计算校验和
- cmd_cal_crc16(cmd);
- hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND;
- }
+ return crc == msg->crc;
}
-u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len)
+static erpc_cache_t *find_free_cache(erpc_hw_t *hw)
{
- erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
- u32 ret =
- erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_REQ, data, len);
- return ret;
-}
-
-u32 erpc_wait_resp_package(u8 hw, u8 dest_id, u16 port, u8 *reply_data,
- u16 *reply_len, u32 time_out)
-{
- erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
- CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
- while (time_out > 0)
- {
- for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
{
- erpc_data_cache_t *rec_cahce = &hw_cfg->rec_cache[i];
- if (rec_cahce->state != ERPC_CMD_RESP_OK)
- {
- continue;
- }
- erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&rec_cahce->data[0];
- if (cmd->head.port != port)
- {
- continue;
- }
- if (cmd->head.src_id != dest_id)
- {
- continue;
- }
- if (reply_data != NULL)
- {
- // memccpy(reply_data, cmd->data, 0, cmd->head.msg_len);
- memcpy(reply_data, cmd->data, cmd->head.msg_len);
- if (reply_len != NULL)
+
+ if (hw->send_cache[i].state == CACHE_FREE)
{
- *reply_len = cmd->head.msg_len;
+ return &hw->send_cache[i];
}
- }
- rec_cahce->state = ERPC_CMD_NO_ERROR;
- return ERPC_NO_ERROR;
}
- if (erpc_sleep_tick != NULL)
+ return NULL;
+}
+// static erpc_cache_t *clean_ack_cache(erpc_hw_t *hw, u8 dest_id)
+// {
+// return NULL;
+// }
+static erpc_cache_t *find_ack_cache(erpc_hw_t *hw, u8 dest_id, u16 port)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
{
- erpc_sleep_tick(1);
- }
- time_out--;
- }
- CHECK_IF_ERROR(time_out == 0, ERPC_ERR_DEST_NO_REPLY);
- return ERPC_NO_ERROR;
-}
-u32 erpc_send_wait_reply(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len,
- u8 *reply_data, u16 *reply_len, u32 timeout)
-{
- u32 ret = erpc_send(hw, dest_id, port, data, len);
- if (reply_len != NULL)
- {
- *reply_len = 0;
- }
- CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
- ret =
- erpc_wait_resp_package(hw, dest_id, port, reply_data, reply_len, timeout);
- CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
- return ERPC_NO_ERROR;
-}
-u32 erpc_replay(u8 hw, u8 dest_id, u16 port, u8 *data_out, u16 len)
-{
- erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
- u32 ret = erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_RESP,
- data_out, len);
-
- return ret;
-}
-
-u32 erpc_send_data(erpc_hw_cfg_t *hw)
-{
- for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
- {
- if (hw->send_cache[i].state == ERPC_CMD_WAIT_SEND)
- {
- erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
- u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd->head.msg_len;
- hw->send_lock();
- u8 ret = hw->write((u8 *)hw->send_cache[i].data, len);
- hw->send_unlock();
- CHECK_IF_ERROR(ret != 0, ERPC_ERR_HW_SEND_FAIL);
- hw->send_cache[i].state = ERPC_CMD_SEND_ONCE;
- }
- }
- return ERPC_NO_ERROR;
-}
-
-u32 erpc_rev_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
-{
- for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
- {
- if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
- hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT)
- {
- erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
- if (cmd_rev->head.port == cmd_send->head.port)
- {
- hw->send_cache[i].state = ERPC_CMD_SEND_OK;
- return ERPC_NO_ERROR;
- }
- }
- }
- return ERPC_NO_ERROR;
-}
-u32 erpc_rev_resp_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
-{
- erpc_cmd_def_t cmd_send;
- cmd_send.head.dest_id = cmd_rev->head.src_id;
- cmd_send.head.port = cmd_rev->head.port;
- cmd_send.head.msg_len = 0;
- cmd_send.head.type = PACKAGE_TYPE_CMD_RESP_ACK;
- cmd_send.head.src_id = hw->local_id;
- cmd_cal_crc16(&cmd_send);
- u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send.head.msg_len;
- hw->send_lock();
- u8 ret = hw->write((u8 *)&cmd_send, len);
- hw->send_unlock();
- CHECK_IF_ERROR(ret != 0, ERPC_ERR_HW_SEND_FAIL);
- return ERPC_NO_ERROR;
-}
-// 重发数据包
-u32 erpc_rev_repeat_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
-{
- for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
- {
- if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
- hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT)
- {
- erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
- if (cmd_rev->head.port == cmd_send->head.port)
- {
- u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send->head.msg_len;
- hw->send_lock();
- u32 ret = hw->write((u8 *)hw->send_cache[i].data, len);
- hw->send_unlock();
- hw->send_cache[i].state = ERPC_CMD_SEND_REPEAT;
- CHECK_IF_ERROR(ret, ERPC_ERR_HW_SEND_FAIL); //
- return ERPC_NO_ERROR;
- }
- }
- }
- return ERPC_NO_ERROR;
-}
-u32 erpc_send_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
-{
- erpc_cmd_def_t cmd_send;
- cmd_send.head.dest_id = cmd_rev->head.src_id;
- cmd_send.head.port = cmd_rev->head.port;
- cmd_send.head.msg_len = 0;
- cmd_send.head.type = PACKAGE_TYPE_CMD_REQ_ACK;
- cmd_send.head.src_id = hw->local_id;
- cmd_cal_crc16(&cmd_send);
- u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send.head.msg_len;
- hw->send_lock();
- u8 ret = hw->write((u8 *)&cmd_send, len);
- hw->send_unlock();
- CHECK_IF_ERROR(ret != 0, ERPC_ERR_HW_SEND_FAIL);
- return ERPC_NO_ERROR;
-}
-
-u32 erpc_rev_package(erpc_hw_cfg_t *hw)
-{
- for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
- {
- if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL)
- {
- hw->deal_lock();
- if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL)
- {
- hw->rec_cache[i].state = ERPC_CMD_SERVER_DEAL;
- }
- else
- {
- hw->deal_unlock();
- continue;
- }
- hw->deal_unlock();
- // ERPC_DEBUG("find cmd wait server deal %d\n", i);
- erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->rec_cache[i].data[0];
- // 检查crc
- u8 crc_result = cmd_check_crc16(cmd);
- // 丢弃错误数据包
- if (crc_result)
- {
- hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
- continue;
- }
- // 丢弃不是本地数据包
- if (cmd->head.dest_id != hw->local_id)
- {
- hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
- continue;
- }
- // 处理数据包
- switch (cmd->head.type)
- {
- case PACKAGE_TYPE_CMD_REQ:
- ERPC_DEBUG("{REQ}\n");
- erpc_send_ack_package(hw, cmd);
- hw->rec_cache[i].state = ERPC_CMD_WAIT_TASK_DEAL;
- break;
- case PACKAGE_TYPE_CMD_REQ_ACK:
- ERPC_DEBUG("{ACK}\n");
-
- erpc_rev_ack_package(hw, cmd);
- hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
- break;
-
- case PACKAGE_TYPE_CMD_REPEAT:
- erpc_rev_repeat_package(hw, cmd);
- hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
- break;
- case PACKAGE_TYPE_CMD_RESP:
- ERPC_DEBUG("{RESP}\n");
- erpc_rev_resp_package(hw, cmd);
- hw->rec_cache[i].state = ERPC_CMD_RESP_OK;
- break;
- case PACKAGE_TYPE_CMD_RESP_ACK:
- ERPC_DEBUG("{RESP_ACK}\n");
- erpc_rev_ack_package(hw, cmd);
- hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
- break;
- default:
-
- break;
- }
- }
- }
- return ERPC_NO_ERROR;
-}
-void erpc_rev_package_core()
-{
- list_t *list = &erpc_hw;
- if (list->data == NULL)
- {
- return;
- }
- while (list != NULL)
- {
- erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
- erpc_rev_package(hw);
- list = list->next;
- }
-}
-u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len)
-{
- erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
- CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
- for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
- {
- if (hw_cfg->rec_cache[i].state == ERPC_CMD_NO_ERROR)
- {
- // ERPC_DEBUG("set rev cache %d\r\n", i);
- memcpy(hw_cfg->rec_cache[i].data, data, len);
- hw_cfg->rec_cache[i].state = ERPC_CMD_WAIT_SERVER_DEAL;
- return ERPC_NO_ERROR;
- }
- }
- return ERPC_ERR_REC_CACHE_FULL;
-}
-void erpc_send_deal_core()
-{
- list_t *list = &erpc_hw;
- if (list->data == NULL)
- {
- return;
- }
- while (list != NULL)
- {
- erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
- erpc_send_data(hw);
- }
- if (erpc_sleep_tick != NULL)
- {
- erpc_sleep_tick(1);
- }
-}
-
-void erpc_rev_deal_core()
-{
- list_t *list = &erpc_hw;
- if (list->data == NULL)
- {
- return;
- }
- while (list != NULL)
- {
- erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
- { // 遍历接收缓存
- for (int j = 0; j < MAX_REC_CMD_CACHE_NUM; j++)
- {
- { // 发现等待处理的数据包
- if (hw->rec_cache[j].state != ERPC_CMD_WAIT_TASK_DEAL)
- {
- continue;
- }
+ erpc_cache_t *cache = &hw->send_cache[i];
+ if (cache->state == CACHE_REC_ACK && cache->msg.src_id == dest_id && cache->msg.port == port)
+ {
+ return cache;
}
- { // 多线程下,抢占处理权限
- hw->deal_lock();
- if (hw->rec_cache[j].state == ERPC_CMD_WAIT_TASK_DEAL)
- {
- // 获取指令的处理权限
- hw->rec_cache[j].state = ERPC_CMD_WAIT_TASK_DEAL_FINISH;
- }
- else
- {
- // 已经有线程抢先执行了
- hw->deal_unlock();
- continue;
- }
- hw->deal_unlock();
- }
- { // 处理指令
- // 搜索指令列表
- list_t *cmd_list = &hw->cmd_list;
- // 链表是空的
- if (cmd_list->data == NULL)
- {
- continue;
- }
- // 获取指令指针
- erpc_cmd_def_t *cmd_def = (erpc_cmd_def_t *)hw->rec_cache[j].data;
- while (cmd_list != NULL)
- { // 搜索指令列表
- erpc_cmd_list_t *cmd_obj = (erpc_cmd_list_t *)cmd_list->data;
- if (cmd_obj->cmd == cmd_def->head.port)
+ }
+ return NULL;
+}
+static u8 check_port_send_available(erpc_hw_t *hw, u8 port)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ erpc_cache_t *cache = &hw->send_cache[i];
+ if (cache->state != CACHE_FREE)
+ {
+ if (cache->msg.port == port)
{
- if (cmd_obj->handle != NULL)
- {
- // 指令调用
- cmd_obj->handle(hw->ord, cmd_def->head.src_id,
- cmd_def->head.dest_id, cmd_def->head.port,
- cmd_def->data, cmd_def->head.msg_len);
- }
-
- break;
+ return 0;
}
- cmd_list = cmd_list->next;
- }
}
- // 处理完成 丢弃缓存 , 无论是否执行指令,都需要把数据包丢弃
- hw->rec_cache[j].state = ERPC_CMD_NO_ERROR;
- }
}
- list = list->next;
- }
- if (erpc_sleep_tick != NULL)
- {
- erpc_sleep_tick(1);
- }
+ return 1;
}
+static void free_port_ack_cache(erpc_hw_t *hw, u16 port)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ erpc_cache_t *cache = &hw->recv_cache[i];
+ if (cache->state == CACHE_REC_ACK)
+ {
+ if (cache->msg.port == port)
+ {
+ cache->state = CACHE_FREE;
+ }
+ }
+ }
+}
+static u32 send_data(erpc_hw_t *hw, erpc_cache_t *cache, u16 port, u16 *timeout)
+{
+ free_port_ack_cache(hw, port);
+ cache->state = CACHE_WAIT_SEND;
+ // 等待发送完成
+ while (*timeout)
+ {
+ if (cache->state == CACHE_SEND_OK)
+ {
+ return 0;
+ }
+ else if (cache->state == CACHE_SEND_HW_ERR)
+ {
+ return ERPC_ERR_SEND_HW_ERR;
+ }
+ else
+ {
+ hw->sleep(1);
+ }
+ (*timeout)--;
+ }
+
+ if (*timeout == 0)
+ {
+ return ERPC_ERR_SEND_TIMEOUT;
+ }
+ return 0;
+}
+static u32 wait_ack(erpc_hw_t *hw, erpc_cache_t *rec, u8 dest_id, u16 port, u16 *timeout)
+{
+ while (*timeout)
+ {
+ rec = find_ack_cache(hw, dest_id, port);
+ if (rec != NULL)
+ {
+ return 0;
+ }
+ hw->sleep(1);
+ (*timeout)--;
+ }
+ if (timeout == 0)
+ {
+ return ERPC_ERR_SEND_ACK_TIMEOUT;
+ }
+ return 0;
+}
+ u32 send_request(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u16 timeout, u8 retry)
+{
+ erpc_cache_t *cache = find_free_cache(hw);
+ CHECK_DEAL(cache == NULL, ERPC_ERR_NO_FREE_SEND_CACHE);
+ hw->lock();
+ if (check_port_send_available(hw, port) == 0)
+ {
+ hw->unlock();
+ return ERPC_ERR_SEND_PORT_IS_INUSE;
+ }
+ cache->msg.dest_id = dest_id;
+ cache->state = CACHE_IN_USE;
+ hw->unlock();
+ cache->msg.src_id = hw->local_id;
+ cache->msg.type = ERPC_MSG_TYPE_REQUEST;
+ cache->msg.len = len;
+ cache->msg.port = port;
+ memcpy(cache->msg.data, data, len);
+ cal_crc16(&cache->msg);
+ erpc_cache_t *rec = NULL;
+ u16 timeout_copy = timeout;
+ while (retry--)
+ {
+ /**
+ * 发送失败应该立即返回,不能retry
+ */
+ u32 ret = send_data(hw, cache, port, &timeout);
+ if (ret)
+ {
+ cache->state = CACHE_FREE;
+ return ret;
+ }
+ // 等待ack
+ ret = wait_ack(hw, rec, dest_id, port, &timeout);
+ if (ret == 0)
+ {
+ break;
+ }
+ timeout = timeout_copy;
+ }
+ CHECK_DEAL(retry == 0, ERPC_ERR_SEND_ACK_TIMEOUT);
+ // 释放cache
+ cache->state = CACHE_FREE;
+ rec->state = CACHE_FREE;
+ return 0;
+}
+
+static erpc_cache_t *find_response_cache(erpc_hw_t *hw, u8 dest_id, u16 port)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ erpc_cache_t *cache = &hw->recv_cache[i];
+ if (cache->state == CACHE_GET_RESP && cache->msg.src_id == dest_id && cache->msg.port == port)
+ {
+ return cache;
+ }
+ }
+ return NULL;
+}
+static void free_response_cache(erpc_hw_t *hw, u8 dest_id, u16 port)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ erpc_cache_t *cache = &hw->recv_cache[i];
+ if (cache->state == CACHE_GET_RESP && cache->msg.src_id == dest_id && cache->msg.port == port)
+ {
+ cache->state = CACHE_FREE;
+ }
+ }
+}
+static u32 send_ack(erpc_hw_t *hw, u8 dest_id, u16 port, u16 time_out)
+{
+ erpc_cache_t *cache = find_free_cache(hw);
+ CHECK_DEAL(cache == NULL, ERPC_ERR_NO_FREE_SEND_CACHE);
+ hw->lock();
+ if (check_port_send_available(hw, port) == 0)
+ {
+ hw->unlock();
+ return ERPC_ERR_SEND_PORT_IS_INUSE;
+ }
+ cache->msg.dest_id = dest_id;
+ cache->state = CACHE_IN_USE;
+ hw->unlock();
+ cache->msg.src_id = hw->local_id;
+ cache->msg.type = ERPC_MSG_TYPE_ACK;
+ cache->msg.len = 0;
+ cache->msg.port = port;
+ cal_crc16(&cache->msg);
+ u32 ret = send_data(hw, cache, port, &time_out);
+ return ret;
+}
+/**
+ * 发送请求,等待响应
+ * @param hw 硬件接口
+ * @param dest_id 目标ID
+ * @param port 端口号
+ * @param data_out 请求数据
+ * @param len_out 请求数据长度
+ * @param data_in 响应数据
+ * @param len_in 响应数据长度
+ * @param send_timeout 发送超时时间
+ * @param recv_timeout 接收超时时间
+ * @param retry 重试次数
+ * @return 0 成功,其他失败
+ */
+ u32 send_request_wait_response(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data_out, u16 len_out, u8 *data_in, u16 *len_in, u16 send_timeout, u16 recv_timeout, u8 retry)
+{
+ free_response_cache(hw, dest_id, port);
+ u32 ret = send_request(hw, dest_id, port, data_out, len_out, send_timeout, retry);
+ CHECK_DEAL(ret != 0, ret);
+ while (recv_timeout)
+ {
+ erpc_cache_t *rec = find_response_cache(hw, dest_id, port);
+ if (rec != NULL)
+ {
+ // 拷贝数据
+ int len = rec->msg.len;
+ if (len > *len_in)
+ {
+ len = *len_in;
+ }
+ memcpy(data_in, rec->msg.data, len);
+ *len_in = len;
+ rec->state = CACHE_FREE;
+ break;
+ }
+ recv_timeout--;
+ hw->sleep(1);
+ }
+ CHECK_DEAL(recv_timeout == 0, ERPC_ERR_NO_CMD_RETURN);
+ ret = send_ack(hw, dest_id, port, send_timeout);
+ CHECK_DEAL(ret != 0, ret);
+ return 0;
+}
+
+ u32 send_response(erpc_hw_t *hw, erpc_cache_t *cache_rec, u8 *data, u16 len, u16 timeout, u8 retry)
+{
+ erpc_cache_t *cache = find_free_cache(hw);
+ CHECK_DEAL(cache == NULL, ERPC_ERR_NO_FREE_SEND_CACHE);
+ hw->lock();
+ if (check_port_send_available(hw, cache->msg.port) == 0)
+ {
+ hw->unlock();
+ return ERPC_ERR_SEND_PORT_IS_INUSE;
+ }
+ cache->msg.dest_id = cache_rec->msg.src_id;
+ cache->state = CACHE_IN_USE;
+ hw->unlock();
+ cache->msg.src_id = hw->local_id;
+ cache->msg.type = ERPC_MSG_TYPE_ACK;
+ cache->msg.len = 0;
+ cache->msg.port = cache_rec->msg.port;
+ memcpy(cache->msg.data, data, len);
+ cal_crc16(&cache->msg);
+ u16 timeout_copy = timeout;
+ erpc_cache_t *rec = NULL;
+ while (retry--)
+ {
+ u32 ret = send_data(hw, cache, cache->msg.port, &timeout);
+ if (ret)
+ {
+ cache->state = CACHE_FREE;
+ return ret;
+ }
+ // 等待ack
+ ret = wait_ack(hw, rec,cache->msg.dest_id,cache->msg.port, &timeout);
+ if (ret == 0)
+ {
+ break;
+ }
+ timeout = timeout_copy;
+ }
+ CHECK_DEAL(retry == 0, ERPC_ERR_SEND_ACK_TIMEOUT);
+ // 释放cache
+ cache->state = CACHE_FREE;
+ rec->state = CACHE_FREE;
+ return 0;
+}
+
+u32 write_rec_cache(erpc_hw_t *hw, u8 *data, u16 len)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ if (hw->recv_cache[i].state == CACHE_FREE)
+ {
+ hw->lock();
+ u8 *data_in = (u8 *)&hw->recv_cache[i].msg;
+ for (int j = 0; j < len; j++)
+ {
+ data_in[j] = data[j];
+ }
+ hw->recv_cache[i].state = CACHE_GET_DATA;
+ hw->unlock();
+ return 0;
+ }
+
+ }
+ return 1;
+}
+ void send_core(erpc_hw_t *hw)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ erpc_cache_t *cache = &hw->send_cache[i];
+ if (cache->state == CACHE_WAIT_SEND)
+ {
+ u32 ret = hw->send((u8 *)&cache->msg, cache->msg.len + ERPC_MSG_HEADER_SIZE);
+ if (ret == 0)
+ {
+ cache->state = CACHE_SEND_OK;
+ }
+ else
+ {
+ cache->state = CACHE_SEND_HW_ERR;
+ }
+ }
+ }
+}
+
+ void recv_core(erpc_hw_t *hw)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ erpc_cache_t *cache = &hw->recv_cache[i];
+ if (cache->state == CACHE_GET_DATA)
+ {
+ if (check_crc16(&cache->msg) == 1)
+ {
+ cache->state = CACHE_GET_MSG;
+ }
+ else
+ {
+ cache->state = CACHE_FREE;
+ }
+ }
+ switch (cache->state)
+ {
+ case CACHE_GET_MSG:
+ {
+ switch (cache->msg.type)
+ {
+ case ERPC_MSG_TYPE_ACK:
+ {
+ cache->state = CACHE_REC_ACK;
+ }
+ break;
+ case ERPC_MSG_TYPE_RESPONSE:
+ {
+ cache->state = CACHE_GET_RESP;
+ }
+ break;
+ case ERPC_MSG_TYPE_REQUEST:
+ {
+ cache->state = CACHE_WAIT_HANDLE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void recv_handle(erpc_hw_t *hw)
+{
+ for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++)
+ {
+ erpc_cache_t *cache = &hw->recv_cache[i];
+ if (cache->state == CACHE_WAIT_HANDLE)
+ {
+
+ cache->state = CACHE_FREE;
+ }
+ }
+}
\ No newline at end of file
diff --git a/erpc_core.h b/erpc_core.h
index 0f19aaf..280997a 100644
--- a/erpc_core.h
+++ b/erpc_core.h
@@ -1,145 +1,110 @@
-#ifndef ERPC_CORE_H_
-#define ERPC_CORE_H_
-
-#include
-#include
-#include
-
+#ifndef _ERPC_CORE_H_
+#define _ERPC_CORE_H_
#include "config.h"
#include "list.h"
-#define ERPC_VERSION "0.0.1"
+#define ERPC_VERSION_MAJOR 1
+#define ERPC_VERSION_MINOR 0
+#define ERPC_VERSION_PATCH 0
-typedef enum package_type {
- PACKAGE_TYPE_DEV_POWER_ON = 0,
- PACKAGE_TYPE_CMD_REQ,
- PACKAGE_TYPE_CMD_REQ_ACK,
- PACKAGE_TYPE_CMD_RESP,
- PACKAGE_TYPE_CMD_RESP_ACK,
- PACKAGE_TYPE_CMD_REPEAT, // crc校验失败,请求重发
- PACKAGE_TYPE_DEV_POWER_OFF,
- PACKAGE_TYPE_CMD_SERCH_DEV_ONLINE,
-} package_type;
+#define ERPC_MSG_HEADER_SIZE 9
+#define ERPC_MSG_DATA_MAX_SIZE (256 - ERPC_MSG_HEADER_SIZE + 2)
+#define ERPC_MSG_CACHE_SIZE 16 // Maximum number of messages in cache
-// 广播ID
-#define ERPC_BOARDCAST_ID 0xff
+#define ERPC_SEND_TIMEOUT 30 // 发送超时时间,单位tick
+typedef struct erpc_msg_t
+{
+ u8 src_id;
+ u8 dest_id;
+ u8 type;
+ u16 port;
+ u16 len;
+ u16 crc;
+ u8 data[ERPC_MSG_DATA_MAX_SIZE];
+} erpc_msg_t;
-typedef struct erpc_cmd_head_t {
- u8 src_id;
- u8 dest_id;
- u8 type; // package_type
- u16 port; // 指令号,指令号=端口号
- u8 msg_len;
-} erpc_cmd_head_t;
-
-#define MAX_CMD_LEN (256 - sizeof(erpc_cmd_head_t)) // crc16最大支持256字节
-
-typedef struct erpc_cmd_def_t {
- erpc_cmd_head_t head;
- u8 crc_16[2];
- u8 data[MAX_CMD_LEN];
-} erpc_cmd_def_t;
-
-#define CMD_MAX_RETRY 5 // 最大重发次数
-#define CMD_TIMEOUT 30 // 超时时间 tick
-#define MAX_REC_CMD_CACHE_NUM \
- 10 // 最大接收指令缓存数量,接受指令优先级>处理指令优先级
-#define MAX_SEND_CMD_CACHE_NUM \
- 10 // 最大发送指令缓存数量,发送指令优先级>接收指令优先级
-typedef enum erpc_status {
- ERPC_CMD_NO_ERROR, // 发送cache,接收cache空闲
- ERPC_CMD_DATA_DEAL, // 发送cache数据组织中
- ERPC_CMD_WAIT_SERVER_DEAL, // 等待服务线程处理接受cache
- ERPC_CMD_SERVER_DEAL, // 服务线程处理接受cache
- ERPC_CMD_WAIT_TASK_DEAL, // 等待任务线程处理指令
- ERPC_CMD_WAIT_TASK_DEAL_FINISH, // 等待任务线程处理指令完成
- ERPC_CMD_WAIT_SEND, // 等待服务线程处理发送cache
- ERPC_CMD_SEND_ONCE, // 发送指令成功
- ERPC_CMD_SEND_REPEAT, // 发送指令重发
- ERPC_CMD_SEND_OK, // 发送指令成功
- ERPC_CMD_DEST_BUSY, // 目标设备忙
- ERPC_CMD_RESP_OK, // 指令响应成功
-} erpc_status;
-
-typedef struct erpc_data_cache_t {
- u8 state;
- u8 data[256];
-} erpc_data_cache_t;
-
-typedef u32 (*erpc_cmd_handle_t)(u8 src_id, u8 dest_id, u16 port, u8 *data,
- u16 len);
-
-typedef struct erpc_cmd_list_t {
- u16 cmd;
- u32 (*handle)(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len);
-} erpc_cmd_list_t;
-typedef enum ERPC_ROLE {
- ERPC_ROLE_MASTER,
- ERPC_ROLE_SLAVE,
-} ERPC_ROLE;
-typedef struct erpc_hw_cfg_t {
- u8 ord;
- u8 local_id;
- u8 (*write)(u8 *data, u16 len);
- void (*send_lock)(void);
- void (*send_unlock)(void);
- erpc_data_cache_t rec_cache[MAX_REC_CMD_CACHE_NUM];
- erpc_data_cache_t send_cache[MAX_SEND_CMD_CACHE_NUM];
- void (*deal_lock)(void);
- void (*deal_unlock)(void);
- list_t cmd_list;
-} erpc_hw_cfg_t;
-
-#define CHECK_IF_ERROR(condition, error) \
- if (condition) { \
- return error; \
- }
-#define CHECK_IF_ERROR_AND_DO(condition, error, action) \
- if (condition) { \
- action; \
- return error; \
- }
-typedef enum erpc_error {
- ERPC_NO_ERROR = 0,
- ERPC_ERR_NOFOND_HW,
- ERPC_ERR_SEND_CACHE_FULL,
- ERPC_ERR_SEND_TIMEOUT,
- ERPC_ERR_HW_SEND_FAIL, // 硬件层发来的错误 erpc_hw_cfg_t.write返回错误
- ERPC_ERR_DEST_BUSY,
- ERPC_ERR_DEST_NO_RESPONSE, // 目标设备无响应
- ERPC_ERR_DEST_NO_REPLY, // 目标设备无回复或者回复超时
- ERPC_ERR_MALLOC_ERROR, // malloc失败,内存不足
- ERPC_ERR_HW_EXIST, // 硬件已经存在
- ERPC_ERR_HW_NOT_EXIST, // 硬件不存在
- ERPC_ERR_REC_CACHE_FULL, // 接收缓存满
+typedef struct erpc_cache_t
+{
+ u8 state;
+ erpc_msg_t msg;
+} erpc_cache_t;
+typedef enum erpc_msg_type
+{
+ ERPC_MSG_TYPE_REQUEST = 0,
+ ERPC_MSG_TYPE_ACK,
+ ERPC_MSG_TYPE_RESPONSE,
+}erpc_msg_type;
+typedef enum erpc_cache_state
+{
+ CACHE_FREE = 0,
+ // 占用
+ CACHE_IN_USE,
+ // 发送cache
+ CACHE_WAIT_SEND,
+ CACHE_SEND_OK,
+ CACHE_SEND_HW_ERR,
+ // 接收cache
+ CACHE_GET_DATA, // 发现数据
+ CACHE_GET_MSG, // 发现完整消息
+ CACHE_REC_ACK, // 收到ACK
+ CACHE_GET_RESP, // 收到RESP数据包
+ CACHE_WAIT_HANDLE, // 等待处理
+} erpc_cache_state;
+typedef enum erpc_error
+{
+ ERPC_OK = 0,
+ // 发送REQ
+ ERPC_ERR_NO_FREE_SEND_CACHE, // 没有空闲的发送缓存
+ ERPC_ERR_SEND_TIMEOUT, // 发送REQ超时
+ ERPC_ERR_SEND_ACK_TIMEOUT, // 发送REQ成功,但是没有收到ACK
+ ERPC_ERR_SEND_PORT_IS_INUSE, // 发送失败,端口已被占用
+ ERPC_ERR_SEND_HW_ERR, // 发送失败,硬件错误
+ // 接收REQ
+ ERPC_ERR_NO_CMD_RETURN, // 发生REQ成功,但是没有收到RESP包
} erpc_error;
-typedef void (*erpc_sleep)(u32 tick);
+typedef struct erpc_hw_t
+{
+ u8 local_id;
+ void (*lock)(void);
+ void (*unlock)(void);
+ void (*sleep)(u32 ms);
+ u32 (*send)(u8 *data, u16 len);
+ erpc_cache_t send_cache[ERPC_MSG_CACHE_SIZE];
+ erpc_cache_t recv_cache[ERPC_MSG_CACHE_SIZE];
+ list_t handler_list;
+} erpc_hw_t;
-void erpc_send_deal_core(); // 发送指令处理线程
-u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len); // 写入接受缓存
-void erpc_rev_package_core(); // 处理接受到的包,通讯层面处理
-void erpc_rev_deal_core(); // 处理接受到的指令,业务层面处理
-extern erpc_sleep erpc_sleep_tick;
+typedef struct handler_list_t
+{
+ u16 port;
+ void (*handle)(erpc_hw_t *hw, erpc_cache_t *cache, u8 *data, u16 len);
+} handler_list_t;
-u32 erpc_hw_add(erpc_hw_cfg_t *hw);
-u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list);
+#define CHECK_DEAL(condition, error) \
+ if ((condition)) \
+ return error;
/**
- * 单纯发送消息
+ * 内核函数,需要手动sleep
*/
-u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len);
-/**
- * 发送消息并等待回复
- */
-u32 erpc_send_wait_reply(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len,
- u8 *reply_data, u16 *reply_len, u32 timeout);
-/**
- * 回复消息
- */
-u32 erpc_replay(u8 hw, u8 dest_id, u16 port, u8 *data_out, u16 len);
+void send_core(erpc_hw_t *hw);
+void recv_core(erpc_hw_t *hw);
+void recv_handle(erpc_hw_t *hw);
/**
- * 广播消息
+ * 用户函数
*/
-u32 erpc_boardcast(u16 port, u8 *data, u16 len);
+u32 send_request(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u16 timeout, u8 retry);
+u32 send_request_wait_response(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data_out, u16 len_out, u8 *data_in, u16 *len_in, u16 send_timeout, u16 recv_timeout, u8 retry);
+u32 send_response(erpc_hw_t *hw, erpc_cache_t *cache, u8 *data, u16 len, u16 timeout, u8 retry);
+u32 write_rec_cache(erpc_hw_t *hw, u8 *data, u16 len);
+/**
+ * 注册处理函数
+ */
+#define EXPORT_ERPC_HANDLE(hw, _port, _handle) \
+ static handler_list_t _A##_handle = \
+ { \
+ .port = _port,\
+.handle = _handle,\
+};\
+EXPORT_LIST_NODE(hw.list,_A##_handle);
-
-#endif /* ERPC_CORE_H_ */
\ No newline at end of file
+#endif /* _ERPC_CORE_H_ */
\ No newline at end of file
diff --git a/erpc_net.c b/erpc_net.c
deleted file mode 100644
index 3c9b91f..0000000
--- a/erpc_net.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "erpc_net.h"
-#include "erpc_core.h"
-
diff --git a/erpc_net.h b/erpc_net.h
deleted file mode 100644
index 3d38351..0000000
--- a/erpc_net.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "erpc_core.h"
-
-u32 erpc_find_all();
\ No newline at end of file
diff --git a/erpc_port_self.c b/erpc_port_self.c
new file mode 100644
index 0000000..372a0d3
--- /dev/null
+++ b/erpc_port_self.c
@@ -0,0 +1,104 @@
+#include "erpc_core.h"
+
+#include
+#include
+
+HANDLE hMutex;
+
+static void lock()
+{
+ WaitForSingleObject(hMutex, INFINITE);
+}
+
+static void unlock()
+{
+ ReleaseMutex(hMutex);
+}
+static void sleep(u32 ms)
+{
+ Sleep(ms);
+}
+extern erpc_hw_t port_self;
+static u32 erpc_send(u8 *data, u16 len)
+{
+ write_rec_cache(&port_self,data,len);
+}
+erpc_hw_t port_self = {
+ .lock = lock,
+ .unlock = unlock,
+ .sleep = sleep,
+ .local_id = 0x12,
+ .send = erpc_send,
+};
+
+
+static void test1(){
+
+}
+DWORD WINAPI fun(LPVOID lpParam)
+{
+ UNUSED(lpParam);
+ while (1)
+ {
+ Sleep(1000);
+ }
+}
+DWORD WINAPI send_thread(LPVOID lpParam)
+{
+ UNUSED(lpParam);
+ while (1)
+ {
+ send_core(&port_self);
+ Sleep(1);
+ }
+}
+DWORD WINAPI recv_thread(LPVOID lpParam)
+{
+ UNUSED(lpParam);
+ while (1)
+ {
+ recv_core(&port_self);
+ Sleep(1);
+ }
+}
+
+DWORD WINAPI recv_handle_thread(LPVOID lpParam)
+{
+ UNUSED(lpParam);
+ while (1)
+ {
+ recv_handle(&port_self);
+ Sleep(1);
+ }
+}
+
+int main()
+{
+ hMutex = CreateMutex(NULL, FALSE, TEXT("MyMutex"));
+
+ if (hMutex == NULL)
+ {
+ printf("CreateMutex error: %d\n", GetLastError());
+ return 1;
+ }
+
+ HANDLE hThreads[4];
+
+ hThreads[0] = CreateThread(NULL, 0, fun, NULL, 0, NULL);
+ hThreads[1] = CreateThread(NULL, 0, send_thread, NULL, 0, NULL);
+ hThreads[2] = CreateThread(NULL, 0, recv_thread, NULL, 0, NULL);
+ hThreads[3] = CreateThread(NULL, 0, recv_handle_thread, NULL, 0, NULL);
+ // 等待所有线程完成
+ WaitForMultipleObjects(4, hThreads, TRUE, INFINITE);
+
+ // 关闭线程句柄
+ for (int i = 0; i < 4; i++)
+ {
+ CloseHandle(hThreads[i]);
+ }
+
+ // 关闭Mutex句柄
+ CloseHandle(hMutex);
+
+ return 0;
+}
diff --git a/erpc设计文档.md b/erpc设计文档.md
deleted file mode 100644
index f7d5498..0000000
--- a/erpc设计文档.md
+++ /dev/null
@@ -1,39 +0,0 @@
-
-## 协议设计
-
-### 指令通讯
-1. 指令发送方法:
- 采用send-ack模式,即主机发送指令后,等待目标设备的ack确认,确认后才认为指令发送成功。
-2. notify-noreply模式:
- 接口:
- ```c
- u32 erpc_sand(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len)
- ```
- 描述:
- 主机对目标设备发送一条指令,并不期待回复。其本质就是发送一次指令。
- 
-3. notify-reply模式:
- 接口:
- ```c
- //主机:
- u32 erpc_send_wait_reply(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len, u8 *reply_data, u16 *reply_len, u32 timeout);
- //目标设备:
- u32 erpc_replay(u8 hw, u8 dest_id, u16 port, u8 *data_out, u16 len);
-
- ```
- 描述:
- 本质由2条指令组成。
- 主机发送req指令,从机直接回复。主机开始等待从机指令。
- 从机处理完成后,向主机发送rep指令,并附带回复数据。
- 主机收到rep指令后,开始等待rep指令的ack确认。
- 
-4. 指令工作在单线程模式下:
- 指令发送后,等待ack确认,直到确认后才认为指令发送成功。如果确认超时,则认为指令发送失败。
- 可以在上述的接口中发现 cmd 并不定义为cmd,而是用了port的称呼。port的取值范围为0~65535,可以用来表示不同的指令。
-
-4. 多device通讯方法:
- 每个port工作是单线程的,这就意味着,如果有多个device需要同时发送指令,则需要多线程或多进程。也就意味着需要定义不同的port号,来区分不同的线程,哪怕他是相同的指令。
- 例如:节点0x03中挂在了3个电机,需要这3个电机同时运动,此时理论上指令是相同的,但是device不同的。通讯库没有做device id的区分。为此需要将port号划分为cmd + device id的形式。cmd相同的指令,device id不同,这样就可以实现多device通讯。
- u16(port) = u8(cmd) + u8(device_id);
- 这样一个cmd号需要链接到多个port上。此时的cmd可叫做cmd组
- 
\ No newline at end of file
diff --git a/list.c b/list.c
index 392318c..2638010 100644
--- a/list.c
+++ b/list.c
@@ -1,90 +1,86 @@
#include "list.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "config.h"
-list_t *list_create(void *data)
-{
- list_t *node = (list_t *)malloc(sizeof(list_t));
- if (node == NULL)
- {
- return NULL;
- }
- node->data = data;
- node->next = NULL;
- return node;
-}
+#include
+#include
-list_t *list_append(list_t *head, void *data)
+int list_node_add(list_t *list, void *data)
{
- list_t *node = list_create(data);
- if (node == NULL)
+ list_node_t *new_node = (list_node_t *)malloc(sizeof(list_node_t));
+ if (new_node == NULL)
{
- return NULL;
+ return LIST_ERR_MALLOC_FAILED;
}
- if (head == NULL)
+ new_node->data = data;
+ new_node->next = NULL;
+ if (*list == NULL)
{
- return NULL;
+ *list = new_node;
}
else
{
- list_t *tail = head;
- while (tail->next != NULL)
+ list_node_t *node = *list;
+ while (node->next != NULL)
{
- tail = tail->next;
+ node = node->next;
}
- tail->next = node;
+ node->next = new_node;
}
- return head;
-}
-void list_print(list_t *head)
-{
- list_t *node = head;
- while (node != NULL)
- {
- ERPC_DEBUG("%p\n", node->data);
- node = node->next;
- }
+ return LIST_OK;
}
-
-/**
- * Destroy a list and all its nodes.
- * @param head The head of the list.
- */
-void list_destroy(list_t *head)
+int list_node_remove(list_t *list, void *data)
{
- list_t *node = head;
- while (node != NULL)
+ if (*list == NULL)
{
- list_t *next = node->next;
- free(node);
- node = next;
+ return LIST_ERR_LIST_IS_NULL;
}
-}
-/**
- * Delete a node from the list.
- * @param head The head of the list.
- */
-void list_delete(list_t *head, void *data)
-{
- list_t *node = head;
- list_t *prev = NULL;
+ list_node_t *node = *list;
+ list_node_t *prev = NULL;
while (node != NULL)
{
if (node->data == data)
{
if (prev == NULL)
{
- head = node->next;
+ if (node->next != NULL)
+ {
+ *list = node->next;
+ }
+ else
+ {
+ *list = NULL;
+ }
}
else
{
- prev->next = node->next;
+ if (node->next != NULL)
+ {
+ prev->next = node->next;
+ }
+ else
+ {
+ prev->next = NULL;
+ }
}
free(node);
- return;
+ return LIST_OK;
}
prev = node;
node = node->next;
}
+ return 0;
+}
+int list_size(list_t *list)
+{
+ if (*list == NULL)
+ {
+ return -1;
+ }
+ int size = 0;
+ list_node_t *node = *list;
+ while (node != NULL)
+ {
+ size++;
+ node = node->next;
+ }
+ return size;
}
diff --git a/list.h b/list.h
index 786051e..d5877fb 100644
--- a/list.h
+++ b/list.h
@@ -1,17 +1,47 @@
-#ifndef _LIST_H_
-#define _LIST_H_
+#ifndef LIST_H
+#define LIST_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+ typedef struct list_node_t
+ {
+ void *data;
+ struct list_node_t *next;
+ } list_node_t;
+ typedef list_node_t *list_t;
+ typedef enum list_error
+ {
+ LIST_OK = 0,
+ LIST_ERR_LIST_IS_NULL = 1,
+ LIST_ERR_MALLOC_FAILED,
+ } list_error;
+ /**
+ * @brief 创建一个节点,如果list为NULL,则创建一个空链表,否则创建一个节点并添加到链表尾部
+ * @param list 链表指针
+ * @param data 数据指针
+ */
+ int list_node_add(list_t *list, void *data);
+ /**
+ * @brief 从链表中删除节点
+ * @param list 链表指针
+ * @param data 数据指针
+ */
+ int list_node_remove(list_t *list, void *data);
+ int list_size(list_t *list);
-typedef struct list_t {
- void *data;
- struct list_t *next;
-} list_t;
-
-list_t *list_create(void *data);
-list_t *list_append(list_t *head, void *data);
-void list_print(list_t *head);
-void list_destroy(list_t *head);
-void list_delete(list_t *head, void *data);
-
-
-#endif /* _LIST_H_ */
\ No newline at end of file
+/**
+ * @param list 链表
+ * @param data 要添加的数据不要取地址,在宏定义里面自动取地址
+ * @warning 这种方式增加节点,会导致无法确定节点添加的先后顺序,更换编译环境后可能会影响编译效率
+ */
+#define EXPORT_LIST_NODE(list, data) \
+ int __attribute__((constructor)) export_list_node_##list_##data(void) \
+ { \
+ return list_node_add(&list, (void *)&data); \
+ }
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // LIST_H
diff --git a/makefile b/makefile
index 158c108..90c8dfa 100644
--- a/makefile
+++ b/makefile
@@ -7,7 +7,7 @@ CFLAGS = -Wall -Wextra -std=c11 -g
BUILD_DIR = build
# 源文件
SRCS = erpc_core.c \
- port_self.c \
+ erpc_port_self.c \
crc16.c\
list.c
diff --git a/picture/1.jpg b/picture/1.jpg
deleted file mode 100644
index 1ec3a8848474f2e1f5e3a8602cbd36f26266d3a9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 9871
zcmeHM2UJtby51B~5KurYNYT&~6r>x9joxbl1P}#63Dtxmh@i(tl@cS;1VRf5geD?Q
zPGl|M9!VF7Ku_
z%569Q3!>Ov?b@{t03GN5Lgt?p)7!vN))aw7%FTzQR8DE^5ehzH_Z^?v#a7?3{4Vx#
zcXOx6=7kY<^)iH
z0iX(8+wDK)nL@5u0JyjU05svh%B-RRpzsj@9Pj&8#+L{HhaLjJ>(*aozkK3$6M6G@
zbF`F{+SV2TmeT=%$rJ$CJ^%oN+3!3`@)vD8MPYGL+T}{Q>;NYK4x9qi0T;j;5TPJ(
z-~u29NbmFmiU1AuF72i?6r!c0-K7I`bo=P&4=^y$AE2jaU_8XgaFF>RJv|c(6Z4_N
zhgl9YFtW0-9%iH9!@EYPb~R~e4^R{jAEZA>Dg75|rvhL(Kn0;HqM-r-)GSmqEL1yH
z05@f5`mi7URG?YfM(69iPfv>H$+R@U^*|YsY!Ucl~Vp%Gw`ni*aC^XtL?xFo>u~D_F
z?rOOpS=OQj6vmtg*`>3-hObQ~JAz71>ddRu4|H7^HeOw;Ok~&NH~+;@Ju>%PR&tbB
z(@_$M2QasEdaaXngl3)Pia37>Y2c_K)pGEsp%)3cuja@02ni+98~?Hpu}27h??2W2
z$7%n=k=A?@|3K)YgRafI<8fEQ=ADrb3>iYbaxpb0r?-dJ-Kp`rvxWBVhN7hL!kxap
z+KYJ&xDKb{sxsDdD=w?C>8jCTtkL|JCZuUO%o|}YL=5!}r+3#rLwyWf=`w~7339UxyZv{|B^#4H?@(ud*
zpmCE~O@vRM5y7v()|@d(>s@LW7Q%16&|#Av%^rc()Vw^aTM$HgR5vaXgv064Lw|Mn
zKIBKl+06x_d3c9A4{rC=UL3D3oM*tiQzdkbR%Z>|%DBLvsHT$s4h5SOH`EDOE5=qU
zK?_(;mtZ`U&f4HVP3VTnmY2Tebpe*b5dMm{34Io-tEWG4cWyskGJaJYHmhtzCG>xv
zRj_>BaQkfg(o3yc=~T9<62APh9n8ScSLLUUF%$mJ$BeY~
zH8OQgQw~R0m-*5AZg|=xMBE#a%*XY8)XE@==ixvzgFY&MQck3jg1d1QUPNn7NllWq*SUG{#<
zOdDakp*K^W9)9bEQ<$&g<;v~pLT)!&bnS~psrJpQR=4@L2kpPH|El>+(AfE&W7_>b
zZF6Voi&MxPF#c+T=i!Ti8TL!3%EG(&w7c=eY;m2+L(oZlU_)Tv^XY>2BPKIQgY`2K
zZeyVG%G2|C2!V+PRNcbYOiBrF2iY(HnW{o>VUu}+2+0a|SxqDnB=^7Og2nS1
zJm9u{Ie`dux~+wL%SxPirHXaLZmV9}Z8+_o>A-FPx%D}{Hr{f`lBICBUo=AFct*ng
zR0VWV=FPX+a|=(d2&EAAM7ZDk&br5G6gJb==!8oS-wvShLE}5$DJ*pQn2yp?Bzu{t
z0yS5lS<Jr@?x_|;Dw3Y_62utst6b{bS0ii>eh-0&G_;4)-$@AHV19v?Vu?RhVHVn
zS< |