void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Get the unaligned size and position of the user-space heap. * This heap begins after the user-space .bss section at an offset * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). */ uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; size_t usize = CONFIG_RAM_END - ubase; DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); /* Return the user-space heap settings */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)ubase; *heap_size = usize; #else /* Return the heap settings */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)g_idle_topstack; *heap_size = CONFIG_RAM_END - g_idle_topstack; #endif }
void up_allocate_heap(FAR void **heap_start, size_t *heap_size) #endif { #if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) /* Get the unaligned size and position of the user-space heap. * This heap begins after the user-space .bss section at an offset * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). */ uintptr_t ubss_start = (uintptr_t)USERSPACE->us_bssstart; uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend; size_t usize = CONFIG_RAM_END - ubase; DEBUGASSERT(ubase < (uintptr_t)CONFIG_RAM_END); /* zero initialize the user space bss section */ memset((void *)ubss_start, 0, (ubase - ubss_start)); /* Return the user-space heap settings */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void *)ubase; *heap_size = usize; #else /* Return the heap settings */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void *)(g_idle_topstack & ~(0x7)); *heap_size = CONFIG_RAM_END - (uint32_t)(*heap_start); #endif }
void up_decodeirq(uint32_t *regs) { #ifdef CONFIG_SUPPRESS_INTERRUPTS board_led_on(LED_INIRQ); lowsyslog("Unexpected IRQ\n"); current_regs = regs; PANIC(); #else unsigned int irq; /* Read the IRQ number from the IVR register (Could probably get the same * info from CIC register without the setup). */ board_led_on(LED_INIRQ); irq = getreg32(STR71X_EIC_IVR); /* Verify that the resulting IRQ number is valid */ if (irq < NR_IRQS) { uint32_t* savestate; /* Current regs non-zero indicates that we are processing an interrupt; * current_regs is also used to manage interrupt level context switches. */ savestate = (uint32_t*)current_regs; current_regs = regs; /* Mask and acknowledge the interrupt */ up_maskack_irq(irq); /* Deliver the IRQ */ irq_dispatch(irq, regs); /* Restore the previous value of current_regs. NULL would indicate that * we are no longer in an interrupt handler. It will be non-NULL if we * are returning from a nested interrupt. */ current_regs = savestate; /* Unmask the last interrupt (global interrupts are still disabled) */ up_enable_irq(irq); } #if CONFIG_DEBUG else { PANIC(); /* Normally never happens */ } #endif board_led_off(LED_INIRQ); #endif }
void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { #if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) /* Get the unaligned size and position of the user-space heap. * This heap begins after the user-space .bss section at an offset * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment). */ uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; size_t usize = SRAM1_END - ubase; int log2; DEBUGASSERT(ubase < (uintptr_t)SRAM1_END); /* Adjust that size to account for MPU alignment requirements. * NOTE that there is an implicit assumption that the SRAM1_END * is aligned to the MPU requirement. */ log2 = (int)mpu_log2regionfloor(usize); DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0); usize = (1 << log2); ubase = SRAM1_END - usize; /* Return the user-space heap settings */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)ubase; *heap_size = usize; /* Colorize the heap for debug */ up_heap_color((FAR void*)ubase, usize); /* Allow user-mode access to the user heap memory */ stm32_mpu_uheap((uintptr_t)ubase, usize); #else /* Return the heap settings */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)g_idle_topstack; *heap_size = SRAM1_END - g_idle_topstack; /* Colorize the heap for debug */ up_heap_color(*heap_start, *heap_size); #endif }
void led_blink(int led_no, int on_duty_cycle, int off_duty_cycle) { int err, idx; idx = decide_led_array_index(led_no); if (idx == -WM_FAIL) return; if (os_timer_is_active(&led_data[idx].timer) == WM_SUCCESS) { err = os_timer_delete(&led_data[idx].timer); if (err != WM_SUCCESS) { return; } } led_data[idx].on_duty_cycle = on_duty_cycle; led_data[idx].off_duty_cycle = off_duty_cycle; board_led_on(led_no); led_data[idx].curr_state = LED_ON; err = os_timer_create(&led_data[idx].timer, "led-timer", os_msec_to_ticks(led_data[idx].on_duty_cycle), led_cb, (void *)idx, OS_TIMER_ONE_SHOT, OS_TIMER_AUTO_ACTIVATE); if (err != WM_SUCCESS) { return; } }
void up_assert(const uint8_t *filename, int lineno) { #ifdef CONFIG_PRINT_TASKNAME struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; #endif board_led_on(LED_ASSERTION); #ifdef CONFIG_PRINT_TASKNAME lldbg("Assertion failed at file:%s line: %d task: %s\n", filename, lineno, rtcb->name); #else lldbg("Assertion failed at file:%s line: %d\n", filename, lineno); #endif up_dumpstate(); #ifdef CONFIG_ARCH_USBDUMP /* Dump USB trace data */ (void)usbtrace_enumerate(assert_tracecallback, NULL); #endif _up_assert(EXIT_FAILURE); }
void up_assert(void) #endif { #if CONFIG_TASK_NAME_SIZE > 0 struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; #endif board_led_on(LED_ASSERTION); #ifdef CONFIG_HAVE_FILENAME #if CONFIG_TASK_NAME_SIZE > 0 lldbg("Assertion failed at file:%s line: %d task: %s\n", filename, lineno, rtcb->name); #else lldbg("Assertion failed at file:%s line: %d\n", filename, lineno); #endif #else #if CONFIG_TASK_NAME_SIZE > 0 lldbg("Assertion failed: task: %s\n", rtcb->name); #else lldbg("Assertion failed\n"); #endif #endif up_stackdump(); REGISTER_DUMP(); _up_assert(EXIT_FAILURE); }
int main(void) { evEntityId_t prev; eventviewer_init(); eventviewer_load(ev_ID_idle, idle); eventviewer_load(ev_ID_systick, SysTick_Handler); eventviewer_load(ev_ID_first_usrdef+1, userdef1); eventviewer_load(ev_ID_first_usrdef+2, userdef2); // the eventviewer shall stay most of time in idle // apart from some specific actions: systick, userdef1 and userdef2 eventviewer_switch_to(ev_ID_idle); board_led_init(); systickserv_start_systick(1000, myonsystick); for(;;) { prev = eventviewer_switch_to(ev_ID_first_usrdef+1); board_led_on(board_led_0); eventviewer_switch_to(prev); systickserv_wait_for(500*1000); prev = eventviewer_switch_to(ev_ID_first_usrdef+2); board_led_off(board_led_0); eventviewer_switch_to(prev); systickserv_wait_for(500*1000); } }
void up_sigdeliver(void) { #ifndef CONFIG_DISABLE_SIGNALS FAR struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; chipreg_t regs[XCPTCONTEXT_REGS]; sig_deliver_t sigdeliver; /* Save the errno. This must be preserved throughout the signal handling * so that the user code final gets the correct errno value (probably * EINTR). */ int saved_errno = rtcb->pterrno; board_led_on(LED_SIGNAL); sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); ASSERT(rtcb->xcp.sigdeliver != NULL); /* Save the real return state on the stack. */ ez80_copystate(regs, rtcb->xcp.regs); regs[XCPT_PC] = rtcb->xcp.saved_pc; regs[XCPT_I] = rtcb->xcp.saved_i; /* Get a local copy of the sigdeliver function pointer. We do this so * that we can nullify the sigdeliver function pointer in the TCB and * accept more signal deliveries while processing the current pending * signals. */ sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; /* Then restore the task interrupt state. */ irqrestore(regs[XCPT_I]); /* Deliver the signals */ sigdeliver(rtcb); /* Output any debug messages BEFORE restoring errno (because they may * alter errno), then disable interrupts again and restore the original * errno that is needed by the user logic (it is probably EINTR). */ sdbg("Resuming\n"); (void)irqsave(); rtcb->pterrno = saved_errno; /* Then restore the correct state for this thread of * execution. */ board_led_off(LED_SIGNAL); ez80_restorecontext(regs); #endif }
static uint32_t *common_handler(int irq, uint32_t *regs) { board_led_on(LED_INIRQ); /* Current regs non-zero indicates that we are processing an interrupt; * current_regs is also used to manage interrupt level context switches. * * Nested interrupts are not supported. */ DEBUGASSERT(current_regs == NULL); current_regs = regs; /* Deliver the IRQ */ irq_dispatch(irq, regs); #if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) /* Check for a context switch. If a context switch occurred, then * current_regs will have a different value than it did on entry. If an * interrupt level context switch has occurred, then restore the floating * point state and the establish the correct address environment before * returning from the interrupt. */ if (regs != current_regs) { #ifdef CONFIG_ARCH_FPU /* Restore floating point registers */ up_restorefpu((uint32_t*)current_regs); #endif #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously * running task is closed down gracefully (data caches dump, * MMU flushed) and set up the address environment for the new * thread at the head of the ready-to-run list. */ (void)group_addrenv(NULL); #endif } #endif /* If a context switch occurred while processing the interrupt then * current_regs may have change value. If we return any value different * from the input regs, then the lower level will know that a context * switch occurred during interrupt processing. */ regs = (uint32_t*)current_regs; /* Set current_regs to NULL to indicate that we are no longer in an * interrupt handler. */ current_regs = NULL; return regs; }
uint32_t *isr_handler(uint32_t *regs) { #ifdef CONFIG_SUPPRESS_INTERRUPTS board_led_on(LED_INIRQ); PANIC(); /* Doesn't return */ return regs; /* To keep the compiler happy */ #else uint32_t *ret; /* Dispatch the interrupt */ board_led_on(LED_INIRQ); ret = common_handler((int)regs[REG_IRQNO], regs); board_led_off(LED_INIRQ); return ret; #endif }
void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { /* Start with the first SRAM region */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)g_idle_topstack; *heap_size = CONFIG_RAM_END - g_idle_topstack; }
void stm32_ledpminitialize(void) { /* Register to receive power management callbacks */ int ret = pm_register(&g_ledscb); if (ret != OK) { board_led_on(LED_ASSERTION); } }
int main(void) { board_led_init(); systickserv_start_systick(1000, myonsystick); for(;;) { board_led_on(board_led_0); board_led_on(board_led_1); systickserv_wait_for(500*1000); board_led_off(board_led_0); board_led_off(board_led_1); systickserv_wait_for(500*1000); } }
FAR chipreg_t *up_doirq(int irq, FAR chipreg_t *regs) { FAR chipreg_t *ret = regs; board_led_on(LED_INIRQ); #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(); #else if ((unsigned)irq < NR_IRQS) { FAR chipreg_t *savestate; /* Nested interrupts are not supported in this implementation. If * you want to implement nested interrupts, you would have to (1) change * the way that current_regs is handled and (2) the design associated * with CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not * work for that purpose as implemented here because only the outermost * nested interrupt can result in a context switch (it can probably be * deleted). */ /* Current regs non-zero indicates that we are processing * an interrupt; current_regs is also used to manage * interrupt level context switches. */ savestate = (FAR chipreg_t *)current_regs; current_regs = regs; /* Acknowledge the interrupt */ up_ack_irq(irq); /* Deliver the IRQ */ irq_dispatch(irq, regs); /* Restore the previous value of current_regs. NULL would indicate that * we are no longer in an interrupt handler. It will be non-NULL if we * are returning from a nested interrupt. */ ret = current_regs; current_regs = savestate; } board_led_off(LED_INIRQ); #endif return ret; }
uint32_t *irq_handler(uint32_t *regs) { #ifdef CONFIG_SUPPRESS_INTERRUPTS board_led_on(LED_INIRQ); PANIC(); /* Doesn't return */ return regs; /* To keep the compiler happy */ #else uint32_t *ret; int irq; board_led_on(LED_INIRQ); /* Get the IRQ number */ irq = (int)regs[REG_IRQNO]; /* Send an EOI (end of interrupt) signal to the PICs if this interrupt * involved the slave. */ if (irq >= IRQ8) { /* Send reset signal to slave */ idt_outb(PIC_OCW2_EOI_NONSPEC, PIC2_OCW2); } /* Send reset signal to master */ idt_outb(PIC_OCW2_EOI_NONSPEC, PIC1_OCW2); /* Dispatch the interrupt */ ret = common_handler(irq, regs); board_led_off(LED_INIRQ); return ret; #endif }
uint32_t *up_doirq(int irq, uint32_t *regs) { board_led_on(LED_INIRQ); #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(); #else uint32_t *savestate; /* Nested interrupts are not supported in this implementation. If you want * to implement nested interrupts, you would have to (1) change the way that * current_regs is handled and (2) the design associated with * CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not work for * that purpose as implemented here because only the outermost nested * interrupt can result in a context switch (it can probably be deleted). */ /* Current regs non-zero indicates that we are processing an interrupt; * current_regs is also used to manage interrupt level context switches. */ savestate = (uint32_t*)current_regs; current_regs = regs; /* Acknowledge the interrupt */ up_ack_irq(irq); /* Deliver the IRQ */ irq_dispatch(irq, regs); /* If a context switch occurred while processing the interrupt then * current_regs may have change value. If we return any value different * from the input regs, then the lower level will know that a context * switch occurred during interrupt processing. */ regs = (uint32_t*)current_regs; /* Restore the previous value of current_regs. NULL would indicate that * we are no longer in an interrupt handler. It will be non-NULL if we * are returning from a nested interrupt. */ current_regs = savestate; #endif board_led_off(LED_INIRQ); return regs; }
void led_on(int led_no) { int idx = decide_led_array_index(led_no); int ret; if (idx == -WM_FAIL) return; if (os_timer_is_active(&led_data[idx].timer) == WM_SUCCESS) { ret = os_timer_delete(&led_data[idx].timer); if (ret != WM_SUCCESS) { wmprintf("Unable to delete LED timer\n\r"); return; } } led_data[idx].curr_state = LED_ON; board_led_on(led_no); }
static void led_cb(os_timer_arg_t handle) { int tid = (int) os_timer_get_context(&handle); if (tid >= LED_COUNT) { return; } if (led_data[tid].curr_state == LED_ON) { board_led_off(led_data[tid].led_no); led_data[tid].curr_state = LED_OFF; os_timer_change(&led_data[tid].timer, led_data[tid].off_duty_cycle, -1); os_timer_activate(&led_data[tid].timer); } else { board_led_on(led_data[tid].led_no); led_data[tid].curr_state = LED_ON; os_timer_change(&led_data[tid].timer, led_data[tid].on_duty_cycle, -1); os_timer_activate(&led_data[tid].timer); } }
static void _up_assert(int errorcode) { /* Are we in an interrupt handler or the idle task? */ if (current_regs || ((struct tcb_s*)g_readytorun.head)->pid == 0) { (void)irqsave(); for (;;) { #ifdef CONFIG_ARCH_LEDS board_led_on(LED_PANIC); up_mdelay(250); board_led_off(LED_PANIC); up_mdelay(250); #endif } } else { exit(errorcode); } }
static void _up_assert(int errorcode) /* noreturn_function */ { /* Are we in an interrupt handler or the idle task? */ if (up_interrupt_context() || ((FAR struct tcb_s*)g_readytorun.head)->pid == 0) { (void)irqsave(); for(;;) { #ifdef CONFIG_ARCH_LEDS board_led_on(LED_PANIC); up_mdelay(250); board_led_off(LED_PANIC); up_mdelay(250); #endif } } else { exit(errorcode); } }
void up_idle(void) { #if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP) g_ledtoggle++; if (g_ledtoggle == 0x80) { board_led_on(LED_IDLE); } else if (g_ledtoggle == 0x00) { board_led_off(LED_IDLE); } #endif #if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) /* If the system is idle and there are no timer interrupts, * then process "fake" timer interrupts. Hopefully, something * will wake up. */ sched_process_timer(); #endif }
void up_assert(void) #endif { #if CONFIG_TASK_NAME_SIZE > 0 struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; #endif board_led_on(LED_ASSERTION); #ifdef CONFIG_HAVE_FILENAME #if CONFIG_TASK_NAME_SIZE > 0 lldbg("Assertion failed at file:%s line: %d task: %s\n", filename, lineno, rtcb->name); #else lldbg("Assertion failed at file:%s line: %d\n", filename, lineno); #endif #else #if CONFIG_TASK_NAME_SIZE > 0 lldbg("Assertion failed: task: %s\n", rtcb->name); #else lldbg("Assertion failed\n"); #endif #endif up_stackdump(); REGISTER_DUMP(); #ifdef CONFIG_ARCH_USBDUMP /* Dump USB trace data */ (void)usbtrace_enumerate(assert_tracecallback, NULL); #endif _up_assert(EXIT_FAILURE); }
void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)g_idle_topstack; *heap_size = LPC31_HEAP_VEND - g_idle_topstack; }
void up_initialize(void) { /* Initialize global variables */ current_regs = NULL; /* Calibrate the timing loop */ up_calibratedelay(); /* Add any extra memory fragments to the memory manager */ up_addregion(); /* Initialize the interrupt subsystem */ up_irqinitialize(); /* Initialize the DMA subsystem if the weak function stm32_dmainitialize has been * brought into the build */ #ifdef CONFIG_ARCH_DMA #ifdef CONFIG_HAVE_WEAKFUNCTIONS if (up_dmainitialize) #endif { up_dmainitialize(); } #endif /* Initialize the system timer interrupt */ #if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS) up_timer_initialize(); #endif /* Register devices */ #if CONFIG_NFILE_DESCRIPTORS > 0 #if defined(CONFIG_DEV_NULL) devnull_register(); /* Standard /dev/null */ #endif #if defined(CONFIG_DEV_ZERO) devzero_register(); /* Standard /dev/zero */ #endif #endif /* CONFIG_NFILE_DESCRIPTORS */ /* Initialize the serial device driver */ #ifdef USE_SERIALDRIVER up_serialinit(); #endif /* Initialize the console device driver (if it is other than the standard * serial driver). */ #if defined(CONFIG_DEV_LOWCONSOLE) lowconsole_init(); #elif defined(CONFIG_SYSLOG_CONSOLE) syslog_console_init(); #elif defined(CONFIG_RAMLOG_CONSOLE) ramlog_consoleinit(); #endif /* Initialize the system logging device */ #ifdef CONFIG_SYSLOG_CHAR syslog_initialize(); #endif #ifdef CONFIG_RAMLOG_SYSLOG ramlog_sysloginit(); #endif #ifndef CONFIG_NETDEV_LATEINIT /* Initialize the network */ up_netinitialize(); #endif #ifdef CONFIG_NETDEV_LOOPBACK /* Initialize the local loopback device */ (void)localhost_initialize(); #endif #ifdef CONFIG_NET_TUN /* Initialize the TUN device */ (void)tun_initialize(); #endif /* Initialize USB -- device and/or host */ up_usbinitialize(); board_led_on(LED_IRQSENABLED); }
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { static bool first_task = true; /* Is there already a stack allocated of a different size? Because of * alignment issues, stack_size might erroneously appear to be of a * different size. Fortunately, this is not a critical operation. */ if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) { /* Yes.. Release the old stack */ up_release_stack(tcb, ttype); } /* Do we need to allocate a new stack? */ if (!tcb->stack_alloc_ptr) { /* Allocate the stack. If DEBUG is enabled (but not stack debug), * then create a zeroed stack to make stack dumps easier to trace. */ #ifdef HAVE_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ if (ttype == TCB_FLAG_TTYPE_KERNEL) { tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); } else #endif { /* Use the user-space allocator if this is a task or pthread */ tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } #ifdef CONFIG_DEBUG /* Was the allocation successful? */ if (!tcb->stack_alloc_ptr) { sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); } #endif } /* Did we successfully allocate a stack? */ if (tcb->stack_alloc_ptr) { size_t top_of_stack; size_t size_of_stack; /* The ARM uses a push-down stack: the stack grows toward lower * addresses in memory. The stack pointer register, points to * the lowest, valid work address (the "top" of the stack). Items * on the stack are referenced as positive word offsets from sp. */ top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; /* The ARM stack must be aligned; 4 byte alignment for OABI and * 8-byte alignment for EABI. If necessary top_of_stack must be * rounded down to the next boundary */ top_of_stack = STACK_ALIGN_DOWN(top_of_stack); /* The size of the stack in bytes is then the difference between * the top and the bottom of the stack (+4 because if the top * is the same as the bottom, then the size is one 32-bit element). * The size need not be aligned. */ size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the struct tcb_s */ tcb->adj_stack_ptr = (uint32_t*)top_of_stack; tcb->adj_stack_size = size_of_stack; /* If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. */ #ifdef CONFIG_STACK_COLORATION up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size); #endif if (first_task) { board_led_on(LED_STACKCREATED); first_task = false; } return OK; } return ERROR; }
__EXPORT int nsh_archinitialize(void) { /* configure ADC pins */ stm32_configgpio(GPIO_ADC1_IN2); /* BATT_VOLTAGE_SENS */ stm32_configgpio(GPIO_ADC1_IN3); /* BATT_CURRENT_SENS */ stm32_configgpio(GPIO_ADC1_IN4); /* VDD_5V_SENS */ stm32_configgpio(GPIO_ADC1_IN13); /* FMU_AUX_ADC_1 */ stm32_configgpio(GPIO_ADC1_IN14); /* FMU_AUX_ADC_2 */ stm32_configgpio(GPIO_ADC1_IN15); /* PRESSURE_SENS */ /* configure power supply control/sense pins */ stm32_configgpio(GPIO_VDD_5V_PERIPH_EN); stm32_configgpio(GPIO_VDD_3V3_SENSORS_EN); stm32_configgpio(GPIO_VDD_BRICK_VALID); stm32_configgpio(GPIO_VDD_SERVO_VALID); stm32_configgpio(GPIO_VDD_5V_HIPOWER_OC); stm32_configgpio(GPIO_VDD_5V_PERIPH_OC); #if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE) /* run C++ ctors before we go any further */ up_cxxinitialize(); # if defined(CONFIG_EXAMPLES_NSH_CXXINITIALIZE) # error CONFIG_EXAMPLES_NSH_CXXINITIALIZE Must not be defined! Use CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE. # endif #else # error platform is dependent on c++ both CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE must be defined. #endif /* configure the high-resolution time/callout interface */ hrt_init(); /* configure the DMA allocator */ dma_alloc_init(); /* configure CPU load estimation */ #ifdef CONFIG_SCHED_INSTRUMENTATION cpuload_initialize_once(); #endif /* set up the serial DMA polling */ static struct hrt_call serial_dma_call; struct timespec ts; /* * Poll at 1ms intervals for received bytes that have not triggered * a DMA event. */ ts.tv_sec = 0; ts.tv_nsec = 1000000; hrt_call_every(&serial_dma_call, ts_to_abstime(&ts), ts_to_abstime(&ts), (hrt_callout)stm32_serial_dma_poll, NULL); /* initial LED state */ drv_led_start(); led_off(LED_AMBER); /* Configure SPI-based devices */ spi1 = up_spiinitialize(1); if (!spi1) { syslog(LOG_ERR, "[boot] FAILED to initialize SPI port 1\n"); board_led_on(LED_AMBER); return -ENODEV; } /* Default SPI1 to 1MHz and de-assert the known chip selects. */ SPI_SETFREQUENCY(spi1, 10000000); SPI_SETBITS(spi1, 8); SPI_SETMODE(spi1, SPIDEV_MODE3); SPI_SELECT(spi1, PX4_SPIDEV_GYRO, false); SPI_SELECT(spi1, PX4_SPIDEV_ACCEL_MAG, false); SPI_SELECT(spi1, PX4_SPIDEV_BARO, false); SPI_SELECT(spi1, PX4_SPIDEV_MPU, false); up_udelay(20); syslog(LOG_INFO, "[boot] Initialized SPI port 1 (SENSORS)\n"); /* Get the SPI port for the FRAM */ spi2 = up_spiinitialize(2); if (!spi2) { syslog(LOG_ERR, "[boot] FAILED to initialize SPI port 2\n"); board_led_on(LED_AMBER); return -ENODEV; } /* Default SPI2 to 37.5 MHz (40 MHz rounded to nearest valid divider, F4 max) * and de-assert the known chip selects. */ // XXX start with 10.4 MHz in FRAM usage and go up to 37.5 once validated SPI_SETFREQUENCY(spi2, 12 * 1000 * 1000); SPI_SETBITS(spi2, 8); SPI_SETMODE(spi2, SPIDEV_MODE3); SPI_SELECT(spi2, SPIDEV_FLASH, false); syslog(LOG_INFO, "[boot] Initialized SPI port 2 (RAMTRON FRAM)\n"); spi4 = up_spiinitialize(4); /* Default SPI4 to 1MHz and de-assert the known chip selects. */ SPI_SETFREQUENCY(spi4, 10000000); SPI_SETBITS(spi4, 8); SPI_SETMODE(spi4, SPIDEV_MODE3); SPI_SELECT(spi4, PX4_SPIDEV_EXT0, false); SPI_SELECT(spi4, PX4_SPIDEV_EXT1, false); syslog(LOG_INFO, "[boot] Initialized SPI port 4\n"); #ifdef CONFIG_MMCSD /* First, get an instance of the SDIO interface */ sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO); if (!sdio) { syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", CONFIG_NSH_MMCSDSLOTNO); return -ENODEV; } /* Now bind the SDIO interface to the MMC/SD driver */ int ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, sdio); if (ret != OK) { syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret); return ret; } /* Then let's guess and say that there is a card in the slot. There is no card detect GPIO. */ sdio_mediachange(sdio, true); syslog(LOG_INFO, "[boot] Initialized SDIO\n"); #endif return OK; }
void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { *heap_start = (FAR void*)UP_HEAP1_BASE; *heap_size = UP_HEAP1_END - UP_HEAP1_BASE; board_led_on(LED_HEAPALLOCATE); }
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* Is there already a stack allocated of a different size? Because of * alignment issues, stack_size might erroneously appear to be of a * different size. Fortunately, this is not a critical operation. */ if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) { /* Yes.. Release the old stack */ up_release_stack(tcb, ttype); } /* Do we need to allocate a new stack? */ if (!tcb->stack_alloc_ptr) { /* Allocate the stack. If DEBUG is enabled (but not stack debug), * then create a zeroed stack to make stack dumps easier to trace. */ #if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Use the kernel allocator if this is a kernel thread */ if (ttype == TCB_FLAG_TTYPE_KERNEL) { #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK) tcb->stack_alloc_ptr = (uint32_t *)kmm_zalloc(stack_size); #else tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); #endif } else #endif { /* Use the user-space allocator if this is a task or pthread */ #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK) tcb->stack_alloc_ptr = (uint32_t *)kumm_zalloc(stack_size); #else tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); #endif } #ifdef CONFIG_DEBUG /* Was the allocation successful? */ if (!tcb->stack_alloc_ptr) { sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); } #endif } /* Did we successfully allocate a stack? */ if (tcb->stack_alloc_ptr) { size_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. */ #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK) memset(tcb->stack_alloc_ptr, 0xaa, stack_size); #endif /* The i486 uses a push-down stack: the stack grows toward lower * addresses in memory. The stack pointer register, points to the * lowest, valid work address (the "top" of the stack). Items on * the stack are referenced as positive word offsets from sp. */ top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; /* The i486 stack must be aligned at word (4 byte) boundaries. If * necessary top_of_stack must be rounded down to the next boundary */ top_of_stack &= ~3; size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the struct tcb_s */ tcb->adj_stack_ptr = (uint32_t*)top_of_stack; tcb->adj_stack_size = size_of_stack; board_led_on(LED_STACKCREATED); return OK; } return ERROR; }
FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs) { board_led_on(LED_INIRQ); #ifdef CONFIG_SUPPRESS_INTERRUPTS lowsyslog(LOG_ERR, "Unexpected IRQ\n"); IRQ_ENTER(regs); PANIC(); return NULL; /* Won't get here */ #else #ifdef CONFIG_ARCH_ADDRENV FAR chipreg_t *newregs; #endif if (irq < NR_IRQS) { DECL_SAVESTATE(); /* Indicate that we have entered IRQ processing logic */ IRQ_ENTER(irq, regs); /* Deliver the IRQ */ irq_dispatch(irq, regs); #ifdef CONFIG_ARCH_ADDRENV /* If a context switch occurred, 'newregs' will hold the new context */ newregs = IRQ_STATE(); if (newregs != regs) { /* Make sure that the address environment for the previously * running task is closed down gracefully and set up the * address environment for the new thread at the head of the * ready-to-run list. */ (void)group_addrenv(NULL); } regs = newregs; #else /* If a context switch occurred, 'regs' will hold the new context */ regs = IRQ_STATE(); #endif /* Indicate that we are no longer in interrupt processing logic */ IRQ_LEAVE(irq); } board_led_off(LED_INIRQ); return regs; #endif }