diff --git a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c index 93117c6fb..71cbebebf 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c +++ b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c @@ -114,7 +114,7 @@ x_err_t PmpClearRegion(void *task_pmp, x_ubase addr) if (!IsDoubleLinkListEmpty(&pmp->tor_list)) { DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list) { tor_node = CONTAINER_OF(link, struct PmpRegionTor, link); - if ( addr = tor_node->start ){ + if ( addr == tor_node->start ){ pmp->count = pmp->count -2; goto __free ; } @@ -123,7 +123,7 @@ x_err_t PmpClearRegion(void *task_pmp, x_ubase addr) if (!IsDoubleLinkListEmpty(&pmp->tor_swap_list)) { DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_swap_list) { tor_node = CONTAINER_OF(link, struct PmpRegionTor, link); - if ( addr = tor_node->start ) { + if ( addr == tor_node->start ) { goto __free; } } @@ -308,7 +308,7 @@ x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr) pmp = (struct Pmp *)task_pmp ; x_bool ret = RET_FALSE; - uint8_t region_type; + uint8_t region_type = 0; DoubleLinklistType *link = NONE; struct PmpRegionTor *tor_node = NONE; @@ -327,7 +327,7 @@ x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr) __swap: - if ( region_type = PMP_TOR ) { + if ( region_type == PMP_TOR ) { if( pmp->count < PMP_MAX_ENTRY_NUMBER - 2) { DoubleLinkListRmNode(&(tor_node->link)); DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link); @@ -340,9 +340,7 @@ __swap: DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link); DoubleLinkListInsertNodeBefore(&pmp->tor_swap_list, &swap_node->link); swap_node->swap_count ++; - } - } ret = RET_TRUE; diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h index 17ffea9bc..14c974da0 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h @@ -78,6 +78,7 @@ struct MemGather typedef struct MemGather *GatherMemType; x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *begin_address, x_size_t gm_size, x_size_t one_block_size); +/* Caller must FreeBlockMemGather all blocks before RemoveMemGather/DeleteMemGather. */ x_err_t RemoveMemGather(struct MemGather *gm_handler); GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size_t one_block_size); x_err_t DeleteMemGather(GatherMemType gm_handler); diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h index e7cae4f42..d3e6a93e6 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h @@ -41,10 +41,10 @@ struct Semaphore typedef struct { int32 (*SemaphoreCreate)(uint16 val); - void (*SemaphoreDelete)(struct Semaphore *sem); - int32 (*SemaphoreObtain)(struct Semaphore *sem, int32 wait_time); - int32 (*SemaphoreAbandon)(struct Semaphore *sem); - int32 (*SemaphoreSetValue)(struct Semaphore *sem, uint16 val); + void (*SemaphoreDelete)(int32 id); + int32 (*SemaphoreObtain)(int32 id, int32 wait_time); + int32 (*SemaphoreAbandon)(int32 id); + int32 (*SemaphoreSetValue)(int32 id, uint16 val); } SemaphoreDoneType; int32 KSemaphoreCreate(uint16 val); diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c index 6ac255725..95b439700 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c @@ -53,6 +53,11 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void * CHECK(gm_size >= 1 && one_block_size >= 1); + if (ALIGN_MEN_DOWN(gm_size, MEM_ALIGN_SIZE) < + ALIGN_MEN_UP(one_block_size, MEM_ALIGN_SIZE) + sizeof(uint8 *)) { + return ERROR; + } + lock = CriticalAreaLock(); /* try to find gatherblock object */ @@ -97,8 +102,10 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void * (uint8 *)(block_ptr + (off_block + 1) * (one_block_size + sizeof(uint8 *))); } - *(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) = - NONE; + if (gm_handler->block_total_number > 0) { + *(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) = + NONE; + } gm_handler->m_block_link = block_ptr; @@ -108,11 +115,12 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void * /** - * This function will remove the gatherblock from the global list, which is created by MemGatherInit function + * This function will remove the gatherblock from the global list, which is created by MemGatherInit function. + * All blocks must be returned via FreeBlockMemGather before calling this function. * * @param gm_handler the gatherblock to be removed * - * @return EOK + * @return EOK on success; ERROR if blocks are still allocated */ x_err_t RemoveMemGather(struct MemGather *gm_handler) { @@ -124,6 +132,10 @@ x_err_t RemoveMemGather(struct MemGather *gm_handler) CHECK((gm_handler->m_kind & Cmpt_KindN_Static)!=0); + if (gm_handler->block_free_number != gm_handler->block_total_number) { + return ERROR; + } + /* resume all the suspend tasks on gatherblock object */ while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) { critical_value = CriticalAreaLock(); @@ -238,10 +250,11 @@ GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size /** * This function will delete a gatherblock object, which is created by MemGatherCreate function. + * All blocks must be returned via FreeBlockMemGather before calling this function. * * @param gm_handler the gatherblock object to be deleted * - * @return EOK + * @return EOK on success; ERROR if blocks are still allocated */ x_err_t DeleteMemGather(GatherMemType gm_handler) { @@ -254,6 +267,10 @@ x_err_t DeleteMemGather(GatherMemType gm_handler) NULL_PARAM_CHECK(gm_handler); CHECK(((gm_handler->m_kind & Cmpt_KindN_Static)==0)); + if (gm_handler->block_free_number != gm_handler->block_total_number) { + return ERROR; + } + /* resume all the suspend tasks on gatherblock object */ while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) { critical_value = CriticalAreaLock(); diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c index 6b291fa24..76d340e68 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c @@ -29,14 +29,23 @@ * This function will return the node height of the avl tree * * @param avl_node avl tree node descriptor - * @return 0 + * @return cached height, or 0 if node is NULL */ static uint32 AvlTreeGetNodeHeight(AvlNodeType avl_node) +{ + return avl_node ? avl_node->height : 0; +} + +/** + * This function will update the cached height of the avl tree node + * + * @param avl_node avl tree node descriptor + */ +static void AvlTreeUpdateNodeHeight(AvlNodeType avl_node) { if(avl_node) { - return AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1; - } else { - return 0; + avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), + AvlTreeGetNodeHeight(avl_node->right)) + 1; } } @@ -69,8 +78,8 @@ static AvlNodeType AvlTreeSetRightRotate(AvlNodeType avl_node) avl_node->left = new_node->right; new_node->right = avl_node; - new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1; - avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1; + AvlTreeUpdateNodeHeight(avl_node); + AvlTreeUpdateNodeHeight(new_node); return new_node; } @@ -90,8 +99,8 @@ static AvlNodeType AvlTreeSetLeftRotate(AvlNodeType avl_node) avl_node->right = new_node->left; new_node->left = avl_node; - new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1; - avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1; + AvlTreeUpdateNodeHeight(avl_node); + AvlTreeUpdateNodeHeight(new_node); return new_node; } @@ -221,74 +230,10 @@ AvlNodeType AvlTreeInsertNode(AvlNodeType avl_node, int32 data) } } + AvlTreeUpdateNodeHeight(avl_node); return AvlTreeBalance(avl_node); } -/** - * This function will find the pre node of the avl_node - * - * @param avl_node avl tree node descriptor - * @return avl tree node - */ -static AvlNodeType AvlTreeFindPreNode(AvlNodeType avl_node) -{ - NULL_PARAM_CHECK(avl_node); - - AvlNodeType pre_node = NONE; - - if(avl_node->left) { - if(avl_node->left->right) { - pre_node = avl_node->left->right; - while(pre_node->right) { - pre_node = pre_node->right; - } - } else { - pre_node = avl_node->left; - } - } else { - pre_node = avl_node; - } - - return pre_node; -} - -/** - * This function will delete a certain node, ultimate target is to find the leaf node - * - * @param avl_node avl tree node descriptor - * @param data delete data - * @return avl tree node - */ -static AvlNodeType AvlTreeDeleteLeafNode(AvlNodeType avl_node) -{ - AvlNodeType pre_node = NONE; - - if((NONE == avl_node->left) && (NONE == avl_node->right)) { - /*Leaf Node*/ - avl_node = NONE; - x_free(avl_node); - } else if(NONE == avl_node->left) { - /*Right child is Leaf Node*/ - avl_node->data = avl_node->right->data; - avl_node->right = NONE; - x_free(avl_node->right); - } else if(NONE == avl_node->right) { - /*Left child is Leaf Node*/ - avl_node->data = avl_node->left->data; - avl_node->left = NONE; - x_free(avl_node->left); - } else { - /*Find the pre node to replace the avl node, then delete the pre node*/ - pre_node = AvlTreeFindPreNode(avl_node); - if(pre_node) { - avl_node->data = pre_node->data; - avl_node->left = AvlTreeDeleteNode(avl_node->left, pre_node->data); - } - } - - return avl_node; -} - /** * This function will delete data from the avl tree * @@ -297,17 +242,39 @@ static AvlNodeType AvlTreeDeleteLeafNode(AvlNodeType avl_node) */ AvlNodeType AvlTreeDeleteNode(AvlNodeType avl_node, int32 data) { + AvlNodeType temp = NONE; + AvlNodeType pred = NONE; + if(avl_node) { - if(data == avl_node->data) { - avl_node = AvlTreeDeleteLeafNode(avl_node); + if(avl_node->data < data) { + avl_node->right = AvlTreeDeleteNode(avl_node->right, data); + } else if(avl_node->data > data) { + avl_node->left = AvlTreeDeleteNode(avl_node->left, data); } else { - if(avl_node->data < data) { - avl_node->right = AvlTreeDeleteNode(avl_node->right, data); + if((NONE == avl_node->left) && (NONE == avl_node->right)) { + x_free(avl_node); + return NONE; + } else if(NONE == avl_node->left) { + temp = avl_node->right; + x_free(avl_node); + AvlTreeUpdateNodeHeight(temp); + return AvlTreeBalance(temp); + } else if(NONE == avl_node->right) { + temp = avl_node->left; + x_free(avl_node); + AvlTreeUpdateNodeHeight(temp); + return AvlTreeBalance(temp); } else { - avl_node->left = AvlTreeDeleteNode(avl_node->left, data); + pred = avl_node->left; + while(pred->right) { + pred = pred->right; + } + avl_node->data = pred->data; + avl_node->left = AvlTreeDeleteNode(avl_node->left, pred->data); } } + AvlTreeUpdateNodeHeight(avl_node); return AvlTreeBalance(avl_node); } else { KPrintf("AvlTreeDeleteNode cannot find the delete data\n"); diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c index 3f581619e..e4f9a63dd 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c @@ -183,8 +183,8 @@ static x_err_t _MsgQueueUrgentSend(struct MsgQueue *mq, const void *buffer, x_si msg = mq->msg_buf + (mq->index % mq->max_msgs) * mq->each_len; memcpy(msg , buffer, size); mq->num_msgs ++; - if (!IsDoubleLinkListEmpty(&mq->send_pend_list)) { - LinklistResume(&(mq->send_pend_list)); + if (!IsDoubleLinkListEmpty(&mq->recv_pend_list)) { + LinklistResume(&(mq->recv_pend_list)); CriticalAreaUnLock(lock); DO_KTASK_ASSIGN; return EOK; diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c index 54ff78629..8a461aa88 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c @@ -61,15 +61,25 @@ static int32 _SemaphoreCreate(uint16 val) return id; } -static void _SemaphoreDelete(struct Semaphore *sem) +static void _SemaphoreDelete(int32 id) { int resched = 0; x_base lock = 0; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return; + + lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("deleted semaphore: id %d\n", (int)sem->id.id)); - lock = CriticalAreaLock(); if (!IsDoubleLinkListEmpty(&sem->pend_list)) { resched = 1; LinklistResumeAll(&sem->pend_list); @@ -84,21 +94,29 @@ static void _SemaphoreDelete(struct Semaphore *sem) if (resched){ DO_KTASK_ASSIGN; } - } -static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec) +static int32 _SemaphoreObtain(int32 id, int32 msec) { int lock = 0; int32 wait_time = 0; struct TaskDescriptor *task = NONE; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return -ERROR; if(WAITING_FOREVER == msec) wait_time = WAITING_FOREVER; else wait_time = CalculateTickFromTimeMs(msec); lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return -ERROR; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("obtain semaphore: id %d, value %d, by task %s\n", (int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name)); @@ -134,14 +152,23 @@ static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec) return task->exstatus; } -static int32 _SemaphoreAbandon(struct Semaphore *sem) +static int32 _SemaphoreAbandon(int32 id) { int lock = 0; int resched = 0; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return -ERROR; lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return -ERROR; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("abandon semaphore: id %d, value %d, by task %s\n", (int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name)); @@ -162,14 +189,23 @@ static int32 _SemaphoreAbandon(struct Semaphore *sem) return EOK; } -static int32 _SemaphoreSetValue(struct Semaphore *sem, uint16 val) +static int32 _SemaphoreSetValue(int32 id, uint16 val) { int lock = 0; int resched = 0; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return -ERROR; lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return -ERROR; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("set semaphore value: id %d, old value %d, new value %d, by task %s\n", (int)sem->id.id, (int)sem->value, (int)val, GetKTaskDescriptor()->task_base_info.name)); @@ -221,24 +257,9 @@ int32 KSemaphoreCreate(uint16 val) */ void KSemaphoreDelete(int32 id) { - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - KDEBUG_NOT_IN_INTERRUPT; - if (id < 0) - return; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE){ - CriticalAreaUnLock(lock); - return; - } - CriticalAreaUnLock(lock); - - sem = CONTAINER_OF(idnode, struct Semaphore, id); - done.SemaphoreDelete(sem); + done.SemaphoreDelete(id); } /** @@ -252,22 +273,7 @@ int32 KSemaphoreObtain(int32 id, int32 msec) { KDEBUG_NOT_IN_INTERRUPT; - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - - if (id < 0) - return -ERROR; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE){ - CriticalAreaUnLock(lock); - return -ERROR; - } - - sem =CONTAINER_OF(idnode, struct Semaphore, id); - CriticalAreaUnLock(lock); - return done.SemaphoreObtain(sem, msec); + return done.SemaphoreObtain(id, msec); } /** @@ -280,23 +286,7 @@ int32 KSemaphoreAbandon(int32 id) { KDEBUG_NOT_IN_INTERRUPT; - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - - if (id < 0) - return -ERROR; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE) { - CriticalAreaUnLock(lock); - return -ERROR; - } - - sem =CONTAINER_OF(idnode, struct Semaphore, id); - CriticalAreaUnLock(lock); - - return done.SemaphoreAbandon(sem); + return done.SemaphoreAbandon(id); } /** @@ -310,20 +300,5 @@ int32 KSemaphoreSetValue(int32 id, uint16 val) { KDEBUG_NOT_IN_INTERRUPT; - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - - if (id < 0) - return -ERROR; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE) { - CriticalAreaUnLock(lock); - return -ERROR; - } - - sem = CONTAINER_OF(idnode, struct Semaphore, id); - CriticalAreaUnLock(lock); - return done.SemaphoreSetValue(sem, val); + return done.SemaphoreSetValue(id, val); }