MCU單晶片韌體設計

2019年8月16日 星期五

Raspberry Pi Mail Box--tag buffer


Raspberry Pi Mailbox的機制是你CPU 送出Request所用的buffer , 在GPU Response 回來時是會被修改的.因為使用的是同一塊Buffer, 所以Request傳送的資料佔了幾個byte (bit 30:0 Value Length)及 Response回來有多少個byte ,在送出Request就要決定了
 value buffer 的大小一定是max(Request data length, Response data length)




value buffer size in bytes 是指value buffer的大小;
  value length in bytes 是請求欄位佔幾個Byte



ARM Bare metal 開發課程連結

2019年8月14日 星期三

[Linux Driver 問題] Linux GPIO Host Controller驅動程式



目前課程影片進行到CH3-3 Linux GPIO Host Controller驅動程式,有一些問題如下:

  1. 01_LED中chr_led.c使用gpio_set_value對GPIO Pin設定輸出值,往Kernel Source Code追: gpio_set_value -> __gpio_set_value -> gpiod_set_raw_value -> _gpiod_set_raw_value ->


    static void _gpiod_set_raw_value(struct gpio_desc *desc, bool value)
    {
            struct gpio_chip        *chip;

            chip = desc->chip;
            trace_gpio_value(desc_to_gpio(desc), 0, value);
            if (test_bit(FLAG_OPEN_DRAIN, &desc->flags))
                    _gpio_set_open_drain_value(desc, value);
            else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags))
                    _gpio_set_open_source_value(desc, value);
            else
                    chip->set(chip, gpio_chip_hwgpio(desc), value);
    }

    追到最後是課程影片中提到的struct gpio_chip,但是課程提供的Image中找不到bcm2708_gpio.c這個檔案,struct gpio_chip中的function應該都是實作在這個檔案中?
        ~/linux-rpi-4.4.y/drivers/bcma/driver_gpio.c  ==> gpio chip driver 
  1. 根據課程影片,gpio_set_value是上層API,由Kernel定義。struct gpio_chip中的function pointer實作則為底層硬體相關,這個部分理論上應該是SoC廠實作並提供給客戶嗎?想知道業界實務上怎麼分配?實務上,如果拿到一塊公版,SoC Vendor會提供整包Linux或Android Source Code,我們只需要針對自己選擇的外接硬體寫驅動程式嗎?
       
            
  1. SoC Vendor是否連Driver Template都會一起提供於整包OS Source Code中,只需要修改對應硬體部分?譬如,選擇的Display不同,選擇的Sensor不同,只需要在module_init()中修改初始化代碼?

             晶片廠通常提供的BSP ,會做好大部份SoC Driver. 若是自己自行外接的, 則要靠自己去撰寫或移植

             同類型硬體其Driver 寫法差異不大,所以可以參考現有的code去修改即可.. 

2019年8月12日 星期一

如何界定User Space Driver和Kernel Space Driver?


課程提供的Image中有一個bcm2835_clibbcm2835_clib資料夾,裡面有兩個資料夾。其中一個example應該是控制IT Shield上面不同External Device的Source Code。另一個src資料夾是不是類似"SoC HAL或BSP"之類的腳色,看起來比較像HAL,因為沒有包成板上Device控制的API,而是SoC Peripheral? 這是底層的HAL code 供上層使用 其中,下面的程式碼中為什麼是MAP_FAILED,而不是BCM2835_GPIO_BASEADDR之類的暫存器位置,而且找不到MAP_FAILED這個MACRO的定義 bcm2835_init () 會給正確值 另外,這樣子的寫法如果理解沒有錯誤,應該是Base Metal的寫法。為什麼blink.c編譯出來的執行檔可以直接執行? 這樣是不是等於不是走syscall -> LDD的方式,這樣Kernel怎麼管理這種Process? 這種方式如何界定User Space和Kernel Space? 這是User Space Driver 的寫法.. Kernel 只當它是一般User Process來管理..所以無法像Kernel Space Driver可以在底層做設備管理
User Space Driver 作法可以走 device file 的方式, 也可以用mmap(2)方式來操作SFR (special function register) . 細節可以自行參考 bcm2835_init () 函式

2019年8月6日 星期二

將vim預設語法Highlight 打開



sudo apt-get install vim

將vim開啓程式,預設即是語法Highlight 打開 (syntax highlighting in vim)

修改 vim $HOME/.vimrc


加入這一行

syntax on

存檔離開



2019年8月5日 星期一

[ARM Boot Loader ] code 說明


有個問題請教一下
Linker Start up code那個章節 56分:28秒的那一段
1. For broad com的bootloader,是不是也應該會把vector table copy to RAM 0x00的位置?
2. Power on and Reset 是一樣的嗎? 都會直接執行RAM上面0x00的位置? 還是Power on的時候會從走一次bootloader,然後copy vector table to RAM 0x00.
是會有誰把vector table copy過去才對。但影片中說reset一開始就跑0x00,0x00要有instructions.讓我聽得有點模糊。reset的時候 , RAM的內容都還保留著? 只有Power on and Power on的情況才會重新從bootloader copy vector table to RAM?

 每個系統有其 PowerOn 流程,如從ROM, EEPROM, NOR Flash或特定bootable devcie開機,而這些地方就是要先放好Exception Vector Table的地方,Power on 即觸發ARM Reset Exception , 故立即進行ARM Reset Handler 的工作。而這個Reset 工作的執行 (Stage 1 boot ),是屬於XIP (Excute In Place) ,即boot code是在ROM或Nor Flash 內被執行的。
Reset 工作初始化SDARM, SDRAM  , ROM 分別映射到CPU定址空間的一塊位址, 如SDRAM 位於 0x0, 若啓用CPU virtual address , 舉例 0x8000 (使用CPU virtual) 也是對應到SDRAM 。接著copy 一份完整的boot code 到SDRAM (頭幾行的內容當然也會是Exception Vector )。

將CPU的PC 指向ARM Reset Handler ( Stage 2 boot ) , 而此時的Reset Handler 是在SDRAM內。並且這時候的ARM Reset Handler 和前面一開始開機的ARM Reset 做不一樣的事了。前面ARM reset 可以只作少量的事, 後面的Reset 做更多事, 如驅動裝置,如 UART, LED, 等, 還有準備好OS載入的相關工作。



我想知道一般broadcom的bootloader,不含我們bootloader的流程。到底有沒有copy vector table to RAM 0x00,以及power on/off and reset是否一樣?

ARM Reset時, 做copy o RAM (可參考上課實作的程式碼)

 如果不一樣,是否power on/off, bootloader會重新copy vector table to RAM, 至於reset是用之前已經copy過存留在RAM的vector table.

  

還有一個問題,RAM and ROM share 相同的位置空間嗎? 不同空間 
課程中常提到 0x8000 and 0x0。這個位置 是RAM 還是 ROM。當我拿到一個位置的時候,我怎麼知道他是RAM還是ROM還是某個peripheral?
   
    0x8000 and 0x0 都可以對應到RAM 

   詳看SoC 晶片手冊..一般 memory map 會告訴你address指的是什麼....

    

2019年8月4日 星期日

軟體開發工具



SVN 基本概念







SVN基本使用步驟:

1.  下載並安裝 Windwos SVN Client工具-- tortoisesvn
2.  新增資料匣, 然後按右鍵新選擇 [SVN Checkout.] , 輸入URL of Repository ,
 , 接著輸入SVN 帳密. 即可checkout 程式碼.






3. 之後可以若要更新程式(即和SVN Server 同步) 則可以按右鍵執行 [SVN Update].

  svn update 

4. 對於既有的檔案有修改可以[SVN Commit] 上傳到SVN Server上

  svn commit -m "message"

5. 對SVN Repository 有要新增/刪除的檔案或目錄,到則要先用 [SVN Add]/[SVN Del], 再SVN Commit 才正式納入版本控制,別人SVN Update 時也才看得到..

 svn add folder_name/file_name
 svn del folder_name//file_name





====================================

Trello 專題使用說明




在Trello上對於文字的格式處理採用Markdown語法, 這點和github上的README.md
相同

How To Format Your Text in Trello

2019年8月3日 星期六

ESP8266 HTTP GET/POST





開始進入HTTP Body,  HTTP Header 結尾必定是連續2組\r\n \r\n , 接著就是準備好實際HTTP要傳送的內容,


ESP8266 寫法1:
String cmd = "GET /test.html HTTP/1.1"; 
ESP8266.println("AT+CIPSEND=4," + String(cmd.length() + 4)); 
delay(1000);
ESP8266.println(cmd);
 delay(1000); 
ESP8266.println(""); 

ESP8266 寫法2:
  sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //  access point
  sendData("AT+CIFSR\r\n", 1000, DEBUG); // get ip address
  sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); // configure for multiple connections
  sendData("AT+CIPSTART=4,\"TCP\",\"api.thingspeak.com\",80\r\n", 1000, DEBUG); // turn on server on port 80
  key = 23;   //random number for testing
  String web = "GET http://api.thingspeak.com/update?api_key=KTQXXXXXXXXXXXXX&field1="";
  web += key;
  web += "HTTP / 1.0";
  web += "\r\n";
  web += "\r\n";

//HTTP Body 開始
  String cipsend = "AT + CIPSEND = ";
  cipsend += 4;
  cipsend += ", ";
  cipsend += String(web.length());

ReadMore:


  1. HTTP 的訊息格式處理
  2. 可以透過wireshark 抓封包軟體, 解析出HTTP 通訊協定https://www.wireshark.org/download.html