_mqx_uint _taskq_resume ( /* [IN] the task queue handle */ pointer users_task_queue_ptr, /* [IN] TRUE if all tasks on the queue to be resumed */ boolean all_tasks ) { /* Body */ register KERNEL_DATA_STRUCT_PTR kernel_data; register TD_STRUCT_PTR td_ptr; register TASK_QUEUE_STRUCT_PTR task_queue_ptr = (TASK_QUEUE_STRUCT_PTR)users_task_queue_ptr; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_taskq_resume, users_task_queue_ptr, all_tasks); #if MQX_CHECK_ERRORS if (task_queue_ptr == NULL){ _KLOGX2(KLOG_taskq_resume, MQX_INVALID_TASK_QUEUE); return(MQX_INVALID_TASK_QUEUE); } /* Endif */ #endif _INT_DISABLE(); #if MQX_CHECK_VALIDITY if (task_queue_ptr->VALID != TASK_QUEUE_VALID) { _int_enable(); _KLOGX2(KLOG_taskq_resume, MQX_INVALID_TASK_QUEUE); return(MQX_INVALID_TASK_QUEUE); } /* Endif */ #endif if (_QUEUE_GET_SIZE(&task_queue_ptr->TD_QUEUE) == 0) { /* Task queue is empty */ _int_enable(); _KLOGX2(KLOG_taskq_resume, MQX_TASK_QUEUE_EMPTY); return(MQX_TASK_QUEUE_EMPTY); } /* Endif */ if (all_tasks) { while (_QUEUE_GET_SIZE(&task_queue_ptr->TD_QUEUE)) { _QUEUE_DEQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr); _TASK_READY(td_ptr, kernel_data); } /* Endwhile */ } else { _QUEUE_DEQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr); _TASK_READY(td_ptr, kernel_data); } /* Endif */ _INT_ENABLE(); _CHECK_RUN_SCHEDULER();/* Let higher priority task run */ _KLOGX2(KLOG_taskq_resume, MQX_OK); return( MQX_OK ); } /* Endbody */
QUEUE_ELEMENT_STRUCT_PTR _queue_dequeue ( /* [IN] the queue to use */ QUEUE_STRUCT_PTR q_ptr ) { /* Body */ QUEUE_ELEMENT_STRUCT_PTR e_ptr; _int_disable(); if (q_ptr->SIZE == 0) { _int_enable(); return(NULL); } /* Endif */ _QUEUE_DEQUEUE(q_ptr, e_ptr); _int_enable(); return(e_ptr); } /* Endbody */
_mqx_uint _mmu_destroy_vcontext ( /* [IN] the task for which a virtual context is to be removed */ _task_id task_id ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; PSP_VIRTUAL_CONTEXT_STRUCT_PTR context_ptr; PSP_PAGE_INFO_STRUCT_PTR mem_ptr; PSP_SUPPORT_STRUCT_PTR psp_support_ptr; _GET_KERNEL_DATA(kernel_data); psp_support_ptr = kernel_data->PSP_SUPPORT_PTR; td_ptr = _task_get_td(task_id); if (td_ptr == NULL) { return(MQX_INVALID_TASK_ID); }/* Endif */ _int_disable(); if ((td_ptr->FLAGS & TASK_MMU_CONTEXT_EXISTS) == 0) { _int_enable(); return(MQX_MMU_CONTEXT_DOES_NOT_EXIST); } /* Endif */ if (td_ptr == kernel_data->ACTIVE_PTR) { /* Remove task MMU pages from the MMU table */ _mmu_reset_vcontext_internal(); }/* Endif */ td_ptr->FLAGS &= ~TASK_MMU_CONTEXT_EXISTS; context_ptr = td_ptr->MMU_VIRTUAL_CONTEXT_PTR; td_ptr->MMU_VIRTUAL_CONTEXT_PTR = NULL; _lwsem_wait(&psp_support_ptr->VPAGE_FREELIST_LWSEM); _int_enable(); while (_QUEUE_GET_SIZE(&context_ptr->PAGE_INFO)) { _QUEUE_DEQUEUE(&context_ptr->PAGE_INFO, mem_ptr); _QUEUE_ENQUEUE(&psp_support_ptr->VPAGE_FREELIST, &mem_ptr->ELEMENT); } /* Endwhile */ _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM); _mem_free(context_ptr); return(MQX_OK); } /* Endbody */
/*! * \private * * \brief Used by a task to destroy an instance of a lightweight event. * * \param[in] event_ptr Pointer to the lightweight event to be deinitialized. * \param[in] user User mode * * \return MQX_OK * \return MQX_LWEVENT_INVALID (Lightweight event was not valid.) * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.) * * \see _lwevent_destroy * \see LWEVENT_STRUCT */ _mqx_uint _lwevent_destroy_internal ( LWEVENT_STRUCT_PTR event_ptr, bool user ) { KERNEL_DATA_STRUCT_PTR kernel_data; #if MQX_COMPONENT_DESTRUCTION TD_STRUCT_PTR td_ptr; #endif #if MQX_ENABLE_USER_MODE if (user && !_psp_mem_check_access_mask((uint32_t)event_ptr, sizeof(LWEVENT_STRUCT), MPU_UM_R, MPU_UM_RW)) { return MQX_LWEVENT_INVALID; } #endif _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_lwevent_destroy, event_ptr); #if MQX_COMPONENT_DESTRUCTION #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _KLOGX2(KLOG_lwevent_destroy, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR); } /* Endif */ #endif _int_disable(); #if MQX_CHECK_VALIDITY if (event_ptr->VALID != LWEVENT_VALID) { _int_enable(); _KLOGX2(KLOG_lwevent_destroy, MQX_LWEVENT_INVALID); return (MQX_LWEVENT_INVALID); } /* Endif */ #endif /* Effectively stop all access to the event */ event_ptr->VALID = 0; while (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS)) { _QUEUE_DEQUEUE(&event_ptr->WAITING_TASKS, td_ptr); _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE); _TIME_DEQUEUE(td_ptr, kernel_data); _TASK_READY(td_ptr, kernel_data); } /* Endwhile */ /* remove event from kernel LWEVENTS queue */ #if MQX_ENABLE_USER_MODE if (user) { _QUEUE_REMOVE(&kernel_data->USR_LWEVENTS, event_ptr); } else #endif { _QUEUE_REMOVE(&kernel_data->LWEVENTS, event_ptr); } _int_enable(); /* May need to let higher priority task run */ _CHECK_RUN_SCHEDULER(); #endif _KLOGX2(KLOG_lwevent_destroy, MQX_OK); return (MQX_OK); }
_mqx_uint _lwmsgq_receive ( /* Handle to the queue */ pointer handle, /* location of message to copy to */ _mqx_max_type_ptr message, /* flags for blocking on empty */ _mqx_uint flags, /* Timeout for receive if using ticks if 0, ignored */ _mqx_uint ticks, /* Timeout if receive timout using tick struct must have flags set */ MQX_TICK_STRUCT_PTR tick_ptr ) {/* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; LWMSGQ_STRUCT_PTR q_ptr = (LWMSGQ_STRUCT_PTR)handle; _mqx_uint i; _mqx_max_type_ptr from_ptr; _mqx_max_type_ptr to_ptr; #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwmsgq_receive(handle, message, flags, ticks, tick_ptr); } #endif /* Start CR 1944 */ _GET_KERNEL_DATA(kernel_data); _KLOGE6(KLOG_lwmsgq_receive, handle, message, flags, ticks, tick_ptr); /* End CR 1944 */ _int_disable(); #if MQX_CHECK_VALIDITY if (q_ptr->VALID != LWMSGQ_VALID){ _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_INVALID); /* End CR 1944 */ return LWMSGQ_INVALID; } /* Endif */ #endif if (LWMSGQ_IS_EMPTY(q_ptr)) { if (flags & LWMSGQ_RECEIVE_BLOCK_ON_EMPTY) { td_ptr = kernel_data->ACTIVE_PTR; while (LWMSGQ_IS_EMPTY(q_ptr)) { td_ptr->STATE = LWMSGQ_READ_BLOCKED; td_ptr->INFO = (_mqx_uint)&q_ptr->WAITING_READERS; _QUEUE_UNLINK(td_ptr); _QUEUE_ENQUEUE(&q_ptr->WAITING_READERS, &td_ptr->AUX_QUEUE); if (ticks || (flags & (LWMSGQ_TIMEOUT_UNTIL | LWMSGQ_TIMEOUT_FOR))){ if (ticks) { PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->TIME, ticks, &td_ptr->TIMEOUT); } else if (flags & LWMSGQ_TIMEOUT_UNTIL){ td_ptr->TIMEOUT = *tick_ptr; } else { PSP_ADD_TICKS(tick_ptr, &kernel_data->TIME, &td_ptr->TIMEOUT); } /* Endif */ _time_delay_internal(td_ptr); if (td_ptr->INFO != 0) { _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_TIMEOUT); /* End CR 1944 */ return LWMSGQ_TIMEOUT; } /* Endif */ } else { _sched_execute_scheduler_internal(); /* Let other tasks run */ } /* Endif */ } /* Endwhile */ } else { _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_EMPTY); /* End CR 1944 */ return LWMSGQ_EMPTY; } /* Endif */ }/* Endif */ from_ptr = q_ptr->MSG_READ_LOC; to_ptr = message; i = q_ptr->MSG_SIZE+1; while (--i) { *to_ptr++ = *from_ptr++; } /* Endwhile */ q_ptr->MSG_READ_LOC += q_ptr->MSG_SIZE; if (q_ptr->MSG_READ_LOC >= q_ptr->MSG_END_LOC) { q_ptr->MSG_READ_LOC = q_ptr->MSG_START_LOC; } /* Endif */ q_ptr->CURRENT_SIZE--; if (! _QUEUE_IS_EMPTY(&q_ptr->WAITING_WRITERS)) { _QUEUE_DEQUEUE(&q_ptr->WAITING_WRITERS, td_ptr); _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE); td_ptr->INFO = 0; /* Signal that post is activating the task */ _TASK_READY(td_ptr, kernel_data); _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */ } /* Endif */ _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_receive, MQX_OK); /* End CR 1944 */ return MQX_OK; }/* Endbody */
_mqx_uint _mmu_add_vcontext ( /* [IN] the task to which a virtual context is to be added */ _task_id task_id, /* [IN] the virtual address to use */ pointer vaddr, /* [IN] the size */ _mem_size input_size, /* [IN] the MMU flags to use */ _mqx_uint flags ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; PSP_VIRTUAL_CONTEXT_STRUCT_PTR context_ptr; PSP_PAGE_INFO_STRUCT_PTR mem_ptr; PSP_SUPPORT_STRUCT_PTR psp_support_ptr; uint_32 page_size; int_32 test_size; int_32 size = (int_32)input_size; uint_32 result; uchar_ptr taddr; pointer tmp; _GET_KERNEL_DATA(kernel_data); td_ptr = _task_get_td(task_id); if (td_ptr == NULL) { return(MQX_INVALID_TASK_ID); }/* Endif */ context_ptr = td_ptr->MMU_VIRTUAL_CONTEXT_PTR; psp_support_ptr = kernel_data->PSP_SUPPORT_PTR; page_size = psp_support_ptr->PAGE_SIZE; _lwsem_wait(&psp_support_ptr->VPAGE_FREELIST_LWSEM); if ((td_ptr->FLAGS & TASK_MMU_CONTEXT_EXISTS) == 0) { _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM); return(MQX_MMU_CONTEXT_DOES_NOT_EXIST); } /* Endif */ if (size > (_QUEUE_GET_SIZE(&psp_support_ptr->VPAGE_FREELIST) * page_size)) { _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM); return(MQX_OUT_OF_MEMORY); }/* Endif */ /* Verify virtual memory not in use */ test_size = size; taddr = vaddr; while (test_size > 0) { /* Use Vtop !! */ if (_mmu_vtop(taddr,&tmp) == MQX_OK) { _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM); return(MQX_INVALID_PARAMETER); }/* Endif */ taddr += page_size; test_size -= page_size; } /* Endwhile */ while (size > 0) { _QUEUE_DEQUEUE(&psp_support_ptr->VPAGE_FREELIST,mem_ptr); mem_ptr->VADDR = vaddr; result = _mmu_set_vmem_loc_internal(mem_ptr, flags); if (result != MQX_OK) { _QUEUE_ENQUEUE(&psp_support_ptr->VPAGE_FREELIST,mem_ptr); _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM); return(MQX_OUT_OF_MEMORY); } /* Endif */ if (td_ptr == kernel_data->ACTIVE_PTR) { result = _mmu_add_vregion(mem_ptr->ADDR, mem_ptr->VADDR, page_size, flags); if (result != MQX_OK) { _QUEUE_ENQUEUE(&psp_support_ptr->VPAGE_FREELIST,mem_ptr); _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM); return(MQX_OUT_OF_MEMORY); } /* Endif */ } /* Endif */ _QUEUE_ENQUEUE(&context_ptr->PAGE_INFO,mem_ptr); size -= page_size; vaddr = (pointer)((uint_32)vaddr + page_size); } /* Endwhile */ _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM); return(MQX_OK); } /* Endbody */
_mqx_uint _lwevent_set ( /* [IN] - The address of the light weight event */ LWEVENT_STRUCT_PTR event_ptr, /* [IN] - bit mask, each bit of which represents an event. */ _mqx_uint bit_mask ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; QUEUE_ELEMENT_STRUCT_PTR q_ptr; QUEUE_ELEMENT_STRUCT_PTR next_q_ptr; TD_STRUCT_PTR td_ptr; _mqx_uint set_bits; #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwevent_set(event_ptr, bit_mask); } #endif _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_lwevent_set, event_ptr, bit_mask); _INT_DISABLE(); #if MQX_CHECK_VALIDITY if (event_ptr->VALID != LWEVENT_VALID) { _int_enable(); _KLOGX2(KLOG_lwevent_set, MQX_LWEVENT_INVALID); return(MQX_LWEVENT_INVALID); } /* Endif */ #endif set_bits = event_ptr->VALUE | bit_mask; if (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS)) { /* Schedule waiting task(s) to run if bits ok */ q_ptr = event_ptr->WAITING_TASKS.NEXT; while (q_ptr != (QUEUE_ELEMENT_STRUCT_PTR) ((pointer)&event_ptr->WAITING_TASKS)) { td_ptr = (pointer)q_ptr; _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE); next_q_ptr = q_ptr->NEXT; if (((td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED) && ((td_ptr->LWEVENT_BITS & set_bits) == td_ptr->LWEVENT_BITS)) || ((!(td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED)) && (td_ptr->LWEVENT_BITS & set_bits))) { /* Start CR 406 */ #if 0 _QUEUE_DEQUEUE(&event_ptr->WAITING_TASKS, q_ptr); #endif _QUEUE_REMOVE(&event_ptr->WAITING_TASKS, q_ptr); /* End CR 406 */ _TIME_DEQUEUE(td_ptr, kernel_data); td_ptr->INFO = 0; _TASK_READY(td_ptr, kernel_data); /* store information about which bits caused task to be unblocked */ td_ptr->LWEVENT_BITS &= set_bits; set_bits &= ~(event_ptr->AUTO & td_ptr->LWEVENT_BITS); } /* Endif */ q_ptr = next_q_ptr; } /* Endwhile */ } /* Endif */ event_ptr->VALUE = set_bits; _INT_ENABLE(); /* May need to let higher priority task run */ _CHECK_RUN_SCHEDULER(); _KLOGX2(KLOG_lwevent_set, MQX_OK); return(MQX_OK); }
_mqx_uint _lwmsgq_send ( /* Handle to the queue */ pointer handle, /* location of message to copy in */ _mqx_max_type_ptr message, /* flags for blocking on full, blocking on send */ _mqx_uint flags ) {/* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; LWMSGQ_STRUCT_PTR q_ptr = (LWMSGQ_STRUCT_PTR)handle; _mqx_uint i; _mqx_max_type_ptr from_ptr; _mqx_max_type_ptr to_ptr; #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwmsgq_send(handle, message, flags); } #endif /* Start CR 1944 */ _GET_KERNEL_DATA(kernel_data); _KLOGE4(KLOG_lwmsgq_send, handle, message, flags); /* End CR 1944 */ _int_disable(); #if MQX_CHECK_VALIDITY if (q_ptr->VALID != LWMSGQ_VALID){ _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_INVALID); /* End CR 1944 */ return LWMSGQ_INVALID; } /* Endif */ #endif if (LWMSGQ_IS_FULL(q_ptr)) { if (flags & LWMSGQ_SEND_BLOCK_ON_FULL) { td_ptr = kernel_data->ACTIVE_PTR; while (LWMSGQ_IS_FULL(q_ptr)) { td_ptr->STATE = LWMSGQ_WRITE_BLOCKED; td_ptr->INFO = (_mqx_uint)&q_ptr->WAITING_WRITERS; _QUEUE_UNLINK(td_ptr); _QUEUE_ENQUEUE(&q_ptr->WAITING_WRITERS, &td_ptr->AUX_QUEUE); _sched_execute_scheduler_internal(); /* Let other tasks run */ } /* Endwhile */ } else { _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_FULL); /* End CR 1944 */ return LWMSGQ_FULL; } /* Endif */ }/* Endif */ to_ptr = q_ptr->MSG_WRITE_LOC; from_ptr = message; i = q_ptr->MSG_SIZE+1; while (--i) { *to_ptr++ = *from_ptr++; } /* Endwhile */ q_ptr->MSG_WRITE_LOC += q_ptr->MSG_SIZE; if (q_ptr->MSG_WRITE_LOC >= q_ptr->MSG_END_LOC) { q_ptr->MSG_WRITE_LOC = q_ptr->MSG_START_LOC; } /* Endif */ q_ptr->CURRENT_SIZE++; if (! _QUEUE_IS_EMPTY(&q_ptr->WAITING_READERS)) { _QUEUE_DEQUEUE(&q_ptr->WAITING_READERS, td_ptr); _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE); _TIME_DEQUEUE(td_ptr, kernel_data); td_ptr->INFO = 0; /* Signal that post is activating the task */ _TASK_READY(td_ptr, kernel_data); if (flags & LWMSGQ_SEND_BLOCK_ON_SEND) { _task_block(); } else { _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */ }/* Endif */ } else { if (flags & LWMSGQ_SEND_BLOCK_ON_SEND) { _task_block(); }/* Endif */ } /* Endif */ _int_enable(); /* Start CR 1944 */ _KLOGX2(KLOG_lwmsgq_send, MQX_OK); /* End CR 1944 */ return MQX_OK; }/* Endbody */