Files
kunlun/plc/halmac/task/mac_msg.c
2024-09-28 14:24:04 +08:00

210 lines
5.8 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_task.h"
/* common includes */
#include "iot_mem_pool.h"
#include "iot_module.h"
#include "iot_task_api.h"
/* mac module internal includes */
#include "mac.h"
#include "mac_msg.h"
#include "mac_task.h"
/* define MAC layer message pool size */
#define MAC_MSG_POOL_SIZE 128
/* define MAC layer message pool size */
#define MAC_MSG_SYNC_POOL_SIZE 4
typedef struct _mac_msg_check_param {
iot_msg_entry_t *head;
uint16_t type;
uint16_t id;
} mac_msg_check_param_t;
uint32_t mac_init_msg_pool()
{
uint8_t i, j;
uint32_t ret;
mac_msg_sync_t *msg[MAC_MSG_SYNC_POOL_SIZE];
/* allocate messages pool */
ret = iot_mem_pool_new(PLC_MAC_COMMON_MID, MAC_MSG_POOL_SIZE,
sizeof(mac_msg_t), &p_mac_glb->msg_p, 1);
if (ret)
goto out;
/* allocate sync messages pool */
ret = iot_mem_pool_new(PLC_MAC_COMMON_MID, MAC_MSG_SYNC_POOL_SIZE,
sizeof(mac_msg_sync_t), &p_mac_glb->msg_sync_p, 1);
if (ret)
goto err_sync;
/* init sync messages event */
for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
msg[i] = iot_mem_pool_alloc(p_mac_glb->msg_sync_p);
msg[i]->event = os_create_event(PLC_MAC_COMMON_MID, false);
if (msg[i]->event == NULL) {
for (j = 0; j < i; j++) {
os_delete_event(msg[j]->event);
msg[j]->event = NULL;
}
goto err_event;
}
}
for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
iot_mem_pool_free(p_mac_glb->msg_sync_p, msg[i]);
}
goto out;
err_event:
iot_mem_pool_destroy(p_mac_glb->msg_sync_p);
p_mac_glb->msg_sync_p = NULL;
err_sync:
iot_mem_pool_destroy(p_mac_glb->msg_p);
p_mac_glb->msg_p = NULL;
out:
return ret;
}
void mac_deinit_msg_pool()
{
uint8_t i;
mac_msg_sync_t *msg[MAC_MSG_SYNC_POOL_SIZE];
if (p_mac_glb->msg_p) {
iot_mem_pool_destroy(p_mac_glb->msg_p);
p_mac_glb->msg_p = NULL;
}
if (p_mac_glb->msg_sync_p) {
for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
msg[i] = iot_mem_pool_alloc(p_mac_glb->msg_sync_p);
os_delete_event(msg[i]->event);
msg[i]->event = NULL;
}
for (i = 0; i < MAC_MSG_SYNC_POOL_SIZE; i++) {
iot_mem_pool_free(p_mac_glb->msg_sync_p, msg[i]);
}
iot_mem_pool_destroy(p_mac_glb->msg_sync_p);
p_mac_glb->msg_sync_p = NULL;
}
}
mac_msg_t *mac_alloc_msg()
{
mac_msg_t *msg = iot_mem_pool_alloc(p_mac_glb->msg_p);
if (msg) {
iot_msg_entry_init(&msg->link);
msg->sync = 0;
}
return msg;
}
void mac_free_msg(mac_msg_t *msg)
{
iot_mem_pool_free(p_mac_glb->msg_p, msg);
}
/*
* @brief : check msg is matched with param type, if msg is matched, it
* will be pushed in param queue
* @param msg : message entry to be checked
* @param param : assigned message type and message id to match
* @return : if check msg is macthed return true, else return false
*/
static uint32_t mac_msg_check(iot_msg_entry_t *msg, void* param)
{
mac_msg_t *mac_msg;
mac_msg_check_param_t *check;
check = (mac_msg_check_param_t *)param;
IOT_ASSERT(check);
mac_msg = container_of(msg, mac_msg_t, link);
if (mac_msg->type == check->type
&& (check->id == MAC_MSG_ID_ALL || mac_msg->id == check->id)) {
msg->next = check->head;
check->head = msg;
return 1;
}
return 0;
}
void mac_clean_msg(uint8_t msg_type, uint16_t msg_id)
{
uint8_t i;
iot_msg_queue_t *pq;
iot_msg_entry_t *msg, *next_msg;
mac_msg_t *mac_msg;
mac_msg_check_param_t param;
param.head = NULL;
param.type = msg_type;
param.id = msg_id;
/* move out assigned message from the message queue */
for (i = 0; i < MAC_MSG_QUEUE_MAX_PRIO; i++) {
pq = &p_mac_glb->msg_q[i].q;
iot_msg_queue_loop(pq, mac_msg_check, &param);
}
/* clean the assigned message queue */
for (msg = param.head; msg != NULL; msg = next_msg) {
next_msg = msg->next;
mac_msg = container_of(msg, mac_msg_t, link);
mac_handle_msg_cancel(p_mac_glb, mac_msg);
}
}
void mac_queue_msg(mac_msg_t *msg, uint8_t prio)
{
IOT_ASSERT(prio < MAC_MSG_QUEUE_MAX_PRIO);
iot_msg_queue_put(&p_mac_glb->msg_q[prio].q, &msg->link);
os_set_task_event(p_mac_glb->task_h);
}
mac_msg_sync_t *mac_alloc_msg_sync()
{
mac_msg_sync_t *msg = iot_mem_pool_alloc(p_mac_glb->msg_sync_p);
if (msg) {
iot_msg_entry_init(&msg->msg.link);
msg->msg.sync = 1;
}
return msg;
}
void mac_free_msg_sync(mac_msg_sync_t *msg)
{
iot_mem_pool_free(p_mac_glb->msg_sync_p, msg);
}
void mac_queue_msg_sync(mac_msg_sync_t *msg, uint8_t prio)
{
IOT_ASSERT(prio < MAC_MSG_QUEUE_MAX_PRIO);
iot_msg_queue_put(&p_mac_glb->msg_q[prio].q, &msg->msg.link);
os_set_task_event(p_mac_glb->task_h);
os_wait_event(msg->event, MAX_TIME);
}