210 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			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, ¶m);
 | 
						|
    }
 | 
						|
 | 
						|
    /* 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);
 | 
						|
}
 |