Friday, March 3, 2017

[Note] GDB 一些指令功能速查

[Note] GDB 一些指令功能速查

前情提要

這篇主要是介紹gdb的一些常用功能,遇到的時候方便google。

常用功能

  • backtrace
  • breakpoint
  • watchpoint
  • stopwatch
  • dump register
  • dump variable
  • continue and stop
  • disasmmebly
  • return

指令速查

  • backtrace
    • bt
  • breakpoint
    • b
    • br
  • watchpoint
    • watch variable_name or watch variable_address
  • stopwatch
  • dump register
    • info r
  • dump variable
    • print variable_name
    • print &variable_name => get address
    • print *variable_address => get address contents
    • info display
  • continue and stop
    • c => continue
    • r= > run
    • stop => Ctrl+c
  • disasmmebly
    • disassemble (func…) link
    • layout asm
    • layout src
  • return
    • return (return this stack)

Written with StackEdit.

Saturday, February 18, 2017

L3G4200 gyroscope使用筆記

L3G4200 gyroscope使用筆記

特性與參數

  • 用途:量測姿態
  • 精度:250/500/2000 dps (degree per second)
  • 輸出資料:為angular rate(角速度) ,16bit
  • 原始感應器電壓(僅有晶片):2.4V ~3.6V
  • 模組(GY50)電壓:3~5V
  • 其他特色:有內建high pass filter和low pass filter可供程式選擇,還有中斷信號選擇
  • 通信方式:I2C/SPIs
  • 晶片datasheet:連結在此
  • 模組(GY50)購買網頁:連結在此

用此模組量測當前姿態方式

軟體部份

Ardunio先安裝wire library和L3G4200D
用這個網站上的code和library即可。

角速度轉成角度

由於該感測器輸出為角速度(離散資料),所以我們須將角速度做離散積分得到角度。
角度 = 初始角度 + (角速度*取樣時間的總和)
下圖為利用QT自製的視覺化工具。其中若要得到角度責須得到線與0軸的面積。



下圖為L3G4200 datasheet p.10 一小部份,其中Sensitivity代表精度,以FS=200dps為例,代表從感測器輸出的數字1代表8.75mdps,如果輸出為兩千時,當前角速度為2000*8.75/1000000dps = 0.0175 dps。

應用限制與誤差處理

由於是作離散積分所以會有誤差,最好使用濾波器(有內建)。
另外由於它需要一直取樣,對Master CPU來說是很大的負擔。
Written with StackEdit.

Friday, January 13, 2017

Valgrind:C/C++分析工具

Valgrind:C/C++分析工具

Valgrind是開源的測試框架,可以用來動態分析記憶體配置、快取使用、多執行序bug。

安裝

sudo pacman -Sy valgrind

基本用法

$ valgrind 程式名稱 args
預設會是用memcheck工具分析,在這個工具下她會匯出heap使用、memory leak、還有記憶體使用錯誤的部份backtrace。

進階用法

$ valgrind --tool=toolname 程式名稱 args
這是valgrind最有方便的地方,valgrind旗下有九個使用者端的工具,和幾個開發者工具。

1. Memcheck:記憶體錯誤分析工具。

2.Cachegrind:預測你的cache使用。

3.Callgrind:分析程式的function call次數,還有call graph,可以幫助快取分析。

4.Helgrind:多執行序錯誤分析工具,有race condition檢測功能。

5.DRD:另一個多執行序分析工具。

6.Massif:分析heap的使用,在一個程式執行中她會測量多次。

7.DHAT:另一種heap分析工具。

8.SGcheck:實驗性的全域變數與stack分析工具。

9.BBV:實驗性SimPoint相關工具。

這些工具比較常用的是前七個。接下來看一下個別的使用。

memcheck

$ valgrind --tool=memcheck 程式名稱 args
首先我先寫一個廢物code來做實驗。以下code new完之後沒有delete。
#include<iostream>
using namespace std;
int main()
{
    int *ptr;
    ptr = new int;
    *ptr = 2;
    cout << *ptr << endl;
}
然後我們來看一下分析結果。
==12313== Memcheck, a memory error detector
==12313== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==12313== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==12313== Command: ./garbage
==12313==
2
==12313==
==12313== HEAP SUMMARY:
==12313== in use at exit: 4 bytes in 1 blocks
==12313== total heap usage: 3 allocs, 2 frees, 73,732 bytes allocated
==12313==
==12313== LEAK SUMMARY:
==12313== definitely lost: 4 bytes in 1 blocks
==12313== indirectly lost: 0 bytes in 0 blocks
==12313== possibly lost: 0 bytes in 0 blocks
==12313== still reachable: 0 bytes in 0 blocks
==12313== suppressed: 0 bytes in 0 blocks
==12313== Rerun with --leak-check=full to see details of leaked memory
==12313==
==12313== For counts of detected and suppressed errors, rerun with: -v
==12313== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

她寫了definitely lost: 4 bytes in 1 blocks,int是4 byte,我new完之後沒有回收所以memory leak了4 byte,不過由於這程式很間單所以很好找到錯誤來源,當程式變得複雜時我們可以加上--leak-check=full來找到源頭,來看一加完的結果。
==14268== Memcheck, a memory error detector
==14268== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14268== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==14268== Command: ./garbage
==14268==
2
==14268==
==14268== HEAP SUMMARY:
==14268== in use at exit: 4 bytes in 1 blocks
==14268== total heap usage: 3 allocs, 2 frees, 73,732 bytes allocated
==14268==
==14268== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==14268== at 0x4C2B1EC: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14268== by 0x4007C7: main (in /home/tommycc/garbage)
==14268==
==14268== LEAK SUMMARY:
==14268== definitely lost: 4 bytes in 1 blocks
==14268== indirectly lost: 0 bytes in 0 blocks
==14268== possibly lost: 0 bytes in 0 blocks
==14268== still reachable: 0 bytes in 0 blocks
==14268== suppressed: 0 bytes in 0 blocks
==14268==
==14268== For counts of detected and suppressed errors, rerun with: -v
==14268== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
可以發現這兩行,指出了錯誤點。
==14268== at 0x4C2B1EC: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14268== by 0x4007C7: main (in /home/tommycc/garbage)

Cachegrind

$valgrind --tool=cachegrind
它可以分析你程式的快取優化程度。它的結果總共有以下類別。以下擷取至valgrind manual
  • I cache reads (Ir, which equals the number of instructions executed), I1 cache read misses (I1mr) and LL cache instruction read misses (ILmr).
  • D cache reads (Dr, which equals the number of memory reads), D1 cache read misses (D1mr), and LL cache data read misses (DLmr).
  • D cache writes (Dw, which equals the number of memory writes), D1 cache write misses (D1mw), and LL cache data write misses (DLmw).
  • Conditional branches executed (Bc) and conditional branches mispredicted (Bcm).
  • Indirect branches executed (Bi) and indirect branches mispredicted (Bim).
一般來說I和D是首要分析的部份。以下的範例是二維陣列存取,我們都知道二維陣列在記憶體上其實是一維的,所以(row major)先row在column會比(column major)先column在row快。我們先執行row major的code如以下。
 for (int i = 0 ; i < 1000 ; i++ ){                                                                    
     for (int j = 0 ; j < 1000 ; j++ ){                                      
         a[i][j] = i+j;                                                      
     }                                                                       
 } 
結果如下。
==11719== Cachegrind, a cache and branch-prediction profiler
==11719== Copyright (C) 2002-2015, and GNU GPL'd, by Nicholas Nethercote et al.
==11719== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==11719== Command: ./tt
==11719== 
--11719-- warning: L3 cache found, using its data for the LL simulation.
==11719== 
==11719== I   refs:      16,204,946
==11719== I1  misses:         1,401
==11719== LLi misses:         1,357
==11719== I1  miss rate:       0.01%
==11719== LLi miss rate:       0.01%
==11719== 
==11719== D   refs:       7,729,575  (6,536,262 rd   + 1,193,313 wr)
==11719== D1  misses:        78,407  (   13,698 rd   +    64,709 wr)
==11719== LLd misses:        71,617  (    7,734 rd   +    63,883 wr)
==11719== D1  miss rate:        1.0% (      0.2%     +       5.4%  )
==11719== LLd miss rate:        0.9% (      0.1%     +       5.4%  )
==11719== 
==11719== LL refs:           79,808  (   15,099 rd   +    64,709 wr)
==11719== LL misses:         72,974  (    9,091 rd   +    63,883 wr)
==11719== LL miss rate:         0.3% (      0.0%     +       5.4%  )
特別注意D1 miss rate是1.0%。接下來是column major的code,如下。
for (int i = 0 ; i < 1000 ; i++ ){                                                            
    for (int j = 0 ; j < 1000 ; j++ ){                                                              
        a[j][i] = i+j;                                                                        
    }                                                                                               
}       
結果如下。
==11522== Cachegrind, a cache and branch-prediction profiler
==11522== Copyright (C) 2002-2015, and GNU GPL'd, by Nicholas Nethercote et al.
==11522== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==11522== Command: ./tt
==11522== 
--11522-- warning: L3 cache found, using its data for the LL simulation.
==11522== 
==11522== I   refs:      16,204,946
==11522== I1  misses:         1,401
==11522== LLi misses:         1,357
==11522== I1  miss rate:       0.01%
==11522== LLi miss rate:       0.01%
==11522== 
==11522== D   refs:       7,729,575  (6,536,262 rd   + 1,193,313 wr)
==11522== D1  misses:     1,015,906  (   13,698 rd   + 1,002,208 wr)
==11522== LLd misses:        71,617  (    7,734 rd   +    63,883 wr)
==11522== D1  miss rate:       13.1% (      0.2%     +      84.0%  )
==11522== LLd miss rate:        0.9% (      0.1%     +       5.4%  )
==11522== 
==11522== LL refs:        1,017,307  (   15,099 rd   + 1,002,208 wr)
==11522== LL misses:         72,974  (    9,091 rd   +    63,883 wr)
==11522== LL miss rate:         0.3% (      0.0%     +       5.4%  )
可以發現D1 miss rate大幅上升至13.1%。另外cachegrind一樣會產生output file,可以透過cg_annotate分析,或是用Kcahcegrind分析。

Callgrind

用來分析整個程式的function call數目。
$valgrind --tool=callgrind 程式名稱
這會開始執行你的程式,通常會執行的比較慢。在執行過程中,你可以透過$callgrind_control -e -b或是$callgrind_control -b 來看程式當下執行的function call backtrace。以下是費氏數列遞迴版結果。
    PID 6989: ./fb
sending command status internal to pid 6989

  Totals:           Ir 
   Th 1  2,560,275,485 

  Frame:             Ir Backtrace for Thread 1
   [ 0]  23,685,553,356 fb(long long) (58138276 x)
   [ 1]  41,379,358,433 fb(long long) (58138297 x)
   [ 2]  41,379,358,449 fb(long long) (58138297 x)
   [ 3]  41,379,358,465 fb(long long) (58138297 x)
   [ 4]  41,379,358,481 fb(long long) (58138297 x)
   [ 5]  41,379,358,497 fb(long long) (58138297 x)
   [ 6]  41,379,358,513 fb(long long) (58138297 x)
   [ 7]  41,379,358,529 fb(long long) (58138297 x)
   [ 8]  41,379,358,545 fb(long long) (58138297 x)
   [ 9]  23,685,553,523 fb(long long) (58138276 x)
   [10]  41,379,364,892 fb(long long) (58138297 x)
   [11]  41,379,364,908 fb(long long) (58138297 x)
   [12]  41,379,364,924 fb(long long) (58138297 x)
   [13]  23,685,559,902 fb(long long) (58138276 x)
   [14]  23,685,630,165 fb(long long) (58138276 x)
   [15]  41,379,619,162 fb(long long) (58138297 x)
   [16]  41,379,619,178 fb(long long) (58138297 x)
   [17]  41,379,619,194 fb(long long) (58138297 x)
   [18]  41,379,619,210 fb(long long) (58138297 x)
   [19]  23,685,814,188 fb(long long) (58138276 x)
   [20]  41,382,920,321 fb(long long) (58138297 x)
   [21]  41,382,920,337 fb(long long) (58138297 x)
   [22]  23,689,115,315 fb(long long) (58138276 x)
   [23]  41,405,546,424 fb(long long) (58138297 x)
   [24]  41,405,546,440 fb(long long) (58138297 x)
   [25]  23,711,741,418 fb(long long) (58138276 x)
   [26]  41,560,627,883 fb(long long) (58138297 x)
   [27]  23,866,822,861 fb(long long) (58138276 x)
   [28]  24,523,758,344 fb(long long) (58138276 x)
   [29]  43,937,442,813 fb(long long) (58138297 x)
   [30]   2,558,084,449 fb(long long) (1 x)
   [31]   2,558,084,465 fb(long long) (1 x)
   [32]   2,558,084,472 main (1 x)
   [33]   2,558,187,428 (below main) (1 x)
   [34]   2,558,187,439 _start (1 x)
   [35]               . 0x0000000000000d70 
可以看到執行當下的遞迴到哪裡,不過由於費氏數列浮動快,這用callgrind_control -e -b的深度會不同。要看到整個function的呼叫次數,可以透過callgrind執行完產生的calgrind.out.pid檔案,這時有兩種分析這個檔案的方式,一是透過callgrind_annotate callgrind.out.pid 來看結果,另一是用KCachegrind (KDE應用程式)。以下是KCachegrind結果,可以看到左下角的框框,fb被call了1+331160280次(第一層call+第二層以上call)。


helgrind

$valgrind --tool=helgrind
這次我們使用官方範例。
#include <pthread.h>

int var = 0;

void* child_fn ( void* arg ) {
   var++; /* Unprotected relative to parent */ /* this is line 6 */
   return NULL;
}

int main ( void ) {
   pthread_t child;
   pthread_create(&child, NULL, child_fn, NULL);
   var++; /* Unprotected relative to child */ /* this is line 13 */
   pthread_join(child, NULL);
   return 0;
}
很明顯的var沒有做mutex lock,會有race。結果如下。
==19156== Helgrind, a thread error detector
==19156== Copyright (C) 2007-2015, and GNU GPL'd, by OpenWorks LLP et al.
==19156== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==19156== Command: ./race
==19156== 
==19156== ---Thread-Announcement------------------------------------------
==19156== 
==19156== Thread #1 is the program's root thread
==19156== 
==19156== ---Thread-Announcement------------------------------------------
==19156== 
==19156== Thread #2 was created
==19156==    at 0x51427AE: clone (in /usr/lib/libc-2.24.so)
==19156==    by 0x4E431A9: create_thread (in /usr/lib/libpthread-2.24.so)
==19156==    by 0x4E44C12: pthread_create@@GLIBC_2.2.5 (in /usr/lib/libpthread-2.24.so)
==19156==    by 0x4C31810: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==19156==    by 0x4C328FD: pthread_create@* (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==19156==    by 0x4005C6: main (in /home/tommycc/race)
==19156== 
==19156== ----------------------------------------------------------------
==19156== 
==19156== Possible data race during read of size 4 at 0x60103C by thread #1
==19156== Locks held: none
==19156==    at 0x4005C7: main (in /home/tommycc/race)
==19156== 
==19156== This conflicts with a previous write of size 4 by thread #2
==19156== Locks held: none
==19156==    at 0x400597: child_fn (in /home/tommycc/race)
==19156==    by 0x4C31A04: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==19156==    by 0x4E44453: start_thread (in /usr/lib/libpthread-2.24.so)
==19156==  Address 0x60103c is 0 bytes inside data symbol "var"
==19156== 
==19156== ----------------------------------------------------------------
==19156== 
==19156== Possible data race during write of size 4 at 0x60103C by thread #1
==19156== Locks held: none
==19156==    at 0x4005D0: main (in /home/tommycc/race)
==19156== 
==19156== This conflicts with a previous write of size 4 by thread #2
==19156== Locks held: none
==19156==    at 0x400597: child_fn (in /home/tommycc/race)
==19156==    by 0x4C31A04: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==19156==    by 0x4E44453: start_thread (in /usr/lib/libpthread-2.24.so)
==19156==  Address 0x60103c is 0 bytes inside data symbol "var"
==19156== 
==19156== 
==19156== For counts of detected and suppressed errors, rerun with: -v
==19156== Use --history-level=approx or =none to gain increased speed, at
==19156== the cost of reduced accuracy of conflicting-access information
==19156== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
她很明確得告訴我們有可能的race問題。而且名稱叫做var。結果十分直觀。

Massif

valgrind --tool=massif 程式名稱
他是用來分析data segement 中heap使用。
heap在data sgment通常是由malloc等函式創造的,是適當的優化減少heap可以paging和盡量避開使用swap space。
在執行完massif後會有一個massif.out.pid檔,可以透過ms_print來印出。不過一般高速運行的程式,他的malloc和free執行很快,在輸出圖形的時候看起來是一條線,所以可以透過valgrind --tool=massif --time-unit=B 程式名稱 讓massif透過allocate與deallcoate記憶體大小作圖。範例程式如下。
#include<stdio.h>
#include<stdlib.h>

int main()
{
    malloc(1000);
    int* a[10];
    for (int i = 0 ; i < 10 ; i++ )
        a[i] = malloc(1000);
    for (int i = 0 ; i < 10 ; i++ )
        free(a[i]);
}
結果如下。
--------------------------------------------------------------------------------
Command:            ./heap
Massif arguments:   --time-unit=B
ms_print arguments: massif.out.2213
--------------------------------------------------------------------------------


    KB
10.91^                                     ####                               
     |                                     #                                  
     |                                  :::#   :::                            
     |                                  :  #   :                              
     |                              @@@@:  #   :  ::::                        
     |                              @   :  #   :  :                           
     |                           :::@   :  #   :  :   :::                     
     |                           :  @   :  #   :  :   :                       
     |                        ::::  @   :  #   :  :   :  :::                  
     |                        :  :  @   :  #   :  :   :  :                    
     |                    :::::  :  @   :  #   :  :   :  :  ::::              
     |                 ::::   :  :  @   :  #   :  :   :  :  :   :::           
     |                 :  :   :  :  @   :  #   :  :   :  :  :   :             
     |             :::::  :   :  :  @   :  #   :  :   :  :  :   :  ::::       
     |             :   :  :   :  :  @   :  #   :  :   :  :  :   :  :          
     |          ::::   :  :   :  :  @   :  #   :  :   :  :  :   :  :   :::    
     |          :  :   :  :   :  :  @   :  #   :  :   :  :  :   :  :   :      
     |      :::::  :   :  :   :  :  @   :  #   :  :   :  :  :   :  :   :  ::: 
     |      :   :  :   :  :   :  :  @   :  #   :  :   :  :  :   :  :   :  :   
     |   ::::   :  :   :  :   :  :  @   :  #   :  :   :  :  :   :  :   :  :  @
   0 +----------------------------------------------------------------------->KB
     0                                                                   20.84

Number of snapshots: 23
 Detailed snapshots: [9, 12 (peak), 22]

--------------------------------------------------------------------------------
  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
--------------------------------------------------------------------------------
  0              0                0                0             0            0
  1          1,016            1,016            1,000            16            0
  2          2,032            2,032            2,000            32            0
  3          3,048            3,048            3,000            48            0
  4          4,064            4,064            4,000            64            0
  5          5,080            5,080            5,000            80            0
  6          6,096            6,096            6,000            96            0
  7          7,112            7,112            7,000           112            0
  8          8,128            8,128            8,000           128            0
  9          9,144            9,144            9,000           144            0
98.43% (9,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->87.49% (8,000B) 0x400569: main (in /home/tommycc/heap)
| 
->10.94% (1,000B) 0x400556: main (in /home/tommycc/heap)

--------------------------------------------------------------------------------
  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
--------------------------------------------------------------------------------
 10         10,160           10,160           10,000           160            0
 11         11,176           11,176           11,000           176            0
 12         11,176           11,176           11,000           176            0
98.43% (11,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->89.48% (10,000B) 0x400569: main (in /home/tommycc/heap)
| 
->08.95% (1,000B) 0x400556: main (in /home/tommycc/heap)

--------------------------------------------------------------------------------
  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
--------------------------------------------------------------------------------
 13         12,192           10,160           10,000           160            0
 14         13,208            9,144            9,000           144            0
 15         14,224            8,128            8,000           128            0
 16         15,240            7,112            7,000           112            0
 17         16,256            6,096            6,000            96            0
 18         17,272            5,080            5,000            80            0
 19         18,288            4,064            4,000            64            0
 20         19,304            3,048            3,000            48            0
 21         20,320            2,032            2,000            32            0
 22         21,336            1,016            1,000            16            0
98.43% (1,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->98.43% (1,000B) 0x400556: main (in /home/tommycc/heap)
| 
->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%
可以看到malloc和free的作用。

其他工具

有些是valgrind的開發工具所以就跳過了。
ref:http://valgrind.org/docs/manual/manual.html



Written with StackEdit.

Wednesday, December 14, 2016

方便的網站:stackedit

**

方便的網站:stackedit

*在CMS風行一段時間之際,傳統的部落格文書編輯器已經顯得過時無用,調字體大小等這些基本功能用傳統文書編輯器還可以接受,但表格等則還需要動用html,這顯得十分麻煩,這時運用markdown方式撰寫文件的功能的網站如與後出筍般出現,包括hackmd:https://hackmd.io/專案的成功。而部落格方面,除了wordpress的markdown插件,logdown以markdown為訴求的網站平台外,如果使用傳統google所提供的blogger功能的話,首推stackedit:https://stackedit.io,他的功能十分強大,可以幫你管理你的文章還可以串連多個blog平台,包括blogger,wordpress,github,gist,tumblr等,而且畫面簡潔明亮,害我都跳槽了哈哈。

Written with StackEdit.

Wednesday, December 7, 2016

[Note]Microcontroller的排程方式

[Note]Microcontroller的排程方式

這篇為我看完Microchip Technology 20024 FRM4 - Interrupt and Task Scheduling - No RTOS Required後所作的筆記。

Race condition與Synchronization

Race condition的觀念在恐龍書已經說很多了,所以就不提了。而Synchronization部份,Microcontroller常用interupt disabling和spin lock來做處理,而用到sempahore的部份也是有。另外值得注意的一點是,由於MCU同時有許多peripheral component(Timer,ADC,SPI,UART...)再運作,這些元件也會改變SFR(special function register)的值,所以建算你的程式是但執行序,仍可能會有race consition發生,例如:在PIC的 16 bit timer中,他是分成兩個register控制timer的值(TMR1L,TMR1H),也就是說你要更動timer的值時,需要大於兩個cycle,才可辦到,但是如果在存取值的時候你的timer仍在運作,則可能發生,不合理的狀況。比方說你想要讀取TMR1的值(TMR1H + TMR1L),原本TMR1H = 0x00,TMR1L = 0xFF,第一部份,你讀到了TMR1H的值為0x00,但在第二部份時你要讀TMR1L的時候,因為timer仍在計時,經過一個cycle,TMR1L的值已經加1並進位到TMR1H,所以TMR1L的值現在為0x00,你讀到的值就是0x00,在這個case中,你預期你會得到(0x00,0xFF),但你實際上拿到(0x00,0x00),這是在MCU常有的情況。避免的方法為暫停timer然後再去取值。


Review interrupt

在MCU中硬體發生的中斷會已硬體的context switch實做,也就是她會將當前的core register複製一份到shadow register儲存,保留狀態,當離開ISR後,CPU會將shadow register載回core register中。

在interupt中,對於跨ISR與main line的變數,可以考慮使用Volatile修飾字(一個資源有多個process使用時,透過這個修飾字可以告訴編譯器,不要對這個值做值域判斷優化),以免編譯器編出你無法預期的行為。

interrupt在context switch時會有所謂的interrupt latency(在IVT中尋找對應的interrupt vector+context switch+當前指令的完成(例如說MUL)),這是MCU的效能指標之一,不過對於多層的interrupt,在第二層以後失去了硬體context swtich的優化,所以速度會慢很多。

Jitter injection為main line在被中斷後所暫停執行的時間,通常要盡量讓Jitter 愈小愈好。

interupt priority:MCU中的interrupt有priority,規範誰可以中斷誰,例如說PIC18F系列有兩個level,dsPIC30F系列有八個level,此外MCU中透過interrupt 在IVT的順序,有所謂的natural order priority,來處理相同level intertupt同時發生的問題。另外,ISR裡可以包裹多個interrupt handler,這部份一樣是透過IVT先後和priority還有發生時間決定進入點。(其他:可重入程序)。

一些ISR設計的注意細節:
1.盡量ISR短,減少jitter
2.避免無限的等待
3.盡量避免ISR與mainline使用相同的全域變數(有的話記的要加volatile)

Review scheduler(非Real time)與相關技術

有cooperative與preemptive兩大類,恐龍書有詳盡描述。此外還有兼容兩種特性的(hybird)。

常見排程方式與技術有:

1.sequential

任務是循序執行的,好處是簡單明瞭,非常好預期行為。缺點是容易多做一些不必要的任務,還有每個任務的latency變異大。

2.Round Robin

恐龍書有提到,就跳過了。

3.basic priority與advanced priority

透過簡單邏輯判斷該執行哪些任務,壞處是要維護判斷的變數狀態正確性,還有避免starvation,而且當判斷模式複雜時難除錯。


4.staged

透過將任務拆解成多個stage然後使用FSM的方式管理任務執行順序,缺點是增加許多資源管理state。


5.scheduled(這裡指時間上)

透過規劃何時該做什麼達成scheduled,好處是簡單好讀,執行時間可預期,好擴展。缺點是需要Timer來排行程,還有有需要維護Ticker。






Tuesday, December 6, 2016

C99 fast data type

C99 fast data type

這個主題是我在看完Efficient C Tip #13 – use the modulus (%) operator with caution這篇文章發現的C99在stdint.h新規範的一些資料型態,所作的小小理解。

C99 fast data type,為一種針對硬體CPU架構所提出的資料型態。主要有這下列八種型態:
uint_fast8_t        
uint_fast16_t
uint_fast32_t
uint_fast64_t
int_fast8_t        
int_fast16_t
int_fast32_t
int_fast64_t
在C99 7.18.1.3是這樣做定義的:
1 Each of the following types designates an integer type that is usually fastest 219) to operate
with among all integer types that have at least the specified width.
2 The typedef name int_fastN_t designates the fastest signed integer type with a width
of at least N . The typedef name uint_fastN_t designates the fastest unsigned integer
type with a width of at least N .
也就是說,這些fast data type確保,你的型態至少為N bit以上(uint_fast8_t至少有8bit width),所以有可能你
宣告一個uint_fast8_t的型態,編出來可能是用16bit裝。
這個型態最重要的用意是aliginment(對齊),一般來說16bitCPU在處理16bit的資料運算有可能8bit的快,這是因為
對齊的因素,因此,這些fast data type在這個例子中直接將uint_fast8_t 定義為uint16_t,來方便CPU運算。

以下這是給16bit MCU的compiler microvhip XC16,在stdint.h中的定義
#ifndef uint_fast8_t                                                            
typedef unsigned int uint_fast8_t;                                              
#define uint_fast8_t uint_fast8_t                                               
#define UINT_FAST8_MAX (65535UL)                                                
#endif  
很明顯可以看到她將uint_fast8_t用unsigned int(16bit)來使用。

Efficient C Tip #13 – use the modulus (%) operator with caution中在16bit的MSP430,作者僅將型態改成,
fast data type,就得到了大幅的加速。在MCU等小型硬體中,在適當的地方使用C99 fast data type可以得到很好的效果。



Wednesday, September 28, 2016

『note』目前的vim

『note』目前的vim

本文僅僅紀錄我用了什麼vim plugin。

首先.vimrc


  • 基本設定

set shiftwidth=4
set expandtab
set softtabstop=4
set laststatus=2
set noshowmode
set number
set modeline
set t_Co=256
set tabstop=2
set fileencodings=utf-8,big5
set cursorline                                                                                                                                    
set mouse=a
syntax on


  • 編譯快捷鍵

autocmd filetype python nnoremap  :w  exec '!python '.shellescape('%')
autocmd filetype c nnoremap  :w  exec '!clear&&gcc '.shellescape('%').' -o '.shellescape('%:r').'&&./'.shellescape('%:r') 
autocmd filetype cpp nnoremap  :w  exec '!clear;echo -n "====================";TEMP=`mktemp`;script $TEMP -e -q -c "g++ '.shellescape('%').' -std=c++11 -Wall -o '.shellescape('%:r').'" > /dev/null 2>&1 ;if [ $? == 0 ] ;then echo -e "\r\033[32m********************\033[0m";./'.shellescape('%:r').';else echo -e "\r\033[31mXXXXXXXXXXXXXXXXX\033[0m";cat $TEMP; fi'                                                                
autocmd filetype c nnoremap  :w  exec '!clear&&gcc '.shellescape('%').' -o '.shellescape('%:r') 
autocmd filetype cpp nnoremap  :w  exec '!clear&&g++ '.shellescape('%').' -std=c++11 -Wall -o '.shellescape('%:r')
nnoremap  :w  exec '!cat '.shellescape('%').'\| xclip -selection clipboard'
nnoremap  :w  exec '!fish'

  • 主題:tomorrow

Bundle
Bundle 'chriskempson/tomorrow-theme', {'rtp': 'vim/'}
設定
color Tomorrow-Night-Bright
colorscheme Tomorrow-Night-Bright

  • neocomplcache

補完插件
Bundle
Bundle 'Shougo/neocomplcache.vim'  
設定
"neocomplcache                                                                                                                                    
let g:neocomplcache_enable_at_startup = 1
let g:neocomplcache_disableautocomplete = 1
let g:neocomplcache_enable_smart_case = 1
" Recommended key-mappings.
" <CR>: close popup and save indent.
let g:neocomplcache_enable_insert_char_pre = 1
  • nerdtree
檔案樹插件
Bundle
Bundle 'scrooloose/nerdtree'
設定
let NERDTreeWinPos='left'
let NERDTreeWinSize=30
map <F2> :NERDTreeToggle<CR>

  • vim-gitgutter

vim git狀態(插入與刪除等)
Bundle


Bundle 'airblade/vim-gitgutter'


  • xterm-color-table.vim

xterm的顏色表
Bundle

Bundle 'guns/xterm-color-table.vim'


  • vim-cuteErrorMarker

語法錯誤標記
Bundle

Bundle 'Twinside/vim-cuteErrorMarker'

  • vim-better-whitespace

行尾空白顯示
Bundle
Bundle 'ntpeters/vim-better-whitespace'
設定
hi ExtraWhitespace ctermbg = 17


  • indentLine

縮排圖示
Bundle
Bundle 'Yggdroot/indentLine'


  • vim-l9

vim script library
Bundle
Bundle 'eparreno/vim-l9'

  • vim-json

vim json syntax highlight
Bundle
Bundle 'elzr/vim-json'

  • syntastic

自動語法檢查
Bundle
Plugin 'scrooloose/syntastic'
設定
set statusline+=%#warningmsg#

set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*

let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 0
let g:syntastic_check_on_wq = 1
let g:syntastic_cpp_compiler = 'g++'
let g:syntastic_cpp_compiler_options = ' -std=c++11 '
let g:syntastic_c_compiler = 'gcc'
let g:syntastic_c_compiler_options = ' -ansi'
let g:syntastic_javascript_checkers = ['standard']
let g:syntastic_javascript_standard_generic = 1
let g:syntastic_javascript_checkers = ['eslint']
let g:syntastic_javascript_eslint_exec = 'eslint'

  • YouCompleteMe

補完工具
Bundle
Bundle 'valloric/YouCompleteMe'
設定
let g:ycm_global_ycm_extra_conf = $HOME/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py'



  • tagbar

C/C++ taglist
Bundle

Bundle 'majutsushi/tagbar'

設定


nmap  :TagbarToggle           
let g:tagbar_ctags_bin='ctags'         
let g:tagbar_width=30                
map  :Tagbar
autocmd BufReadPost *.cpp,*.c,*.h,*.hpp,*.cc,*.cxx call tagbar#autoopen()

精選文章

使用Ardunio Atmega2560 連接 nRF24L01+

使用Ardunio Atmega2560 連接 nRF24L01+ 關於library 目前主流有 https://github.com/maniacbug/RF24 與 https://github.com/TMRh20/RF24 這兩個。 其中TMRh20大大做...