diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-11-04 15:12:55 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-11-04 15:12:55 +0000 |
commit | dec5edaa7fcf561f5538ca3ba0af07e402a6b55e (patch) | |
tree | 91d9f298d4568c87e8a0c3f4211e229dc80f2b13 /nuttx/arch/rgmp/src/nuttx.c | |
parent | 9c2462da3c765755e63a15e85050e92a9d873a6c (diff) | |
download | px4-nuttx-dec5edaa7fcf561f5538ca3ba0af07e402a6b55e.tar.gz px4-nuttx-dec5edaa7fcf561f5538ca3ba0af07e402a6b55e.tar.bz2 px4-nuttx-dec5edaa7fcf561f5538ca3ba0af07e402a6b55e.zip |
RGMP 4.0 update from Qiang Yu
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5305 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/rgmp/src/nuttx.c')
-rw-r--r-- | nuttx/arch/rgmp/src/nuttx.c | 317 |
1 files changed, 162 insertions, 155 deletions
diff --git a/nuttx/arch/rgmp/src/nuttx.c b/nuttx/arch/rgmp/src/nuttx.c index 14b3e6d1d..7deb959a2 100644 --- a/nuttx/arch/rgmp/src/nuttx.c +++ b/nuttx/arch/rgmp/src/nuttx.c @@ -38,13 +38,12 @@ ****************************************************************************/ #include <rgmp/boot.h> -#include <rgmp/pmap.h> +#include <rgmp/cxx.h> +#include <rgmp/memlayout.h> +#include <rgmp/allocator.h> #include <rgmp/assert.h> -#include <rgmp/spinlock.h> #include <rgmp/string.h> - #include <rgmp/arch/arch.h> -#include <rgmp/arch/console.h> #include <nuttx/sched.h> #include <nuttx/kmalloc.h> @@ -67,37 +66,34 @@ static inline void up_switchcontext(_TCB *ctcb, _TCB *ntcb) { // do nothing if two tasks are the same if (ctcb == ntcb) - return; + return; // this function can not be called in interrupt if (up_interrupt_context()) { - panic("%s: try to switch context in interrupt\n", __func__); + panic("%s: try to switch context in interrupt\n", __func__); } // start switch current_task = ntcb; - rgmp_context_switch(ctcb?&ctcb->xcp.tf:NULL, ntcb->xcp.tf); + rgmp_context_switch(ctcb ? &ctcb->xcp.ctx : NULL, &ntcb->xcp.ctx); } void up_initialize(void) { extern pidhash_t g_pidhash[]; - extern void up_register_bridges(void); - extern void vnet_initialize(void); + extern void vdev_init(void); extern void nuttx_arch_init(void); // intialize the current_task to g_idletcb current_task = g_pidhash[PIDHASH(0)].tcb; - // setup console - up_register_bridges(); + // OS memory alloc system is ready + use_os_kmalloc = 1; -#ifdef CONFIG_NET_VNET - // setup vnet device - vnet_initialize(); -#endif + // rgmp vdev init + vdev_init(); - nuttx_arch_init(); + nuttx_arch_init(); // enable interrupt local_irq_enable(); @@ -110,8 +106,9 @@ void up_idle(void) void up_allocate_heap(void **heap_start, size_t *heap_size) { + void *boot_freemem = boot_alloc(0, sizeof(int)); *heap_start = boot_freemem; - *heap_size = KERNBASE + boot_param.mem_size - (uint32_t)boot_freemem; + *heap_size = KERNBASE + kmem_size - (uint32_t)boot_freemem; } int up_create_stack(_TCB *tcb, size_t stack_size) @@ -128,16 +125,16 @@ int up_create_stack(_TCB *tcb, size_t stack_size) uint32_t *stack_alloc_ptr = (uint32_t*)kmalloc(adj_stack_size); if (stack_alloc_ptr) { - /* This is the address of the last word in the allocation */ + /* This is the address of the last word in the allocation */ - adj_stack_ptr = &stack_alloc_ptr[adj_stack_words - 1]; + adj_stack_ptr = &stack_alloc_ptr[adj_stack_words - 1]; - /* Save the values in the TCB */ + /* Save the values in the TCB */ - tcb->adj_stack_size = adj_stack_size; - tcb->stack_alloc_ptr = stack_alloc_ptr; - tcb->adj_stack_ptr = (void *)((unsigned int)adj_stack_ptr & ~7); - ret = OK; + tcb->adj_stack_size = adj_stack_size; + tcb->stack_alloc_ptr = stack_alloc_ptr; + tcb->adj_stack_ptr = (void *)((unsigned int)adj_stack_ptr & ~7); + ret = OK; } return ret; } @@ -164,7 +161,7 @@ int up_use_stack(_TCB *tcb, void *stack, size_t stack_size) void up_release_stack(_TCB *dtcb) { if (dtcb->stack_alloc_ptr) { - free(dtcb->stack_alloc_ptr); + free(dtcb->stack_alloc_ptr); } dtcb->stack_alloc_ptr = NULL; @@ -199,43 +196,43 @@ void up_block_task(_TCB *tcb, tstate_t task_state) { /* Verify that the context switch can be performed */ if ((tcb->task_state < FIRST_READY_TO_RUN_STATE) || - (tcb->task_state > LAST_READY_TO_RUN_STATE)) { - warn("%s: task sched error\n", __func__); - return; + (tcb->task_state > LAST_READY_TO_RUN_STATE)) { + warn("%s: task sched error\n", __func__); + return; } else { - _TCB *rtcb = current_task; - bool switch_needed; - - /* Remove the tcb task from the ready-to-run list. If we - * are blocking the task at the head of the task list (the - * most likely case), then a context switch to the next - * ready-to-run task is needed. In this case, it should - * also be true that rtcb == tcb. - */ - switch_needed = sched_removereadytorun(tcb); - - /* Add the task to the specified blocked task list */ - sched_addblocked(tcb, (tstate_t)task_state); - - /* Now, perform the context switch if one is needed */ - if (switch_needed) { - _TCB *nexttcb; - // this part should not be executed in interrupt context - if (up_interrupt_context()) { - panic("%s: %d\n", __func__, __LINE__); - } - // If there are any pending tasks, then add them to the g_readytorun - // task list now. It should be the up_realease_pending() called from - // sched_unlock() to do this for disable preemption. But it block - // itself, so it's OK. - if (g_pendingtasks.head) { - warn("Disable preemption failed for task block itself\n"); - sched_mergepending(); - } - nexttcb = (_TCB*)g_readytorun.head; - // context switch - up_switchcontext(rtcb, nexttcb); + _TCB *rtcb = current_task; + bool switch_needed; + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + sched_addblocked(tcb, (tstate_t)task_state); + + /* Now, perform the context switch if one is needed */ + if (switch_needed) { + _TCB *nexttcb; + // this part should not be executed in interrupt context + if (up_interrupt_context()) { + panic("%s: %d\n", __func__, __LINE__); + } + // If there are any pending tasks, then add them to the g_readytorun + // task list now. It should be the up_realease_pending() called from + // sched_unlock() to do this for disable preemption. But it block + // itself, so it's OK. + if (g_pendingtasks.head) { + warn("Disable preemption failed for task block itself\n"); + sched_mergepending(); + } + nexttcb = (_TCB*)g_readytorun.head; + // context switch + up_switchcontext(rtcb, nexttcb); } } } @@ -259,31 +256,31 @@ void up_unblock_task(_TCB *tcb) { /* Verify that the context switch can be performed */ if ((tcb->task_state < FIRST_BLOCKED_STATE) || - (tcb->task_state > LAST_BLOCKED_STATE)) { - warn("%s: task sched error\n", __func__); - return; + (tcb->task_state > LAST_BLOCKED_STATE)) { + warn("%s: task sched error\n", __func__); + return; } else { - _TCB *rtcb = current_task; + _TCB *rtcb = current_task; - /* Remove the task from the blocked task list */ - sched_removeblocked(tcb); + /* Remove the task from the blocked task list */ + sched_removeblocked(tcb); - /* Reset its timeslice. This is only meaningful for round - * robin tasks but it doesn't here to do it for everything - */ + /* Reset its timeslice. This is only meaningful for round + * robin tasks but it doesn't here to do it for everything + */ #if CONFIG_RR_INTERVAL > 0 - tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK; + tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK; #endif - // Add the task in the correct location in the prioritized - // g_readytorun task list. - if (sched_addreadytorun(tcb) && !up_interrupt_context()) { - /* The currently active task has changed! */ - _TCB *nexttcb = (_TCB*)g_readytorun.head; - // context switch - up_switchcontext(rtcb, nexttcb); - } + // Add the task in the correct location in the prioritized + // g_readytorun task list. + if (sched_addreadytorun(tcb) && !up_interrupt_context()) { + /* The currently active task has changed! */ + _TCB *nexttcb = (_TCB*)g_readytorun.head; + // context switch + up_switchcontext(rtcb, nexttcb); + } } } @@ -298,11 +295,11 @@ void up_release_pending(void) /* Merge the g_pendingtasks list into the g_readytorun task list */ if (sched_mergepending()) { - /* The currently active task has changed! */ - _TCB *nexttcb = (_TCB*)g_readytorun.head; + /* The currently active task has changed! */ + _TCB *nexttcb = (_TCB*)g_readytorun.head; - // context switch - up_switchcontext(rtcb, nexttcb); + // context switch + up_switchcontext(rtcb, nexttcb); } } @@ -311,54 +308,54 @@ void up_reprioritize_rtr(_TCB *tcb, uint8_t priority) /* Verify that the caller is sane */ if (tcb->task_state < FIRST_READY_TO_RUN_STATE || - tcb->task_state > LAST_READY_TO_RUN_STATE + tcb->task_state > LAST_READY_TO_RUN_STATE #if SCHED_PRIORITY_MIN > UINT8_MIN - || priority < SCHED_PRIORITY_MIN + || priority < SCHED_PRIORITY_MIN #endif #if SCHED_PRIORITY_MAX < UINT8_MAX - || priority > SCHED_PRIORITY_MAX + || priority > SCHED_PRIORITY_MAX #endif - ) { - warn("%s: task sched error\n", __func__); - return; + ) { + warn("%s: task sched error\n", __func__); + return; } else { - _TCB *rtcb = current_task; - bool switch_needed; - - /* Remove the tcb task from the ready-to-run list. - * sched_removereadytorun will return true if we just - * remove the head of the ready to run list. - */ - switch_needed = sched_removereadytorun(tcb); - - /* Setup up the new task priority */ - tcb->sched_priority = (uint8_t)priority; - - /* Return the task to the specified blocked task list. - * sched_addreadytorun will return true if the task was - * added to the new list. We will need to perform a context - * switch only if the EXCLUSIVE or of the two calls is non-zero - * (i.e., one and only one the calls changes the head of the - * ready-to-run list). - */ - switch_needed ^= sched_addreadytorun(tcb); - - /* Now, perform the context switch if one is needed */ - if (switch_needed && !up_interrupt_context()) { - _TCB *nexttcb; - // If there are any pending tasks, then add them to the g_readytorun - // task list now. It should be the up_realease_pending() called from - // sched_unlock() to do this for disable preemption. But it block - // itself, so it's OK. - if (g_pendingtasks.head) { - warn("Disable preemption failed for reprioritize task\n"); - sched_mergepending(); + _TCB *rtcb = current_task; + bool switch_needed; + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + if (switch_needed && !up_interrupt_context()) { + _TCB *nexttcb; + // If there are any pending tasks, then add them to the g_readytorun + // task list now. It should be the up_realease_pending() called from + // sched_unlock() to do this for disable preemption. But it block + // itself, so it's OK. + if (g_pendingtasks.head) { + warn("Disable preemption failed for reprioritize task\n"); + sched_mergepending(); } - nexttcb = (_TCB*)g_readytorun.head; - // context switch - up_switchcontext(rtcb, nexttcb); + nexttcb = (_TCB*)g_readytorun.head; + // context switch + up_switchcontext(rtcb, nexttcb); } } } @@ -390,26 +387,26 @@ void up_assert(const uint8_t *filename, int line) // which will stop the OS // if in user space just terminate the task if (up_interrupt_context() || current_task->pid == 0) { - panic("%s: %d\n", __func__, __LINE__); + panic("%s: %d\n", __func__, __LINE__); } else { - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } void up_assert_code(const uint8_t *filename, int line, int code) { fprintf(stderr, "Assertion failed at file:%s line: %d error code: %d\n", - filename, line, code); + filename, line, code); // in interrupt context or idle task means kernel error // which will stop the OS // if in user space just terminate the task if (up_interrupt_context() || current_task->pid == 0) { - panic("%s: %d\n", __func__, __LINE__); + panic("%s: %d\n", __func__, __LINE__); } else { - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } @@ -420,38 +417,38 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) { /* Refuse to handle nested signal actions */ if (!tcb->xcp.sigdeliver) { - int flags; - - /* Make sure that interrupts are disabled */ - flags = pushcli(); - - // First, handle some special cases when the signal is - // being delivered to the currently executing task. - if (tcb == current_task) { - // CASE 1: We are not in an interrupt handler and - // a task is signalling itself for some reason. - if (!up_interrupt_context()) { - // In this case just deliver the signal now. - sigdeliver(tcb); - } - // CASE 2: We are in an interrupt handler AND the - // interrupted task is the same as the one that - // must receive the signal. - else { - tcb->xcp.sigdeliver = sigdeliver; + int flags; + + /* Make sure that interrupts are disabled */ + local_irq_save(flags); + + // First, handle some special cases when the signal is + // being delivered to the currently executing task. + if (tcb == current_task) { + // CASE 1: We are not in an interrupt handler and + // a task is signalling itself for some reason. + if (!up_interrupt_context()) { + // In this case just deliver the signal now. + sigdeliver(tcb); + } + // CASE 2: We are in an interrupt handler AND the + // interrupted task is the same as the one that + // must receive the signal. + else { + tcb->xcp.sigdeliver = sigdeliver; } } - // Otherwise, we are (1) signaling a task is not running - // from an interrupt handler or (2) we are not in an - // interrupt handler and the running task is signalling - // some non-running task. - else { - tcb->xcp.sigdeliver = sigdeliver; - push_xcptcontext(&tcb->xcp); + // Otherwise, we are (1) signaling a task is not running + // from an interrupt handler or (2) we are not in an + // interrupt handler and the running task is signalling + // some non-running task. + else { + tcb->xcp.sigdeliver = sigdeliver; + push_xcptcontext(&tcb->xcp); } - popcli(flags); + local_irq_restore(flags); } } @@ -461,7 +458,7 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) bool up_interrupt_context(void) { if (nest_irq) - return true; + return true; return false; } @@ -496,6 +493,16 @@ void up_sigdeliver(struct Trapframe *tf) local_irq_disable(); } +#if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE) + +void up_cxxinitialize(void) +{ + rgmp_cxx_init(); +} + +#endif + + |