| ===================================================== |
| APIs Exported by Architecture-Specific Logic to NuttX |
| ===================================================== |
| |
| .. c:function:: void up_initialize(void) |
| |
| Called once during OS |
| initialization after the basic OS services have been initialized. |
| The architecture specific details of initializing the OS will be |
| handled here. Such things as setting up interrupt service |
| routines, starting the clock, and registering device |
| are some of the things that are |
| different for each processor and hardware platform. |
| |
| ``up_initialize()`` is called after the OS initialized but before |
| the init process has been started and before the libraries have |
| been initialized. OS services and driver services are available. |
| |
| .. c:function:: void up_idle(void) |
| |
| The logic that will be executed |
| when their is no other ready-to-run task. This is processor idle |
| time and will continue until some interrupt occurs to cause a |
| context switch from the idle task. |
| |
| Processing in this state may be processor-specific. e.g., this is |
| where power management operations might be performed. |
| |
| .. c:function:: void up_initial_state(FAR struct tcb_s *tcb) |
| |
| A new thread is being started and a new TCB has |
| been created. This function is called to initialize the processor |
| specific portions of the new TCB. |
| |
| This function must setup the initial architecture registers and/or |
| stack so that execution will begin at tcb->start on the next |
| context switch. |
| |
| This function may also need to set up processor registers so that |
| the new thread executes with the correct privileges. If |
| ``CONFIG_BUILD_PROTECTED`` or ``CONFIG_BUILD_KERNEL`` have been |
| selected in the NuttX configuration, then special initialization |
| may need to be performed depending on the task type specified in |
| the TCB's flags field: Kernel threads will require kernel-mode |
| privileges; User tasks and pthreads should have only user-mode |
| privileges. If neither ``CONFIG_BUILD_PROTECTED`` nor |
| ``CONFIG_BUILD_KERNEL`` have been selected, then all threads |
| should have kernel-mode privileges. |
| |
| .. c:function:: STATUS up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) |
| |
| Allocate a stack for a new thread and setup up |
| stack-related information in the TCB. |
| |
| The following TCB fields must be initialized: |
| |
| - ``adj_stack_size``: Stack size after adjustment for hardware, |
| processor, etc. This value is retained only for debug purposes. |
| - ``stack_alloc_ptr``: Pointer to allocated stack |
| - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data |
| and Arguments has been removed from the stack allocation. |
| |
| :param tcb: The TCB of new task. |
| :param stack_size: The requested stack size. At least this much |
| must be allocated. |
| :param ttype: The thread type. This may be one of following |
| (defined in ``include/nuttx/sched.h``): |
| |
| - ``TCB_FLAG_TTYPE_TASK``: Normal user task |
| - ``TCB_FLAG_TTYPE_PTHREAD``: User pthread |
| - ``TCB_FLAG_TTYPE_KERNEL``: Kernel thread |
| |
| This thread type is normally available in the flags field of |
| the TCB, however, there are certain contexts where the TCB may |
| not be fully initialized when up_create_stack is called. |
| |
| If ``CONFIG_BUILD_PROTECTED`` or ``CONFIG_BUILD_KERNEL`` are |
| defined, then this thread type may affect how the stack is |
| allocated. For example, kernel thread stacks should be |
| allocated from protected kernel memory. Stacks for user tasks |
| and threads must come from memory that is accessible to user |
| code. |
| |
| .. c:function:: STATUS up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) |
| |
| Setup up stack-related information in the TCB |
| using pre-allocated stack memory. This function is called only |
| from ``nxtask_init()`` when a task or kernel thread is started |
| (never for pthreads). |
| |
| The following TCB fields must be initialized: |
| |
| - ``adj_stack_size``: Stack size after adjustment for hardware, |
| processor, etc. This value is retained only for debug purposes. |
| - ``stack_alloc_ptr``: Pointer to allocated stack |
| - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data |
| and Arguments has been removed from the stack allocation. |
| |
| :param tcb: The TCB of new task. |
| :param stack_size: The allocated stack size. |
| |
| NOTE: Unlike ``up_stack_create()`` and ``up_stack_release``, this |
| function does not require the task type (``ttype``) parameter. The |
| TCB flags will always be set to provide the task type to |
| ``up_use_stack()`` if the information needs that information. |
| |
| .. c:function:: FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) |
| |
| Allocate a stack frame in the TCB's stack to hold |
| thread-specific data. This function may be called any time after |
| ``up_create_stack()`` or ``up_use_stack()`` have been called but |
| before the task has been started. |
| |
| Thread data may be kept in the stack (instead of in the TCB) if it |
| is accessed by the user code directly. This includes such things |
| as ``argv[]``. The stack memory is guaranteed to be in the same |
| protection domain as the thread. |
| |
| The following TCB fields will be re-initialized: |
| |
| - ``adj_stack_size``: Stack size after removal of the stack frame |
| from the stack. |
| - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data |
| and Arguments has been removed from the stack allocation. |
| |
| Here is the diagram after some allocation(tls, arg):: |
| |
| +-------------+ <-stack_alloc_ptr(lowest) |
| | TLS Data | |
| +-------------+ |
| | Arguments | |
| stack_base_ptr-> +-------------+\ |
| | Available | + |
| | Stack | | |
| | | | | |
| | | | +->adj_stack_size |
| v | | | |
| | | | |
| | | + |
| +-------------+/ |
| |
| :param tcb: The TCB of new task. |
| :param frame_size: The size of the stack frame to allocate. |
| |
| :return: |
| A pointer to bottom of the allocated stack |
| frame. NULL will be returned on any failures. The alignment of the |
| returned value is the same as the alignment of the stack itself |
| |
| .. c:function:: void up_release_stack(FAR struct tcb_s *dtcb) |
| |
| A task has been stopped. Free all stack related |
| resources retained int the defunct TCB. |
| |
| :param dtcb: The TCB containing information about the stack to be |
| released. |
| |
| :param ttype: The thread type. This may be one of following |
| (defined in ``include/nuttx/sched.h``): |
| |
| - ``TCB_FLAG_TTYPE_TASK``: Normal user task |
| - ``TCB_FLAG_TTYPE_PTHREAD``: User pthread |
| - ``TCB_FLAG_TTYPE_KERNEL``: Kernel thread |
| |
| This thread type is normally available in the flags field of |
| the TCB, however, there are certain error recovery contexts |
| where the TCB may not be fully initialized when |
| up_release_stack is called. |
| |
| If ``CONFIG_BUILD_PROTECTED`` or ``CONFIG_BUILD_KERNEL`` are |
| defined, then this thread type may affect how the stack is |
| freed. For example, kernel thread stacks may have been |
| allocated from protected kernel memory. Stacks for user tasks |
| and threads must have come from memory that is accessible to |
| user |
| |
| .. c:function:: void up_switch_context(FAR struct tcb_s *tcb, FAR struct tcb_s *rtcb) |
| |
| A task is currently in the ready-to-run list but has been preppe |
| to execute. Restore its context, and start execution. |
| |
| This function is called only from the NuttX scheduling logic. |
| Interrupts will always be disabled when this function is called. |
| |
| :param tcb: Refers to the head task of the ready-to-run list |
| which will be executed. |
| :param rtcb: Refers to the running task which will be blocked. |
| |
| .. c:macro:: noreturn_function |
| |
| .. c:function:: void up_exit(int status) noreturn_function; |
| |
| This function causes the currently executing task |
| to cease to exist. This is a special case of task_delete(). |
| |
| Unlike other UP APIs, this function may be called directly from |
| user programs in various states. The implementation of this |
| function should disable interrupts before performing scheduling |
| operations. |
| |
| .. c:function:: void up_dump_register(FAR void *dumpregs) |
| |
| Register dump may be handled in an |
| architecture-specific way. |
| |
| .. c:function:: void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver) |
| |
| This function is called by the OS when one or |
| more signal handling actions have been queued for execution. The |
| architecture specific code must configure things so that the |
| 'sigdeliver' callback is executed on the thread specified by 'tcb' |
| as soon as possible. |
| |
| This function may be called from interrupt handling logic. |
| |
| This operation should not cause the task to be unblocked nor |
| should it cause any immediate execution of sigdeliver. Typically, |
| a few cases need to be considered: |
| |
| #. This function may be called from an interrupt handler During |
| interrupt processing, all xcptcontext structures should be |
| valid for all tasks. That structure should be modified to |
| invoke sigdeliver() either on return from (this) interrupt or |
| on some subsequent context switch to the recipient task. |
| #. If not in an interrupt handler and the tcb is NOT the currently |
| executing task, then again just modify the saved xcptcontext |
| structure for the recipient task so it will invoke sigdeliver |
| when that task is later resumed. |
| #. If not in an interrupt handler and the tcb IS the currently |
| executing task -- just call the signal handler now. |
| |
| .. c:function:: void up_allocate_heap(FAR void **heap_start, size_t *heap_size) |
| |
| This function will be called to dynamically set |
| aside the heap region. |
| |
| For the kernel build (``CONFIG_BUILD_PROTECTED=y`` or |
| ``CONFIG_BUILD_KERNEL=y``) with both kernel- and user-space heaps |
| (``CONFIG_MM_KERNEL_HEAP=y``), this function provides the size of |
| the unprotected, user-space heap. If a protected kernel-space heap |
| is provided, the kernel heap must be allocated (and protected) by |
| an analogous ``up_allocate_kheap()``. |
| |
| .. c:function:: bool up_interrupt_context(void) |
| |
| Return true if we are currently executing in the |
| interrupt handler context. |
| |
| .. c:function:: void up_disable_irq(int irq) |
| |
| Disable the IRQ specified by 'irq' On many |
| architectures, there are three levels of interrupt enabling: (1) |
| at the global level, (2) at the level of the interrupt controller, |
| and (3) at the device level. In order to receive interrupts, they |
| must be enabled at all three levels. |
| |
| This function implements enabling of the device specified by 'irq' |
| at the interrupt controller level if supported by the architecture |
| (up_irq_save() supports the global level, the device level is |
| hardware specific). |
| |
| If the architecture does not support ``up_disable_irq``, |
| ``CONFIG_ARCH_NOINTC`` should be defined in the NuttX |
| configuration file. Since this API cannot be supported on all |
| architectures, it should be avoided in common implementations |
| where possible. |
| |
| .. c:function:: void up_enable_irq(int irq) |
| |
| This function implements disabling of the device |
| specified by 'irq' at the interrupt controller level if supported |
| by the architecture (up_irq_restore() supports the global level, |
| the device level is hardware specific). |
| |
| If the architecture does not support ``up_disable_irq``, |
| ``CONFIG_ARCH_NOINTC`` should be defined in the NuttX |
| configuration file. Since this API cannot be supported on all |
| architectures, it should be avoided in common implementations |
| where possible. |
| |
| .. c:function:: void up_prioritize_irq(int irq) |
| |
| Set the priority of an IRQ. |
| |
| If the architecture supports ``up_enable_irq``, |
| ``CONFIG_ARCH_IRQPRIO`` should be defined in the NuttX |
| configuration file. Since this API cannot be supported on all |
| architectures, it should be avoided in common implementations |
| where possible. |
| |
| .. c:function:: void up_putc(int ch) |
| |
| This is a debug interface exported by the |
| architecture-specific logic. Output one character on the console |
| |