/* * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /****************************************************************************** * @file csi_rhino.c * @brief the adapter file for the rhino * @version V1.0 * @date 20. July 2016 ******************************************************************************/ #include #include #include #include #include #include #include extern uint32_t dump_mmleak(void); extern void krhino_task_dump(ktask_t *task, void* stack); #define AUTORUN 1 #define TMR_ONE_SHOT_DLY 10 #define TMR_PERIODIC_PERIOD 10 #define RHINO_OS_MS_PERIOD_TICK (1000 / RHINO_CONFIG_TICKS_PER_SECOND) __init k_status_t csi_kernel_init(void) { kstat_t ret = krhino_init(); #ifdef CONFIG_KERNEL_PWR_MGMT extern void cpu_pwrmgmt_init(void); cpu_pwrmgmt_init(); #endif if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } __init k_status_t csi_kernel_start(void) { kstat_t ret = krhino_start(); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } k_sched_stat_t csi_kernel_get_stat(void) { kstat_t get = g_sys_stat; if (get == RHINO_STOPPED) { return KSCHED_ST_INACTIVE; } else if (get == RHINO_RUNNING) { return KSCHED_ST_RUNNING; } return KSCHED_ST_ERROR; } int32_t csi_kernel_sched_lock(void) { return -EOPNOTSUPP; } int32_t csi_kernel_sched_unlock(void) { return -EOPNOTSUPP; } int32_t csi_kernel_sched_restore_lock(int32_t lock) { return -EOPNOTSUPP; } uint32_t csi_kernel_sched_suspend(void) { if (g_sys_stat != RHINO_RUNNING) { return 0; } krhino_sched_disable(); return 0; } void csi_kernel_sched_resume(uint32_t sleep_ticks) { if (g_sys_stat != RHINO_RUNNING) { return; } krhino_sched_enable(); } k_status_t csi_kernel_task_new(k_task_entry_t task, const char *name, void *arg, k_priority_t prio, uint32_t time_quanta, void *stack, uint32_t stack_size, k_task_handle_t *task_handle) { if ((task_handle == NULL) || (stack_size % 4 != 0) || ((stack_size == 0) && (stack == NULL)) || prio <= KPRIO_IDLE || prio > KPRIO_REALTIME7) { return -EINVAL; } k_status_t rc = -1; #if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) uint8_t prio_trans = RHINO_CONFIG_USER_PRI_MAX - prio; csi_kernel_sched_suspend(); kstat_t ret; if (name) { ret = krhino_task_dyn_create((ktask_t **)task_handle, name, arg, prio_trans, time_quanta, stack, stack_size / 4, task, AUTORUN); } else { ret = krhino_task_dyn_create((ktask_t **)task_handle, "user_task", arg, prio_trans, time_quanta, stack, stack_size / 4, task, AUTORUN); } if (ret == RHINO_SUCCESS) { csi_kernel_sched_resume(0); return 0; } else { csi_kernel_sched_resume(0); return -EPERM; } #endif return rc; } k_status_t csi_kernel_task_del(k_task_handle_t task_handle) { if (task_handle == NULL) { return -EINVAL; } k_status_t rc = -1; #if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) kstat_t ret = krhino_task_dyn_del(task_handle); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } #else kstat_t ret = krhino_task_del(task_handle); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } #endif return rc; } k_task_handle_t csi_kernel_task_get_cur(void) { ktask_t *ret; ret = g_active_task[cpu_cur_get()]; return (k_task_handle_t)ret; } k_task_stat_t csi_kernel_task_get_stat(k_task_handle_t task_handle) { if (task_handle == NULL) { return KTASK_ST_ERROR; } if (csi_kernel_task_get_cur() == task_handle) { return KTASK_ST_RUNNING; } task_stat_t get; ktask_t *handle = (ktask_t *)task_handle; get = handle->task_state; switch (get) { case K_PEND: case K_SUSPENDED: case K_PEND_SUSPENDED: case K_SLEEP: case K_SLEEP_SUSPENDED: return KTASK_ST_BLOCKED; break; case K_DELETED: return KTASK_ST_TERMINATED; break; case K_RDY: return KTASK_ST_READY; break; default: return KTASK_ST_ERROR; } } k_status_t csi_kernel_task_set_prio(k_task_handle_t task_handle, k_priority_t priority) { if (task_handle == NULL || priority <= KPRIO_IDLE || priority > KPRIO_REALTIME7) { return -EINVAL; } uint8_t prio = RHINO_CONFIG_USER_PRI_MAX - priority; uint8_t old; kstat_t ret = krhino_task_pri_change(task_handle, prio, &old); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } k_status_t csi_kernel_task_set_lprun(k_task_handle_t task_handle, uint8_t run) { if (task_handle == NULL) { return -EINVAL; } krhino_task_set_lprun(task_handle, run); return 0; } void csi_kernel_lpower_mode(uint8_t enable) { krhino_lpower_mode(enable); } k_priority_t csi_kernel_task_get_prio(k_task_handle_t task_handle) { if (task_handle == NULL) { return KPRIO_ERROR; } ktask_t *handle = (ktask_t *)task_handle; uint8_t ret = handle->prio; if (ret <= RHINO_CONFIG_USER_PRI_MAX) { ret = RHINO_CONFIG_USER_PRI_MAX - ret; } else { ret = RHINO_CONFIG_PRI_MAX - ret; } return ret; } const char *csi_kernel_task_get_name(k_task_handle_t task_handle) { if (task_handle == NULL) { return NULL; } ktask_t *handle = (ktask_t *)task_handle; return handle->task_name; } k_status_t csi_kernel_task_suspend(k_task_handle_t task_handle) { if (task_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_task_suspend(task_handle); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } k_status_t csi_kernel_task_resume(k_task_handle_t task_handle) { if (task_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_task_resume(task_handle); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } void csi_kernel_task_dump(k_task_handle_t task_handle, void* stack) { krhino_task_dump(task_handle, stack); } k_status_t csi_kernel_task_terminate(k_task_handle_t task_handle) { return csi_kernel_task_del(task_handle); } void csi_kernel_task_exit(void) { csi_kernel_task_del(csi_kernel_task_get_cur()); } k_status_t csi_kernel_task_yield(void) { kstat_t ret = krhino_task_yield(); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } uint32_t csi_kernel_task_get_count(void) { #if (RHINO_CONFIG_SYSTEM_STATS > 0) klist_t *taskhead; klist_t *taskend; klist_t *tmp; taskhead = &g_kobj_list.task_head; taskend = taskhead; uint32_t ret = 0; for (tmp = taskhead->next; tmp != taskend; tmp = tmp->next) { ret ++; } return ret; #else return 0; #endif } uint32_t csi_kernel_task_get_stack_size(k_task_handle_t task_handle) { if (task_handle == NULL) { return 0; } ktask_t *handle = (ktask_t *)task_handle; return 4 * handle->stack_size; } uint32_t csi_kernel_task_get_stack_space(k_task_handle_t task_handle) { if (task_handle == NULL) { return 0; } uint32_t stack_free; kstat_t ret = krhino_task_stack_min_free(task_handle, &stack_free); if (ret == RHINO_SUCCESS) { return 4 * stack_free; } else { return 0; } } uint32_t csi_kernel_task_list(k_task_handle_t *task_array, uint32_t array_items) { if (task_array == NULL || array_items == 0) { return 0; } uint32_t real_tsk_num = 0; #if (RHINO_CONFIG_SYSTEM_STATS > 0) klist_t *taskhead; klist_t *taskend; klist_t *tmp; ktask_t *task; k_task_handle_t *tk_tmp = task_array; taskhead = &g_kobj_list.task_head; taskend = taskhead; #ifdef CONFIG_BACKTRACE uint32_t task_free; size_t irq_flags; #endif #ifdef CONFIG_STACK_GUARD int stack_flags; #endif for (tmp = taskhead->next; tmp != taskend; tmp = tmp->next) { real_tsk_num ++; task = krhino_list_entry(tmp, ktask_t, task_stats_item); #ifdef CONFIG_BACKTRACE krhino_task_stack_min_free(task, &task_free); printf("\n%s:\n\t state %d, pri %d, stack: total %d, free %d\n", task->task_name, task->task_state, task->prio, 4 * task->stack_size, 4 * task_free); #endif } if (array_items < real_tsk_num) { real_tsk_num = array_items; } for (tmp = taskhead->next; tmp != taskend && real_tsk_num >= 1; tmp = tmp->next) { task = krhino_list_entry(tmp, ktask_t, task_stats_item); *tk_tmp = task; tk_tmp ++; } #ifdef CONFIG_BACKTRACE irq_flags = cpu_intrpt_save(); #ifdef CONFIG_STACK_GUARD extern int stack_guard_save(void); stack_flags = stack_guard_save(); #endif for (tmp = taskhead->next; tmp != taskend; tmp = tmp->next) { task = krhino_list_entry(tmp, ktask_t, task_stats_item); krhino_task_stack_min_free(task, &task_free); printf("\n%s:\n", task->task_name); extern int csky_task_backtrace(void *stack, char *buf, int len); csky_task_backtrace(task->task_stack, NULL, 0); } #ifdef CONFIG_STACK_GUARD extern void stack_guard_restore(int value); stack_guard_restore(stack_flags); #endif cpu_intrpt_restore(irq_flags); #endif /* CONFIG_BACKTRACE */ #endif /* RHINO_CONFIG_SYSTEM_STATS */ return real_tsk_num; } k_status_t csi_kernel_intrpt_enter(void) { kstat_t ret = krhino_intrpt_enter(); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } return 0; } k_status_t csi_kernel_intrpt_exit(void) { krhino_intrpt_exit(); return 0; } k_status_t csi_kernel_delay(uint32_t ticks) { kstat_t ret = krhino_task_sleep(ticks); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } k_status_t csi_kernel_delay_until(uint64_t ticks) { return -EOPNOTSUPP; } uint64_t csi_kernel_tick2ms(uint32_t ticks) { return ((uint64_t)ticks * RHINO_OS_MS_PERIOD_TICK); } uint64_t csi_kernel_ms2tick(uint32_t ms) { if (ms < RHINO_OS_MS_PERIOD_TICK) { return 0; } return (((uint64_t)ms) / RHINO_OS_MS_PERIOD_TICK); } k_status_t csi_kernel_delay_ms(uint32_t ms) { uint32_t ms_get = ms; if ((ms < RHINO_OS_MS_PERIOD_TICK) && (ms != 0)) { ms_get = RHINO_OS_MS_PERIOD_TICK; } uint64_t ticks = csi_kernel_ms2tick(ms_get); kstat_t ret = krhino_task_sleep(ticks); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } uint64_t csi_kernel_get_ticks(void) { return (uint64_t)krhino_sys_tick_get(); } uint64_t csi_kernel_suspend_tick(void) { // return next_task_wake_tick_get(); return 0; } void csi_kernel_update_tick(uint32_t ms) { extern uint64_t g_sys_tick_count; uint32_t ticks = ms * RHINO_CONFIG_TICKS_PER_SECOND / 1000; CPSR_ALLOC(); RHINO_CPU_INTRPT_DISABLE(); g_sys_tick_count += ticks; RHINO_CPU_INTRPT_ENABLE(); } uint32_t csi_kernel_get_tick_freq(void) { return RHINO_CONFIG_TICKS_PER_SECOND; } uint32_t csi_kernel_get_systimer_freq(void) { return 0;//drv_get_sys_freq(); } typedef struct tmr_ad { k_timer_cb_t func; ktimer_t tmr; } tmr_ad_t; typedef struct tmr_arg { void *arg; tmr_ad_t *tmr_above; } tmr_arg_t; static void tmr_adapt_cb(void *timer, void *arg) { ktimer_t *get = (ktimer_t *)timer; tmr_arg_t *arg_above = (tmr_arg_t *)(get->timer_cb_arg); tmr_ad_t *tmr_above = (tmr_ad_t *)arg_above->tmr_above; tmr_above->func(arg_above->arg); return; } k_timer_handle_t csi_kernel_timer_new(k_timer_cb_t func, k_timer_type_t type, void *arg) { if (type < 0 || type > 3 || func == NULL) { return NULL; } tick_t first = TMR_ONE_SHOT_DLY; tick_t round; if (type == KTIMER_TYPE_ONCE) { round = 0; } else { round = TMR_PERIODIC_PERIOD; } tmr_ad_t *handle_ad = (tmr_ad_t *)krhino_mm_alloc(sizeof(tmr_ad_t), __builtin_return_address(0)); if (handle_ad == NULL) { return NULL; } tmr_arg_t *get_arg = (tmr_arg_t *)krhino_mm_alloc(sizeof(tmr_arg_t), __builtin_return_address(0)); if (get_arg == NULL) { krhino_mm_free((void *)handle_ad); return NULL; } get_arg->arg = arg; kstat_t ret = krhino_timer_create(&(handle_ad->tmr), "UserTmr", (timer_cb_t)tmr_adapt_cb, first, round, get_arg, 0); if (ret == RHINO_SUCCESS) { handle_ad->func = func; get_arg->tmr_above = handle_ad; return handle_ad; } else { krhino_mm_free((void *)handle_ad); krhino_mm_free((void *)get_arg); return NULL; } } k_status_t csi_kernel_timer_del(k_timer_handle_t timer_handle) { if (timer_handle == NULL) { return -EINVAL; } tmr_ad_t *handle_ad = (tmr_ad_t *)timer_handle; kstat_t ret = krhino_timer_del(&(handle_ad->tmr)); if (ret == RHINO_SUCCESS) { krhino_mm_free(((ktimer_t *)(&(handle_ad->tmr)))->timer_cb_arg); krhino_mm_free(timer_handle); return 0; } else { return -EPERM; } } k_status_t csi_kernel_timer_start(k_timer_handle_t timer_handle, uint32_t ticks) { if (timer_handle == NULL || ticks == 0) { return -EINVAL; } tick_t round; tmr_ad_t *handle_ad = (tmr_ad_t *)timer_handle; ktimer_t *handle = (ktimer_t *)(&(handle_ad->tmr)); round = handle->round_ticks; tick_t tr; tick_t tf = ticks; if (round != 0) { tr = ticks; } else { tr = 0; } kstat_t ret1 = krhino_timer_change(handle, tf, tr); if (ret1 == RHINO_SUCCESS) { kstat_t ret2 = krhino_timer_start(handle); if (ret2 == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } else { return -EPERM; } } k_status_t csi_kernel_timer_stop(k_timer_handle_t timer_handle) { if (timer_handle == NULL) { return -EINVAL; } tmr_ad_t *handle_ad = (tmr_ad_t *)timer_handle; ktimer_t *handle = (ktimer_t *)(&(handle_ad->tmr)); kstat_t ret = krhino_timer_stop(handle); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } k_timer_stat_t csi_kernel_timer_get_stat(k_timer_handle_t timer_handle) { if (timer_handle == NULL) { return KTIMER_ST_INACTIVE; } tmr_ad_t *handle_ad = (tmr_ad_t *)timer_handle; ktimer_t *handle = (ktimer_t *)(&(handle_ad->tmr)); k_timer_state_t get = handle->timer_state; if (get == TIMER_DEACTIVE) { return KTIMER_ST_INACTIVE; } else { return KTIMER_ST_ACTIVE; } } k_event_handle_t csi_kernel_event_new(void) { #if (RHINO_CONFIG_EVENT_FLAG > 0) kevent_t *handle = (kevent_t *)krhino_mm_alloc(sizeof(kevent_t), __builtin_return_address(0)); if (handle == NULL) { return NULL; } kstat_t ret = krhino_event_create(handle, "UserEvent", 0); if (ret == RHINO_SUCCESS) { return handle; } else { return NULL; } #else return NULL; #endif } k_status_t csi_kernel_event_del(k_event_handle_t ev_handle) { #if (RHINO_CONFIG_EVENT_FLAG > 0) if (ev_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_event_del(ev_handle); if (ret == RHINO_SUCCESS) { krhino_mm_free(ev_handle); return 0; } else { return -EPERM; } #else return -EOPNOTSUPP; #endif } k_status_t csi_kernel_event_set(k_event_handle_t ev_handle, uint32_t flags, uint32_t *ret_flags) { #if (RHINO_CONFIG_EVENT_FLAG > 0) if (ev_handle == NULL || ret_flags == NULL) { return -EINVAL; } kstat_t ret = krhino_event_set(ev_handle, flags, RHINO_OR); if (ret == RHINO_SUCCESS) { kevent_t *handle = (kevent_t *)ev_handle; *ret_flags = handle->flags; return 0; } else { return -EPERM; } #else return -EOPNOTSUPP; #endif } k_status_t csi_kernel_event_clear(k_event_handle_t ev_handle, uint32_t flags, uint32_t *ret_flags) { #if (RHINO_CONFIG_EVENT_FLAG > 0) if (ev_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_event_set(ev_handle, ~flags, RHINO_AND); if (ret == RHINO_SUCCESS) { kevent_t *handle = (kevent_t *)ev_handle; if(ret_flags) *ret_flags = handle->flags; return 0; } else { return -EPERM; } #else return -EOPNOTSUPP; #endif } k_status_t csi_kernel_event_get(k_event_handle_t ev_handle, uint32_t *ret_flags) { #if (RHINO_CONFIG_EVENT_FLAG > 0) if (ev_handle == NULL || ret_flags == NULL) { return -EINVAL; } kevent_t *handle = (kevent_t *)ev_handle; *ret_flags = handle->flags; return 0; #else return -EOPNOTSUPP; #endif } k_status_t csi_kernel_event_wait(k_event_handle_t ev_handle, uint32_t flags, k_event_opt_t options, uint8_t clr_on_exit, uint32_t *actl_flags, int32_t timeout) { #if (RHINO_CONFIG_EVENT_FLAG > 0) if (ev_handle == NULL || actl_flags == NULL || ((clr_on_exit != 0) && (clr_on_exit != 1))) { return -EINVAL; } if (options == KEVENT_OPT_CLR_ANY || options == KEVENT_OPT_CLR_ALL) { return -EOPNOTSUPP; } uint8_t opt = 0; if (options == KEVENT_OPT_SET_ANY) { if (clr_on_exit == 1) { opt = RHINO_OR_CLEAR; } else { opt = RHINO_OR; } } else if (options == KEVENT_OPT_SET_ALL) { if (clr_on_exit == 1) { opt = RHINO_AND_CLEAR; } else { opt = RHINO_AND; } } tick_t t; if (timeout < 0) { t = RHINO_WAIT_FOREVER; } else { t = timeout; } kstat_t ret = krhino_event_get(ev_handle, flags, opt, actl_flags, t); if (ret == RHINO_SUCCESS) { return 0; } else if (ret == RHINO_BLK_TIMEOUT) { return -ETIMEDOUT; } else { return -EPERM; } #else return -EOPNOTSUPP; #endif } k_mutex_handle_t csi_kernel_mutex_new(void) { kmutex_t *handle = (kmutex_t *)krhino_mm_alloc(sizeof(kmutex_t), __builtin_return_address(0)); if (handle == NULL) { return NULL; } kstat_t ret = krhino_mutex_create(handle, "UserMutex"); if (ret == RHINO_SUCCESS) { return handle; } else { return NULL; } } k_status_t csi_kernel_mutex_del(k_mutex_handle_t mutex_handle) { if (mutex_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_mutex_del(mutex_handle); if (ret == RHINO_SUCCESS) { krhino_mm_free(mutex_handle); return 0; } else { return -EPERM; } } k_status_t csi_kernel_mutex_lock(k_mutex_handle_t mutex_handle, int32_t timeout, uint32_t lr) { if (mutex_handle == NULL) { return -EINVAL; } tick_t t; if (timeout < 0) { t = RHINO_WAIT_FOREVER; } else { t = timeout; } kstat_t ret = krhino_mutex_lock(mutex_handle, t, lr); if (ret == RHINO_SUCCESS || ret == RHINO_MUTEX_OWNER_NESTED) { return 0; } else if (ret == RHINO_BLK_TIMEOUT) { return -ETIMEDOUT; } else { return -EPERM; } } k_status_t csi_kernel_mutex_unlock(k_mutex_handle_t mutex_handle) { if (mutex_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_mutex_unlock(mutex_handle); if (ret == RHINO_SUCCESS || ret == RHINO_MUTEX_OWNER_NESTED) { return 0; } else { return -EPERM; } } k_task_handle_t csi_kernel_mutex_get_owner(k_mutex_handle_t mutex_handle) { if (mutex_handle == NULL) { return NULL; } kmutex_t *handle = (kmutex_t *)mutex_handle; return handle->mutex_task; } k_sem_handle_t csi_kernel_sem_new(int32_t max_count, int32_t initial_count) { if (max_count <= 0 || initial_count < 0) { return NULL; } if (max_count < initial_count) { return NULL; } ksem_t *handle = (ksem_t *)krhino_mm_alloc(sizeof(ksem_t), __builtin_return_address(0)); if (handle == NULL) { return NULL; } kstat_t ret = krhino_sem_create(handle, "UserSem", initial_count); if (ret == RHINO_SUCCESS) { return handle; } else { return NULL; } } k_status_t csi_kernel_sem_del(k_sem_handle_t sem_handle) { if (sem_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_sem_del(sem_handle); if (ret == RHINO_SUCCESS) { krhino_mm_free(sem_handle); return 0; } else { return -EPERM; } } k_status_t csi_kernel_sem_wait(k_sem_handle_t sem_handle, int32_t timeout) { if (sem_handle == NULL) { return -EINVAL; } tick_t t; if (timeout < 0) { t = RHINO_WAIT_FOREVER; } else { t = timeout; } kstat_t ret = krhino_sem_take(sem_handle, t); if (ret == RHINO_SUCCESS) { return 0; } else if (ret == RHINO_BLK_TIMEOUT) { return -ETIMEDOUT; } else { return -EPERM; } } k_status_t csi_kernel_sem_post(k_sem_handle_t sem_handle) { if (sem_handle == NULL) { return -EINVAL; } kstat_t ret = krhino_sem_give(sem_handle); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } int32_t csi_kernel_sem_get_count(k_sem_handle_t sem_handle) { if (sem_handle == NULL) { return -EINVAL; } sem_count_t cnt; kstat_t ret = krhino_sem_count_get(sem_handle, &cnt); if (ret == RHINO_SUCCESS) { return (int32_t)cnt; } else { return -EPERM; } } #if 0 k_mpool_handle_t csi_kernel_mpool_new(void *p_addr, int32_t block_count, int32_t block_size) { if (p_addr == NULL || block_count < 0 || block_size <= 0 || (block_size % 4 != 0)) { return NULL; } #if (RHINO_CONFIG_MM_BLK > 0) mblk_pool_t *handle = (mblk_pool_t *)krhino_mm_alloc(sizeof(mblk_pool_t), __builtin_return_address(0)); if (handle == NULL) { return NULL; } kstat_t ret = krhino_mblk_pool_init(handle, "UserMp", p_addr, block_size, block_count * block_size); if (ret == RHINO_SUCCESS) { return handle; } else { return NULL; } #else return NULL; #endif } k_status_t csi_kernel_mpool_del(k_mpool_handle_t mp_handle) { if (mp_handle == NULL) { return -EINVAL; } memset(mp_handle, 0, sizeof(mblk_pool_t)); krhino_mm_free(mp_handle); return 0; } void *csi_kernel_mpool_alloc(k_mpool_handle_t mp_handle, int32_t timeout) { if (mp_handle == NULL) { return NULL; } #if (RHINO_CONFIG_MM_BLK > 0) uint32_t g_csi_rhino_blk = 0; kstat_t ret = krhino_mblk_alloc(mp_handle, (void **)&g_csi_rhino_blk); if (ret == RHINO_SUCCESS) { return (void *)g_csi_rhino_blk; } else { return NULL; } #else return NULL; #endif } k_status_t csi_kernel_mpool_free(k_mpool_handle_t mp_handle, void *block) { if (mp_handle == NULL || block == NULL) { return -EINVAL; } #if (RHINO_CONFIG_MM_BLK > 0) kstat_t ret = krhino_mblk_free(mp_handle, block); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } #else return -EPERM; #endif } int32_t csi_kernel_mpool_get_count(k_mpool_handle_t mp_handle) { if (mp_handle == NULL) { return 0; } mblk_pool_t *handle = (mblk_pool_t *)mp_handle; int32_t used = handle->blk_whole - handle->blk_avail; return used; } uint32_t csi_kernel_mpool_get_capacity(k_mpool_handle_t mp_handle) { if (mp_handle == NULL) { return 0; } mblk_pool_t *handle = (mblk_pool_t *)mp_handle; return handle->blk_whole; } uint32_t csi_kernel_mpool_get_block_size(k_mpool_handle_t mp_handle) { if (mp_handle == NULL) { return 0; } mblk_pool_t *handle = (mblk_pool_t *)mp_handle; return handle->blk_size; } #endif typedef struct mq_adapter { kbuf_queue_t *buf_q; int32_t msg_size; int32_t msg_count; } mq_adapter_t; k_msgq_handle_t csi_kernel_msgq_new(int32_t msg_count, int32_t msg_size) { if (msg_count <= 0 || msg_size <= 0) { return NULL; } #if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) mq_adapter_t *handle = (mq_adapter_t *)krhino_mm_alloc(sizeof(mq_adapter_t), __builtin_return_address(0)); if (handle == NULL) { return NULL; } kstat_t ret = krhino_buf_queue_dyn_create(&(handle->buf_q), "UserMsgQ", msg_size * (msg_count + 1), msg_size); if (ret == RHINO_SUCCESS) { handle->msg_count = msg_count; handle->msg_size = msg_size; return (k_msgq_handle_t)handle; } else { krhino_mm_free(handle); return NULL; } #else return NULL; #endif } k_status_t csi_kernel_msgq_del(k_msgq_handle_t mq_handle) { if (!mq_handle) { return -EINVAL; } #if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) mq_adapter_t *handle = (mq_adapter_t *)mq_handle; kstat_t ret = krhino_buf_queue_dyn_del(handle->buf_q); if (ret == RHINO_SUCCESS) { krhino_mm_free(mq_handle); return 0; } else { return -EPERM; } #else return -EPERM; #endif } k_status_t csi_kernel_msgq_put(k_msgq_handle_t mq_handle, const void *msg_ptr, uint8_t front_or_back, int32_t timeout) { k_status_t retval = -EPERM; if ((!mq_handle) || (msg_ptr == NULL) || ((front_or_back != 0) && (front_or_back != 1))) { return -EINVAL; } mq_adapter_t *handle = (mq_adapter_t *)mq_handle; if (front_or_back == 0) { kstat_t ret = krhino_buf_queue_send(handle->buf_q, (void *)msg_ptr, handle->msg_size, timeout); if (ret == RHINO_SUCCESS) { retval = 0 ; } else { retval = -EPERM; } } else if (front_or_back == 1) { kstat_t ret = krhino_buf_queue_send(handle->buf_q, (void *)msg_ptr, handle->msg_size, timeout); if (ret == RHINO_SUCCESS) { retval = 0; } else { retval = -EPERM; } } return retval; } k_status_t csi_kernel_msgq_get(k_msgq_handle_t mq_handle, void *msg_ptr, int32_t timeout) { if (mq_handle == NULL || msg_ptr == NULL) { return -EINVAL; } tick_t t; if (timeout < 0) { t = RHINO_WAIT_FOREVER; } else { t = timeout; } mq_adapter_t *handle = (mq_adapter_t *)mq_handle; uint32_t size; kstat_t ret = krhino_buf_queue_recv(handle->buf_q, t, msg_ptr, &size); if (ret == RHINO_SUCCESS) { return 0; } else if (ret == RHINO_BLK_TIMEOUT) { return -ETIMEDOUT; } else { return -EPERM; } } int32_t csi_kernel_msgq_get_count(k_msgq_handle_t mq_handle) { if (mq_handle == NULL) { return -EINVAL; } mq_adapter_t *handle = (mq_adapter_t *)mq_handle; kbuf_queue_info_t info; kstat_t ret = krhino_buf_queue_info_get(handle->buf_q, &info); if (ret == RHINO_SUCCESS) { int32_t cnt = info.cur_num; return cnt; } else { return -EPERM; } } uint32_t csi_kernel_msgq_get_capacity(k_msgq_handle_t mq_handle) { if (mq_handle == NULL) { return 0; } mq_adapter_t *handle = (mq_adapter_t *)mq_handle; return handle->msg_count; } uint32_t csi_kernel_msgq_get_msg_size(k_msgq_handle_t mq_handle) { if (mq_handle == NULL) { return 0; } mq_adapter_t *handle = (mq_adapter_t *)mq_handle; return handle->buf_q->max_msg_size; } k_status_t csi_kernel_msgq_flush(k_msgq_handle_t mq_handle) { if (mq_handle == NULL) { return -EINVAL; } mq_adapter_t *handle = (mq_adapter_t *)mq_handle; kstat_t ret = krhino_buf_queue_flush(handle->buf_q); if (ret == RHINO_SUCCESS) { return 0; } else { return -EPERM; } } #if 0 void *csi_kernel_malloc(int32_t size, void *caller) { void *ret; if (size < 1) { return NULL; } csi_kernel_sched_suspend(); ret = krhino_mm_alloc(size, caller); csi_kernel_sched_resume(0); return ret; } void csi_kernel_free(void *ptr, void *caller) { csi_kernel_sched_suspend(); krhino_mm_free(ptr); csi_kernel_sched_resume(0); } void *csi_kernel_realloc(void *ptr, int32_t size, void *caller) { void *new_ptr; new_ptr = krhino_mm_realloc(ptr, size, caller); return new_ptr; } #endif #if 0 k_status_t csi_kernel_get_mminfo(int32_t *total, int32_t *used, int32_t *free, int32_t *peak) { *total = g_kmm_head->used_size + g_kmm_head->free_size; *used = g_kmm_head->used_size; *free = g_kmm_head->free_size; *peak = g_kmm_head->maxused_size; return 0; } k_status_t csi_kernel_mm_dump(void) { #if (RHINO_CONFIG_MM_DEBUG > 0u) dumpsys_mm_info_func(NULL, 0); #endif return 0; } #endif const char *csi_kernel_task_status_text(int state) { switch(state){ case K_SEED: return "Seed"; case K_RDY: return "Ready"; case K_PEND: return "Pend"; case K_SUSPENDED: return "Suspended"; case K_PEND_SUSPENDED: return "Pend_Suspended"; case K_SLEEP: return "Sleep"; case K_SLEEP_SUSPENDED: return "Sleep_Suspended"; case K_DELETED: return "Deleted"; default: return "Unused"; } } struct os_task_info { uint32_t id; const char *name; const char *status; uint32_t time; uint32_t stack; uint32_t prio; uint32_t arg; }; uint32_t csi_kernel_task_runtime(struct os_task_info *tsk_rumtime, int count) { #if (RHINO_CONFIG_SYSTEM_STATS > 0) uint32_t ret = 0; klist_t *taskhead; klist_t *taskend; klist_t *tmp; ktask_t *task; taskhead = &g_kobj_list.task_head; taskend = taskhead; for (tmp = taskhead->next; tmp != taskend && ret < count; tmp = tmp->next) { task = krhino_list_entry(tmp, ktask_t, task_stats_item); if(task == &g_idle_task[cpu_cur_get()]) //忽略idle task continue; tsk_rumtime[ret].id = ret; tsk_rumtime[ret].name = task->task_name; tsk_rumtime[ret].time = task->runtime; tsk_rumtime[ret].stack = task->stack_size; tsk_rumtime[ret].prio = task->prio; tsk_rumtime[ret].arg = (uint32_t)task; tsk_rumtime[ret].status = csi_kernel_task_status_text(task->task_state); task->runtime = 0; ret ++; } return ret; #else return 0; #endif } void csi_kernel_task_print(void) { #if (RHINO_CONFIG_SYSTEM_STATS > 0) klist_t *taskhead; klist_t *taskend; klist_t *tmp; ktask_t *task; taskhead = &g_kobj_list.task_head; taskend = taskhead; for (tmp = taskhead->next; tmp != taskend; tmp = tmp->next) { task = krhino_list_entry(tmp, ktask_t, task_stats_item); printf("\0011Task %s %s, ticks:%d stack:%d prio:%d arg:%p\r\n", task->task_name, csi_kernel_task_status_text(task->task_state), task->runtime, task->stack_size, task->prio, task); task->runtime = 0; } #endif } int csi_kernel_task_count(void) { int count = 0; #if (RHINO_CONFIG_SYSTEM_STATS > 0) klist_t *taskhead; klist_t *taskend; klist_t *tmp; taskhead = &g_kobj_list.task_head; taskend = taskhead; for (tmp = taskhead->next; tmp != taskend; tmp = tmp->next) { count++; } #endif return count; } void csi_kernel_blklist_suspend(void *hdl, k_task_handle_t task_hdl) { CPSR_ALLOC(); ktask_t *task = (ktask_t *)task_hdl; blk_obj_t *obj = (blk_obj_t *)hdl; if (obj) { krhino_check_fatal_call(__FUNCTION__); if (task == NULL) { task = g_active_task[cpu_cur_get()]; } printf("task %s suspend!\r\n", task->task_name); RHINO_CRITICAL_ENTER(); if (obj->obj_type != RHINO_BLKLIST_OBJ_TYPE) { RHINO_CRITICAL_EXIT(); return; } pend_to_blk_obj(obj, task, RHINO_WAIT_FOREVER, psr); RHINO_CRITICAL_EXIT_SCHED(); /* task has been wakeup !!!*/ RHINO_CPU_INTRPT_DISABLE(); /* so the task is waked up, need know which reason cause wake up */ pend_state_end_proc(task); RHINO_CPU_INTRPT_ENABLE(); printf("task %s wakeup ...\r\n", task->task_name); } } void csi_kernel_blklist_wakeup(void *hdl) { CPSR_ALLOC(); klist_t *iter; klist_t *event_head; klist_t *iter_temp; ktask_t *task; blk_obj_t *obj = (blk_obj_t *)hdl; if (obj) { /* this is only needed when system zero interrupt feature is enabled */ #if (RHINO_CONFIG_INTRPT_GUARD > 0) soc_intrpt_guard(); #endif RHINO_CRITICAL_ENTER(); if (obj->obj_type != RHINO_BLKLIST_OBJ_TYPE) { RHINO_CRITICAL_EXIT(); return; } event_head = &obj->blk_list; iter = event_head->next; /* if list is not empty */ while (iter != event_head) { task = krhino_list_entry(iter, ktask_t, task_list); iter_temp = iter->next; pend_task_wakeup(task); iter = iter_temp; } RHINO_CRITICAL_EXIT_SCHED(); } } void *csi_kernel_blklist_new() { blk_obj_t *obj = malloc(sizeof(blk_obj_t)); if (obj) { memset(obj, 0, sizeof(blk_obj_t)); klist_init(&obj->blk_list); obj->blk_policy = BLK_POLICY_PRI; obj->name = "blklist"; obj->obj_type = RHINO_BLKLIST_OBJ_TYPE; } return obj; } void csi_kernel_blklist_del(void *hdl) { blk_obj_t *obj = (blk_obj_t *)hdl; if (obj && obj->obj_type == RHINO_BLKLIST_OBJ_TYPE) { csi_kernel_blklist_wakeup(hdl); obj->obj_type = RHINO_OBJ_TYPE_NONE; free(obj); } }