=====================================================
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:function:: void up_release_pending(void)

  When tasks become ready-to-run but cannot run
  because pre-emption is disabled, they are placed into a pending
  task list. This function releases and makes ready-to-run all of
  the tasks that have collected in the pending task list. This can
  cause a context switch if a new task is placed at the head of the
  ready to run list.

  This function is called only from the NuttX scheduling logic when
  pre-emption is re-enabled. Interrupts will always be disabled when
  this function is called.

.. 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_assert(FAR const char *filename, int linenum)

  Assertions 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::  int up_putc(int ch)

  This is a debug interface exported by the
  architecture-specific logic. Output one character on the console

