#01 : NuttX 是什麼 ??
NuttX Real-Time Operating System
NuttX is a real-time operating system (RTOS) with an emphasis on standards compliance and small footprint. Scalable from 8-bit to 32-bit microcontroller environments, the primary governing standards in NuttX are Posix and ANSI standards. Additional standard APIs from Unix and other common RTOS's (such as VxWorks) are adopted for functionality not available under these standards, or for functionality that is not appropriate for deeply-embedded environments (such as fork()).
NuttX was first released in 2007 by under the permissive BSD license.
Nuttx 是一個實時嵌入式操作系統(RTOS),它有一個小巧是在微控制器的環境中使用。這是完全可擴展,從小型(8位)至中型嵌入式(32位)系統。它的目的還在於要完全符合標准,完全實時,並完全開放。
#02 : 硬體設備
TMR-FC 是一個開源硬體 (Open Source Hardware, OSHW) 開源電路圖及源碼, TMR-FC 板上具備 MPU6050 ( 3軸陀螺儀,3軸加速規 ) , HMC5883l 地磁 及 MS5611 大氣壓力等多種感測器, 使用 ST 義法半導體的 STM32F405RG ( ARM Cortex-M4) 的控制器, 板上具備 PWM 輸出入及超聲波模組介面, RF 介面, GPS 介面, 電流感測器介面, LED 控制介面, 等等. 其主要作為航空模型控制用途.
TMR-FC 電路圖( Schematic ) 下載連結 :
現在還是一人團隊, 自己一個在作, 希望找到好夥伴. 來信或留言.
#03 : Eclipse 設定
Version : Kepler Release
需要安裝 C/C++ GDB Hardware Debugging.
下面是跑 ostest 過程的詳細訊息,
tmrfc/ostest - > defconfig 裡需要做設定並重新編譯
#
# Debug Options#CONFIG_DEBUG=y( TMR-FC Side )
輸出訊息導向 USART1, 並透過藍芽模組開始傳送資料.
(PC Side)
電腦藍芽跟TMR-FC 上的藍芽模組配對後可得到虛擬 com port ( example com3 to be found on my PC ) , 使用 terminal 打開 com3, baud rate 設定 11520 即可開始接收資料.
ABCDFstdio_test: write fd=1stdio_test: Standard I/O Check: printfstdio_test: write fd=2stdio_test: Standard I/O Check: fprintf to stderrostest_main: Started user_main at PID=2ostest_main: Exittinguser_main: Begin argument testuser_main: Started with argc=5user_main: argv[0]="ostest"user_main: argv[1]="Arg1"user_main: argv[2]="Arg2"user_main: argv[3]="Arg3"user_main: argv[4]="Arg4"End of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: /dev/null testdev_null: Read 0 bytes from /dev/nulldev_null: Wrote 1024 bytes to /dev/nullEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: task_restart testTest task_restart()restart_main: Started restart_main at PID=3restart_main: Started with argc=4restart_main: argv[0]="ostest"restart_main: argv[1]="This is argument 1"restart_main: argv[2]="Argument 2 here"restart_main: argv[3]="Lastly, the 3rd argument"restart_main: I am still hererestart_main: I am still hererestart_main: Started with argc=4restart_main: argv[0]="ostest"restart_main: argv[1]="This is argument 1"restart_main: argv[2]="Argument 2 here"restart_main: argv[3]="Lastly, the 3rd argument"restart_main: ExittingEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: mutex testInitializing mutexStarting thread 1Starting thread 2 Thread1 Thread2 Loops 32 32 Errors 0 0End of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: cancel testcancel_test: Test 1: Normal Cancelationcancel_test: Starting threadstart_thread: Initializing mutexstart_thread: Initializing condstart_thread: Starting threadthread_waiter: Taking mutexthread_waiter: Starting wait for conditionstart_thread: Yieldingcancel_test: Canceling threadcancel_test: Joiningcancel_test: waiter exited with result=ffffffffcancel_test: PASS thread terminated with PTHREAD_CANCELEDcancel_test: Test 2: Cancelation of detached threadcancel_test: Re-starting threadrestart_thread: Destroying condrestart_thread: Destroying mutexrestart_thread: Re-starting threadstart_thread: Initializing mutexstart_thread: Initializing condstart_thread: Starting threadthread_waiter: Taking mutexthread_waiter: Starting wait for conditionstart_thread: Yieldingcancel_test: Canceling threadcancel_test: Joiningcancel_test: PASS pthread_join failed with status=ESRCHcancel_test: Test 3: Non-cancelable threadscancel_test: Re-starting thread (non-cancelable)restart_thread: Destroying condrestart_thread: Destroying mutexrestart_thread: Re-starting threadstart_thread: Initializing mutexstart_thread: Initializing condstart_thread: Starting threadthread_waiter: Taking mutexthread_waiter: Starting wait for conditionthread_waiter: Setting non-cancelablestart_thread: Yieldingcancel_test: Canceling threadcancel_test: Joiningthread_waiter: Releasing mutexthread_waiter: Setting cancelablecancel_test: waiter exited with result=ffffffffcancel_test: PASS thread terminated with PTHREAD_CANCELEDEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: semaphore testsem_test: Initializing semaphore to 0sem_test: Starting waiter thread 1sem_test: Set thread 1 priority to 191waiter_func: Thread 1 Startedwaiter_func: Thread 1 initial semaphore value = 0waiter_func: Thread 1 waiting on semaphoresem_test: Starting waiter thread 2sem_test: Set thread 2 priority to 128waiter_func: Thread 2 Startedwaiter_func: Thread 2 initial semaphore value = -1waiter_func: Thread 2 waiting on semaphoresem_test: Starting poster thread 3sem_test: Set thread 3 priority to 64poster_func: Thread 3 startedposter_func: Thread 3 semaphore value = -2poster_func: Thread 3 posting semaphorewaiter_func: Thread 1 awakenedwaiter_func: Thread 1 new semaphore value = -1waiter_func: Thread 1 doneposter_func: Thread 3 new semaphore value = -1poster_func: Thread 3 semaphore value = -1poster_func: Thread 3 posting semaphorewaiter_func: Thread 2 awakenedwaiter_func: Thread 2 new semaphore value = 0waiter_func: Thread 2 doneposter_func: Thread 3 new semaphore value = 0poster_func: Thread 3 doneEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: condition variable testcond_test: Initializing mutexcond_test: Initializing condcond_test: Starting waitercond_test: Set thread 1 priority to 128waiter_thread: Startedcond_test: Starting signalercond_test: Set thread 2 priority to 64thread_signaler: Startedthread_signaler: Terminatingcond_test: signaler terminated, now cancel the waitercond_test: Waiter Signalercond_test: Loops 32 32cond_test: Errors 0 0cond_test:cond_test: 0 times, waiter did not have to wait for datacond_test: 0 times, data was already available when the signaler runcond_test: 0 times, the waiter was in an unexpected state when the signaler ranEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: timed wait testthread_waiter: Initializing mutextimedwait_test: Initializing condtimedwait_test: Starting waitertimedwait_test: Set thread 2 priority to 177thread_waiter: Taking mutexthread_waiter: Starting 5 second wait for conditiontimedwait_test: Joiningthread_waiter: pthread_cond_timedwait timed outthread_waiter: Releasing mutexthread_waiter: Exit with status 0x12345678timedwait_test: waiter exited with result=12345678End of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: message queue testmqueue_test: Starting receivermqueue_test: Set receiver priority to 128receiver_thread: Startingmqueue_test: Starting sendermqueue_test: Set sender thread priority to 64mqueue_test: Waiting for sender to completesender_thread: Startingreceiver_thread: mq_receive succeeded on msg 0sender_thread: mq_send succeeded on msg 0receiver_thread: mq_receive succeeded on msg 1sender_thread: mq_send succeeded on msg 1receiver_thread: mq_receive succeeded on msg 2sender_thread: mq_send succeeded on msg 2receiver_thread: mq_receive succeeded on msg 3sender_thread: mq_send succeeded on msg 3receiver_thread: mq_receive succeeded on msg 4sender_thread: mq_send succeeded on msg 4receiver_thread: mq_receive succeeded on msg 5sender_thread: mq_send succeeded on msg 5receiver_thread: mq_receive succeeded on msg 6sender_thread: mq_send succeeded on msg 6receiver_thread: mq_receive succeeded on msg 7sender_thread: mq_send succeeded on msg 7receiver_thread: mq_receive succeeded on msg 8sender_thread: mq_send succeeded on msg 8receiver_thread: mq_receive succeeded on msg 9sender_thread: mq_send succeeded on msg 9sender_thread: returning nerrors=0mqueue_test: Killing receiverreceiver_thread: mq_receive interrupted!receiver_thread: returning nerrors=0mqueue_test: Canceling receivermqueue_test: receiver has already terminatedEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: timed message queue testtimedmqueue_test: Starting sendersender_thread: Startingsender_thread: mq_timedsend succeeded on msg 0sender_thread: mq_timedsend succeeded on msg 1sender_thread: mq_timedsend succeeded on msg 2sender_thread: mq_timedsend succeeded on msg 3sender_thread: mq_timedsend succeeded on msg 4sender_thread: mq_timedsend succeeded on msg 5sender_thread: mq_timedsend succeeded on msg 6sender_thread: mq_timedsend succeeded on msg 7sender_thread: mq_timedsend succeeded on msg 8timedmqueue_test: Waiting for sender to completesender_thread: mq_timedsend 9 timed out as expectedsender_thread: returning nerrors=0timedmqueue_test: Starting receiverreceiver_thread: Startingreceiver_thread: mq_timedreceive succeeded on msg 0receiver_thread: mq_timedreceive succeeded on msg 1receiver_thread: mq_timedreceive succeeded on msg 2receiver_thread: mq_timedreceive succeeded on msg 3receiver_thread: mq_timedreceive succeeded on msg 4receiver_thread: mq_timedreceive succeeded on msg 5receiver_thread: mq_timedreceive succeeded on msg 6receiver_thread: mq_timedreceive succeeded on msg 7receiver_thread: mq_timedreceive succeeded on msg 8timedmqueue_test: Waiting for receiver to completereceiver_thread: Receive 9 timed out as expectedreceiver_thread: returning nerrors=0timedmqueue_test: Test completeEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: signal handler testsighand_test: Initializing semaphore to 0sighand_test: Starting waiter tasksighand_test: Started waiter_main pid=21waiter_main: Waiter startedwaiter_main: Unmasking signal 17waiter_main: Registering signal handlerwaiter_main: oact.sigaction=0 oact.sa_flags=0 oact.sa_mask=0waiter_main: Waiting on semaphoresighand_test: Signaling pid=21 with signo=17 sigvalue=42wakeup_action: Received signal 17wakeup_action: sival_int=42wakeup_action: si_code=1wakeup_action: ucontext=0waiter_main: sem_wait() successfully interrupted by signalwaiter_main: donesighand_test: doneEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: POSIX timer testtimer_test: Initializing semaphore to 0timer_test: Unmasking signal 17timer_test: Registering signal handlertimer_test: oact.sigaction=0 oact.sa_flags=0 oact.sa_mask=0timer_test: Creating timertimer_test: Starting timertimer_test: Waiting on semaphoretimer_expiration: Received signal 17timer_expiration: sival_int=42timer_expiration: si_code=2 (SI_TIMER)timer_expiration: ucontext=0timer_test: sem_wait() successfully interrupted by signaltimer_test: g_nsigreceived=1timer_test: Waiting on semaphoretimer_expiration: Received signal 17timer_expiration: sival_int=42timer_expiration: si_code=2 (SI_TIMER)timer_expiration: ucontext=0timer_test: sem_wait() successfully interrupted by signaltimer_test: g_nsigreceived=2timer_test: Waiting on semaphoretimer_expiration: Received signal 17timer_expiration: sival_int=42timer_expiration: si_code=2 (SI_TIMER)timer_expiration: ucontext=0timer_test: sem_wait() successfully interrupted by signaltimer_test: g_nsigreceived=3timer_test: Waiting on semaphoretimer_expiration: Received signal 17timer_expiration: sival_int=42timer_expiration: si_code=2 (SI_TIMER)timer_expiration: ucontext=0timer_test: sem_wait() successfully interrupted by signaltimer_test: g_nsigreceived=4timer_test: Waiting on semaphoretimer_expiration: Received signal 17timer_expiration: sival_int=42timer_expiration: si_code=2 (SI_TIMER)timer_expiration: ucontext=0timer_test: sem_wait() successfully interrupted by signaltimer_test: g_nsigreceived=5timer_test: Deleting timertimer_test: doneEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: round-robin scheduler testrr_test: Set thread priority to 1rr_test: Set thread policy to SCHED_RRrr_test: Starting first get_primes_thread First get_primes_thread: 22rr_test: Starting second get_primes_threadget_primes_thread id=1 started, looking for primes < 10000, doing 10 run(s) Second get_primes_thread: 23rr_test: Waiting for threads to complete -- this should take awhile If RR scheduling is working, they should start and complete at about the same timeget_primes_thread id=2 started, looking for primes < 10000, doing 10 run(s)get_primes_thread id=1 finished, found 1230 primes, last one was 9973get_primes_thread id=2 finished, found 1230 primes, last one was 9973rr_test: DoneEnd of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: barrier testbarrier_test: Initializing barrierbarrier_func: Thread 0 startedbarrier_test: Thread 0 createdbarrier_func: Thread 1 startedbarrier_test: Thread 1 createdbarrier_func: Thread 2 startedbarrier_test: Thread 2 createdbarrier_func: Thread 0 calling pthread_barrier_wait()barrier_func: Thread 1 calling pthread_barrier_wait()barrier_func: Thread 2 calling pthread_barrier_wait()barrier_func: Thread 2, back with status=PTHREAD_BARRIER_SERIAL_THREAD (I AM SPECIAL)barrier_func: Thread 0, back with status=0 (I am not special)barrier_func: Thread 1, back with status=0 (I am not special)barrier_func: Thread 2 donebarrier_func: Thread 0 donebarrier_func: Thread 1 donebarrier_test: Thread 0 completed with result=0barrier_test: Thread 1 completed with result=0barrier_test: Thread 2 completed with result=0End of test memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0Final memory usage:VARIABLE BEFORE AFTER======== ======== ========arena 2f140 2f140ordblks 3 3mxordblk 1e840 1e840uordblks 1870 1870fordblks 2d8d0 2d8d0user_main: Exitting
--External Tool 設定--
其他頁面設定同步驟 1 )
--除錯介面 --
--Debug Configurations 設定--
環境架設好後相當好用, 對 Nuttx 也可以開始深入了解, 最重要的是可以很自由的設定斷點來一窺究竟. 日後加入的程式碼也可以同此操作.
做完後會發現對於其他的 ARM 平台只要 Jlink 有支援都可以用這一招在 Eclipse 裡做編譯除錯. 管用!!
#04 : USB Composite ( CDC+ MSC )在 Nuttx 的實現
在 defconfig 中的除錯項目設定. 設定 debug symbols 後才能對應到 C code, 否則只能看組譯程式碼.
## Debug Options#CONFIG_DEBUG=yCONFIG_DEBUG_SYMBOLS=yCONFIG_DEBUG_VERBOSE=yCONFIG_DEBUG_USB=y
CDC : Communication Device Class ( VCP : Virtual COM Port)
今天試了一下沒能成功... 希望有高手可以幫忙看一下..感謝, 下面是輸出的 Log
ABCDFconn_main: Performing architecture-specific intializationcomposite_archinitialize: Initializing SDIO slot 0composite_archinitialize: Bind SDIO to the MMC/SD driver, minor=0composite_archinitialize: Successfully bound SDIO to the MMC/SD driverboard_cdcclassobject: Initializing USB serial driveruart_register: Registering /dev/ttyACM0board_mscclassobject: Configuring with NLUNS=1board_mscclassobject: MSC handle=10001ed0board_mscclassobject: Bind LUN=0 to /dev/mmcsd0Assertion failed at file:usbdev/usbmsc.c line: 422 task: initsp: 10001a30stack base: 10001b48stack size: 000007fc10001a20: 10001a20 10001a20 10001a40 08009985 00000000 00000000 10001a40 080015f110001a40: 10001a30 10000f80 000007fc 10001b48 10001a58 08001665 000001a6 08019cb810001a60: 00010000 10000f80 10001a70 0800e7e9 2000045c 10001f64 00001a80 0000004010001a80: 00000005 2000045c 10001ed0 0f260000 00011a98 08009985 10001aa0 0800e76f10001aa0: 2000045c 10001f64 00000000 10001c64 00601ab8 10001ed0 00000004 ffffffed10001ac0: 00001ac8 00000000 10001ad0 08012005 2000045c 10001bd4 10001bc0 0000000010001ae0: 10001ae8 0800a541 00000000 10001bd4 00000008 2000045c 10001b00 0801270d10001b00: 00000000 10001bd4 10001bc0 10001bc0 10001b18 0800b131 10001064 0000000110001b20: 00000000 00000000 10001b30 08002169 00000000 00000000 10000f80 0000000110001b40: 00000000 00000000 00000000 00000000 00000000 00000000 00000030 80000810
Updated : 2013/07/08
USB composite MSC 部分已經可以正常讀寫小檔案, 寫大檔案會有 CRC failed, 這個問題待解決.
如果要測試的話請使用有加入 Composite MSC 修改之後的版本.
Updated : 2013/07/010
USB Composite CDC/ACM 測試終於成功了!!
under construction
#05 : PWM driver for input capture and output
under construction
#06 : Flight Control