版本 d64f182bd17ff03810e9f1d6f6b295c7643a3c6a
Changes from d64f182bd17ff03810e9f1d6f6b295c7643a3c6a to 05721ec9093560c24df9f49699d07b617e0cd081
---
title: nuttx
categories: embedded, arm, stm32, stm32f429
toc: no
...
組員
----
* 翁振育
* 黃亮穎
* 蘇偉嘉
* 李英碩
hackpad : https://stm32f429.hackpad.com/NuttX--hqco2YSgAcJ
Nuttx 參考應用
---------------
* `PX4 autopilot<http://pixhawk.org/dev/nuttx/start>`_
NuttX 架構
------------
* 可混用task跟thread。
* 支援FPU。
* 可混用FIFO跟RR。
與平台相關
------------
Run Nuttx on STM32F429-Disco
----------------------------------------------
| (1) 從 https://github.com/deadbeefcafe/nuttx-stm32f4disc-bb 複製Nuttx到workspace
| (2) cd workspace/nuttx-stm32f4disc-bb/nuttx/tools
| (3) ./configure.sh stm32f429i-disco/nsh
| (4) cd ..
| (5) make CROSSDEV=arm-none-eabi-
| (6) st-flash write nuttx.bin 0x8000000
| (7) sudo screen /dev/ttyUSB0 115200 8n1
設定相關應用程式與功能
------------------
| at stm32f429i-disco/nsh/defconfig
| 120 CONFIG_ARCH_FPU=n
| 465 CONFIG_RTC=y
| 466 CONFIG_RTC_DATETIME=y
| 653 CONFIG_EXAMPLES_HELLO=y
| 676 CONFIG_EXAMPLES_OSTEST=y
Task Control Interfaces
-----------------------
- task_create : 產生一個activates的新task,並回傳系統指派的pid
- task_init : 將task的TCB初始化,但並不activate task
- task_activate : activate task,否則scheduler沒辦法執行它
- task_delete : 將task關掉,並deallocate它的TCB與stack
- task_exit : 關掉目前在運行的task,不能在user mode被呼叫
Task state
------------
include/nuttx/sched.h
.. code-block:: c
enum tstate_e
{
TSTATE_TASK_INVALID = 0, /* INVALID - The TCB is uninitialized */
TSTATE_TASK_PENDING, /* READY_TO_RUN - Pending preemption unlock */
TSTATE_TASK_READYTORUN, /* READY-TO-RUN - But not running */
TSTATE_TASK_RUNNING, /* READY_TO_RUN - And running */
TSTATE_TASK_INACTIVE, /* BLOCKED - Initialized but not yet activated */
TSTATE_WAIT_SEM, /* BLOCKED - Waiting for a semaphore */
#ifndef CONFIG_DISABLE_SIGNALS
TSTATE_WAIT_SIG, /* BLOCKED - Waiting for a signal */
#endif
#ifndef CONFIG_DISABLE_MQUEUE
TSTATE_WAIT_MQNOTEMPTY, /* BLOCKED - Waiting for a MQ to become not empty. */
TSTATE_WAIT_MQNOTFULL, /* BLOCKED - Waiting for a MQ to become not full. */
#endif
#ifdef CONFIG_PAGING
TSTATE_WAIT_PAGEFILL, /* BLOCKED - Waiting for page fill */
#endif
NUM_TASK_STATES /* Must be last */
};
Task list
------------
sched/os_internal.h
.. code-block:: c
typedef struct tasklist_s tasklist_t;
extern volatile dq_queue_t g_pendingtasks;
extern volatile dq_queue_t g_waitingforsemaphore;
#ifndef CONFIG_DISABLE_SIGNALS
extern volatile dq_queue_t g_waitingforsignal;
#endif
#ifndef CONFIG_DISABLE_MQUEUE
extern volatile dq_queue_t g_waitingformqnotempty;
#endif
#ifndef CONFIG_DISABLE_MQUEUE
extern volatile dq_queue_t g_waitingformqnotfull;
#endif
#ifdef CONFIG_PAGING
extern volatile dq_queue_t g_waitingforfill;
#endif
extern volatile dq_queue_t g_inactivetasks;
extern volatile sq_queue_t g_delayed_kufree;
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
extern volatile sq_queue_t g_delayed_kfree;
#endif
extern volatile pid_t g_lastpid;
extern pidhash_t g_pidhash[CONFIG_MAX_TASKS];
extern const tasklist_t g_tasklisttable[NUM_TASK_STATES];
TCB
------------
include/nuttx/sched.h
.. code-block:: c
struct tcb_s
{
/* Fields used to support list management *************************************/
FAR struct tcb_s *flink; /* Doubly linked list */
FAR struct tcb_s *blink;
/* Task Management Fields *****************************************************/
pid_t pid; /* This is the ID of the thread */
start_t start; /* Thread start function */
entry_t entry; /* Entry Point into the thread */
uint8_t sched_priority; /* Current priority of the thread */
uint8_t task_state; /* Current state of the thread */
uint16_t flags; /* Misc. general status flags */
int16_t lockcount; /* 0=preemptable (not-locked) */
#if CONFIG_RR_INTERVAL > 0
int timeslice; /* RR timeslice interval remaining */
#endif
/* Stack-Related Fields *******************************************************/
#ifndef CONFIG_CUSTOM_STACK
size_t adj_stack_size; /* Stack size after adjustment */
/* for hardware, processor, etc. */
/* (for debug purposes only) */
FAR void *stack_alloc_ptr; /* Pointer to allocated stack */
/* Need to deallocate stack */
FAR void *adj_stack_ptr; /* Adjusted stack_alloc_ptr for HW */
/* The initial stack pointer value */
#endif
/* POSIX Semaphore Control Fields *********************************************/
sem_t *waitsem; /* Semaphore ID waiting on */
/* POSIX Signal Control Fields ************************************************/
#ifndef CONFIG_DISABLE_SIGNALS
sigset_t sigprocmask; /* Signals that are blocked */
sigset_t sigwaitmask; /* Waiting for pending signals */
sq_queue_t sigactionq; /* List of actions for signals */
sq_queue_t sigpendactionq; /* List of pending signal actions */
sq_queue_t sigpostedq; /* List of posted signals */
siginfo_t sigunbinfo; /* Signal info when task unblocked */
#endif
/* POSIX Named Message Queue Fields *******************************************/
#ifndef CONFIG_DISABLE_MQUEUE
FAR msgq_t *msgwaitq; /* Waiting for this message queue */
#endif
/* The form and content of these fields are processor-specific. */
struct xcptcontext xcp; /* Interrupt register save area */
#if CONFIG_TASK_NAME_SIZE > 0
char name[CONFIG_TASK_NAME_SIZE]; /* Task name */
#endif
:
:
:
:
:
:
};
Register
---------
.. image:: /ARM_register.jpg
Communication
---------------------
Scheduling
----------------
include/sys/types.h
.. code-block:: c
/* HPUX-like MIN/MAX value */
#define PRIOR_RR_MIN 0
#define PRIOR_RR_MAX 255
#define PRIOR_FIFO_MIN 0
#define PRIOR_FIFO_MAX 255
#define PRIOR_OTHER_MIN 0 /* Not use */
#define PRIOR_OTHER_MAX 255 /* Not use */
/* Scheduling Priorities. NOTE: Only the idle task can take
* the true minimum priority. */
#define SCHED_PRIORITY_MAX 255
#define SCHED_PRIORITY_DEFAULT 100
#define SCHED_PRIORITY_MIN 1
#define SCHED_PRIORITY_IDLE 0
| 1. RR 時間間隔是 20 ticks 做一次 context switch。
| 觀看每個設定time slice的相關檔案其運算是皆為 timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK
| 在 nuttx/include/nuttx/config.h 中
| CONFIG_RR_INTERVAL = 200
| MSEC_PER_TICK = 10
| 2. 若要禁止 context switch,可用sched_lock()
| 此區禁止 context switch
| sched_unlock()用在修改scheduler和priority。
| 3. 若要先將 timer interrupt 暫停,可用saved_state = irqsave();
| 此區暫停 timer interrupt
| irqrestore(saved_state);
| 用在修改 scheduler。
| 注意:timer interrupt 跟 context switch 是不同系統。
| 4. Nuttx 只有兩個 scheduler policy,其 tcb->timeslice = 0 則表示FIFO, 非0則為RR。
Interrupt handler
------------------------
IRQ numbers
.. code-block:: c
#define STM32_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */
/* Vector 0: Reset stack pointer value */
/* Vector 1: Reset (not handler as an IRQ) */
#define STM32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
#define STM32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
#define STM32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
#define STM32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
#define STM32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
#define STM32_IRQ_SVCALL (11) /* Vector 11: SVC call */
#define STM32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
/* Vector 13: Reserved */
#define STM32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
#define STM32_IRQ_SYSTICK (15) /* Vector 15: System tick */
測試環境架設
------------
硬體驅動原理
------------
* `UART<embedded/USART>`_
* FPU (Floating Point Unit)
效能表現
--------
參考資料
--------
* https://github.com/deadbeefcafe/nuttx-stm32f4disc-bb
* http://bibliodigital.itcr.ac.cr/xmlui/bitstream/handle/2238/3051/FinalReport.pdf