|
|
In order to test performance of the system, core operation of the system has been evaluated. The goal of the test was to check performance of context switch between two threads.
The test consists of two threads and a semaphore. The first thread (higher priority) is waiting on the semaphore while the second one (lower priority) makes post operation on the semaphore. The semaphore is triggered and thread #1 is released. Delay was measured from os_sema_post() to os_sema_wait(), functions present respectively in the thread #2 and #1. Execution of testpoints in the code was signalled on output processor pins and recorded by logic analyser.
Id | Description | Debug signalling Thread# on pin | Switch interfered by Tick INTR | [cycles] | t / fosc=18MHz | t / fosc=25MHz |
1 | from os_sema_post_intr() to os_sema_wait() | no | no | 260 | 14.4us | 10.4us |
2 | from os_sema_post_intr() to os_sema_wait() | yes | no | 276 | 15.3us | 11.0us |
3 | from os_sema_post() to os_sema_wait() | no | no | 297 | 16.5us | 11.9us |
4 | from os_sema_post() to os_sema_wait() | yes | no | 312 | 17.3us | 12.5us |
5 | from os_sema_post() to os_sema_wait() interfered by tick isr (one timer running) | no | yes | 432 | 23.5us | 16.9us |
6 | Tick ISR load (no timers) | - | - | 102 | 5.6us | 4.1us |
7 | Tick ISR load, 1 timer, not elapsed | - | - | 115 | 6.4us | 4.6us |
Measurements were performed in the system compiled with following options: silicon_version=msp430x, large_code_model, opt_level=3.
The test was performed on MSP430F5438 and captured by logic analyser.
The system was configured to show context switch (CFG_DEBUG_PIN_THREADS),
so running thread can be recognized on the graph (SwTh1,SwTh0) as well as context switch points.
Legend - Annotated events on the graph
1. System Tick interrupt
2. Thread #2 is woken up from sleep
3. Testpoint just before os_sema_post() in thread #2
4. Context switch to thread #1
5. After return from os_sema_wait() in thread #1
6. Just before thread #1 enters os_sema_wait() again
7. context switch to thread #2
8. Thread #2 enters os_sleep()
The program contains required items for the test but also additional elements that helped to make measurements (i.e. "busy waiting" implemented by __delay_cycles, repetitive trigger from thread #1 achieved by os_sleep(), that holds its execution for a while). During the test system tick interrupt was present.
os_sema_t sema_a; //================= THREAD #1, High Priority ================ os_result_t thread1(void * args) { debug_pin_clr( D_THREAD1_RUN ); while(1) //infinite loop, { debug_pin_clr( D_THREAD1_RUN ); os_sema_wait( &sema_a );//waits for trigger from thread #2 debug_pin_set( D_THREAD1_RUN ); debug_pin_clr( D_THREAD2_POST ); __delay_cycles( 100 ); } } //================= THREAD #2, Low Priority ================ os_result_t thread2(void * args) { while(1) //infinite loop, { debug_pin_set( D_THREAD2_POST ); os_sema_post( &sema_a );//trigger thread #1 debug_pin_inv( D_CLK_CALIB ); os_sleep(100);//repeat trigger after 100ms } } //================== IDLE THREAD =========================== os_result_t thr_idle(void * args) { while(1) //infinite loop, { debug_pin_inv( D_IDLE );//invert D_IDLE pin (defined in debug_user.h pin 6) __delay_cycles(40); } }