2019年10月4日 星期五

[MJPG-streamer] command data path

簡述:

mjpg-streamer 用來做 streaming 很好用吃. 而且他也自帶了一個簡易的 web server, 用來做基本的操作是可以的. 如果要用一些自訂的命令, 這部分的資料及說明是相對比較少的.

mjpg-streamer 起始命令

./mjpg_streamer –i “input_uvc.so” –o “output_http.so –w ./www”

Command Data Path :

輸入的 URL 命令如下 :

http://192.168.43.201:8080/?action=command&id=1&group=0&dest=1&value=0

此 URL 會被 plugins/output_http/httpd.c 內的 client_thread() 接收,

此時由 _readline 所帶入的 buffer 的內容為 “GET /?action=command&id=1&group=0&dest=1&value=0” ,

最後在 A_COMMAND 的段落, 截去 command, parameter 剩下 “&id=1&group=0&dest=1&value=0”

再呼叫到 command( ….)

進到帶到 command() 之後,  再轉換 id, group, dest, value 這幾個變數為整數型別, 再根據 dest 去呼叫 input/output 的 output_cmd()

問題:

當參數為字串, 無法轉換成整數型別的時候, 就不行了.



然後呼叫到 plugins/output_http/output_http.c 的 output_cmd(int plugin, unsigned int control_id, unsigned int group, int value)

int output_cmd(int plugin, unsigned int control_id, unsigned int group, int value)

2019年9月30日 星期一

[MQTT] What it AND WHY

簡述:

MQTT 是一個 Client/Server 的輕量級訊息傳遞網路協議, 主要應用在硬體性能低下或是網路能力糟糕的環境下. 它是為了最大程度的減少電池損耗, 使用最小的網路頻寬, 已透過衛星和石油管道設備連接. 因此, 它有以下幾個要求:

  • Simple implementation
  • Quality of Service data delivery
  • Lightweight and bandwidth efficient
  • Data agnostic
  • Continuous session awareness

2019年9月23日 星期一

[NT98515] Camera bring-up

簡述:

空的 (全新) 的 NT98515 camera, 上面的 flash 是沒有寫入過的. 所以需要先寫入 loader.

  1. 格式化 SD card.
  2. 置入 LD98510A.bin ( loader 的影像檔, 檔名或有些微差異)
  3. 置入 FW98510A.bin ( all-in-one 影像檔)

Update sequence:

  1. 先將 boot option ( reference NT98515_NT98512_DemoBoard_User_Guide_V1.3_Nova.pdf) 設定成 boot from SD
  2. 寫入 loder 之後, 再切換成  boot from SPI

NOTE:

  • Loader (LD98510A.bin) 是在 uItron 的空間, 所以訊息要接 uItron 的 UART 才看的到.
  • Loader 載入 uboot 之後, 訊息才會從 linux 的 UART 看得到



2019年8月13日 星期二

[Linux] Binary Link

簡述:

城市中有時會用到一大塊的二進位資料, 有幾種方法可以處理. 或是把它轉成 C 的原始檔, 不過這樣會犧牲處存空間及編譯的時間. 在 Linux 上, 可以用 ld 搭配程式中使用巨集, 可以做到二進位資料的直接鏈結, 不需要先轉成原始碼再編譯.

二進位檔轉成原始檔:

$ xxd –i image_src.jpg > image_src.h


範例:

以下以 image_src.jpg 作為 二進位資料檔

二進位資料處理:

$ ld –r –b binary –o image_src.o image_src.jpg

這時就會把 image_src.jpg 的內容, 放到 image_src.o 裡面, 如果有好幾個輸入檔, 可以連續輸入

$ ld –r –b binary –o image_src.o image_src_1.jpg image_src_2.jpg

檢視目的檔 (*.o) 中的二進位資料符號:

$ objdump –t image_src.o

可以看到如下的資料, 這些就是在資料連結階段所參考到的符號

SYMBOL TABLE:
0000000000000000 l    d  .data    0000000000000000 .data
0000000000000000 g       .data    0000000000000000 _binary_image_src_jpg_start
000000000000c815 g       .data    0000000000000000 _binary_image_src_jpg_end
000000000000c815 g       *ABS*    0000000000000000 _binary_image_src_jpg_size

參考用巨集 :

#define EXT_SYMBOL(NAME) \
   extern const unsigned char _binary_ ## NAME ## _start[]; \
   extern const unsigned char _binary_ ## NAME ## _end[];
#define EXT_VARIABLE(NAME) \
   _binary_ ## NAME ## _start
#define EXT_LENGTH(NAME) \
   ((_binary_ ## NAME ## _end) - (_binary_ ## NAME ## _start))

2019年8月1日 星期四

[Linux] Timer

簡述:

測試 Linux 的 Timer 功能.

說明:

在 Linux 中, 我們可以用 setitimer 來設定 timer, 讓他在一段時間後去執行一個動作. 程式原型如下:

#include <sys/time.h>

int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *restrict value, struct itimerval *restrict ovalue);

參數如下 :

  1. which: timer 種類
    • ITIMER_REAL 觸發 SIGALRM, 累計實際上經過的時間.
    • ITIMER_VIRTUAL 觸發 SIGVTALRM, 累計程序執行的時間.
    • ITIMER_PROF 觸發 SIGPROF, 累計程序執行的時間及系統時間.
  2. itimerval: timer 時間定義
    1. time.it_value 第一次觸發的時間
    2. time.it_interval 下一次觸發的時間間隔

注意 :

在 setitimer() 運作的時間 (timer 累計中), alarm(), sleep(), usleep() 均不能正常作用.

範例 :

struct sigaction sa;
struct itimerval timer;

memset(&sa, 0, sizeof(sa));
sa.sa_handler = &timer_handler;
sigaction(SIGALRM, &sa, NULL);
// SIGALRM, SIGVTALRM, SIGPROF

timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = WAKE_INTERVAL;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = WAKE_INTERVAL;

setitimer(ITIMER_REAL, &timer, NULL);
// ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF

2019年7月26日 星期五

2019年7月25日 星期四

PTZ Camera platform assembly

簡述:

說明組裝舵機雲台. 其實這個滿簡單的, 只是對有些強迫證嚴重的人 ( 譬如本人), 會很擔心組裝順序不對, 重裝的時候造成自攻螺絲咬壞塑膠件. 所以還是說明一下.

買來的套件拆開如下:

雲台零件(黑色素膠片) 1 組, 雲台螺絲包 x1, 馬達 x2, 馬達螺絲包 x2,


組立後的成品圖如下 :

組立順序

1. 底座:

底座中心有十字型的凹槽, 是用來安裝馬達的旋翼, 如圖中白色的零件. 這個的硬度不高, 用小刀修整就可以裝入吻合.

馬達的旋翼需要用小小的自攻螺絲. 這螺絲在雲台螺絲包裡.

雲台底座的下視圖.

組裝好的底座.

2. 水平馬達 (pan driver)

將底座裝上馬達

組裝上去的底部視角

組裝後的上視角

接下來組裝左右翼片

組裝左翼片

組裝右翼片

3. 螺絲的位置 (先不要鎖上)

後面會說明為什麼不要先上螺絲.

4. 水平馬達 (tilt)

修整馬達旋翼

結合馬達和承座

馬達和承座和螺絲

5. 最後組裝步驟

組裝上下兩件組件

這兩個部件要交錯組合, 如果先鎖上螺絲, 到這邊就沒有辦法順利裝入, 需要退螺絲.

最終成品





 




 



 

2019年7月8日 星期一

[NT98515] cross compile jpegsrc

簡述 :

因為 mjpeg 需要用到 jpeg, 所以下載, 並且編譯 jpeg 的 MIPS 版本

下載 :

$ wget http://www.ijg.org/files/jpegsrc.v9c.tar.gz
$ tar –xzvf jpegsrc.v9c.tar.gz

編譯 :

$ ./configure CC=”$CC –std=C11” –host=mips-linux
產生錯誤
查看 config.log, 錯誤訊息如下
configure:4603: checking how to run the C preprocessor
configure:4673: result: /opt/ivot/mipsel-24kec-linux-glibc-4.9-2017.08/usr/bin/mipsel-24kec-linux-gnu-g++
configure:4693: /opt/ivot/mipsel-24kec-linux-glibc-4.9-2017.08/usr/bin/mipsel-24kec-linux-gnu-g++  conftest.c
conftest.c:16:8: error: 'Syntax' does not name a type
         Syntax error
         ^

修正 :

這其實是設定的問題. 用以下的指令就可以正常執行
OPEN_SOURCE=/home/nick/NTK-Release-V1.2/Software/Source/NVT_NA51023_BSP/NA51023_BSP/OpenSource
export CC=/opt/ivot/mipsel-24kec-linux-glibc-4.9-2017.08/usr/bin/mipsel-24kec-linux-gnu-gcc
export CPP=/opt/ivot/mipsel-24kec-linux-glibc-4.9-2017.08/usr/bin/mipsel-24kec-linux-gnu-cpp
export CXX=/opt/ivot/mipsel-24kec-linux-glibc-4.9-2017.08/usr/bin/mipsel-24kec-linux-gnu-g++
./configure \
     CC="$CC -std=c11" \
     --host=mips-linux \
     --prefix=${OPEN_SOURCE}/install/jpeg-9c     \
     --enable-shared \
     --enable-static

$ make
$ install

2019年7月5日 星期五

[NT98515] Prepare Boot-up script

簡述 :

編譯系統的時候, 會把每次都要執行的步驟城市都都放在一起. 以下說明 NT98515 的 BOOT-UP script.

rcS :

rcS 是系統開機程序中, busybox 開始生成預設的配置, 並且初始化文件系統的腳本. NT98515 的 SDK 會把它放在 root-fs/rootfs/etc_Model/etc_IPCAM2_EVB/init.d 的這個目錄. 在編譯的過程中再把它編入根目錄.
NT98515 的 rcS 並沒有做太多事. 修改的部分也只是讓他把目前的事情做完後, 接著執行 PS_DemoStart 這一個腳本
source /etc/profile_prjcfg
# fstab devices create
mount -a
echo "ker" > /proc/nvt_info/bootts
echo "rcS" > /proc/nvt_info/bootts
# To run /etc/init.d/S* script
for initscript in /etc/init.d/S[0-9][0-9]*
do
     if [ -x $initscript ]; then
         echo "[Start] $initscript"
         $initscript
     fi
done
echo "rcS" > /proc/nvt_info/bootts
# Add demo project init
/etc/init.d/PS_DemoStart

PS_DemoStart :

PS_DemoStart 是從 rcS 接回 demo 的這個專案. 在這邊可以做 USB Host 的 initial (這個案子不用), SD 的掛載. 如果 SD 卡上有 SD_DemoStart, 則執行 SD_DemoStart, 這是為了如果需要可以改動的執行程序, 放在 /etc/ 就不適合 ( NT98515 的 etc 是 readonly), 不容易變更.

2019年7月4日 星期四

[NT98515] mjpg-streamer

簡述 :

在 NT98515 上編譯及安裝 mjpg-streamer

下載及編譯 :

mjpg-streamer:
原始的作者似乎已經沒有在維護, https://github.com/jacksonliam/mjpg-streamer
所以找到另外一個分支 https://github.com/codewithpassion/mjpg-streamer

下載 :

$ git clone https://github.com/codewithpassion/mjpg-streamer.git

修改配置 :

1. Makefile/gcc
修改 mjpg-stremaer 下的 Makefile 及, mjpg-stremaer/plugins 下面所有目錄的 Makefile
CC = gcc
修改為
CC = mipsel-24kec-linux-gnu-gcc
2. Makefile/CFLAGS
修改 mjpg-stremaer/plugins/input_uvc 下面的 Makefile
CFLAGS += –I/home/nick/SDK-1.2/OpenSource/install/jpeg-9c/include –L/home/nick/SDK-1.2/OpenSource/install/jpeg-9c/lib
然後 make

測試 :

將 mjpg-streamer 複製到 camera, 然後啟動.
可以透過 http://192.168.43.81:8080/index.html 連線到 mjpg-streamer



[NT98515] NEW PROJECT

簡述 :

新的專案, 硬體元件及軟體需求  :
  • ISP NT98515
  • Sensor OV4689
  • WiFi RTL8189ES/SDIO
軟體功能 :
  • WiFi AP/Station Mode
  • mjpg-stream
  • Youtube streamming
以下逐步建置專案所需軟體 :
  1. Source code unpack
    1. $ tar –jxvf NA51023_BSP_20180928_IPCAM_V1.2.02.tar.bz2
    2. $ sh sdk.unpack
    3. $ source build/envsetup.sh
    4. $ lunch 1, 1, 1
    5. $ make
  2. Sensor/OV4689 Configure  https://miworkbook.blogspot.com/2019/07/nt98515-configure-sensor-ov4689.html
  3. WIFI/8189ES Configure
    1. Enable WIFI support https://miworkbook.blogspot.com/2019/07/nt98515-enable-wifi-support.html
    2. Compile RTL8189ES/SDIO https://miworkbook.blogspot.com/2019/06/nt98515-sdio-wifi-module-rtl-8189es.html
  4. 修整 boot-up script https://miworkbook.blogspot.com/2019/07/nt98515-prepare-boot-up-script.html
  5. 安裝 mjpg-streamer
    1. 編譯 jpegsrc https://miworkbook.blogspot.com/2019/07/nt98515-cross-compile-jpegsrc.html
    2. 編譯 mjpg-streamer https://miworkbook.blogspot.com/2019/07/nt98515-mjpg-streamer.html
    3. 製作 mjpg-streamer plugin  
  6. Enable WiFi support

2019年7月3日 星期三

[NT98515] Configure sensor Ov4689

簡述 :

新的專案預計使用 OV4689.

修改 Project Config

修改 uitron/Project/DemoKit/ModelConfig_IP_CAM2_EVB.txt 其中有關 sensor/AE/AWB/IQ 的設定

特別要注意的是, 這個修改必須重新 lunch.

影像是上下顛倒, 左右相反的. 需要再修改 uitron/DrvExt/DrvExt_src/ModelExt/DxCamera_Sensor.c











原來是系統設定就是上下顛倒的, 把它改回來

//    init_obj.option= SENSOR_OPTION_FLIP;
init_obj.option = SENSOR_OPTION_MIRROR;













   
   

2019年7月2日 星期二

[NT98515] Enable WiFi Support

簡述 :

NT98515 的 SDK 預設不支援 WiFi. 必須要在 Linux Kernel 設定.

Configure :

$ make linux_config
[*] Networking support
  [*] Wireless
    <M> cfg80211 - wireless configuration API 
    [*] nl80211 testmode command
    [ ] enable powersave by default
    [*] cfg80211 wireless extensions compatibility
<M> Generic IEEE 802.11 Networking Stack (mac80211) 
[*] Minstrel
[*]      Minstrel 802.11n support 



Device Drivers --->
  [*] Network device support 
    [*] Wireless LAN
        <*> IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)












  
  

  

2019年6月27日 星期四

[Raspberry] mjpg-streamer

簡述:

測試看看 Raspberry Pi 上, 使用 Mjpeg-Streamer 的 frame delay.

安裝及編譯:

$ sudo apt-get install libjpeg8-dev
$ sudo apt-get install imagemagick
$ sudo apt-get install cmake
$ sudo git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpeg-streamer/mjpg-streamer-experimental
$ make all
$ sudo make install

用測試圖片驗證:

在 plugins 目錄下有一個 input_testpicture 的目錄, 可以用來測試驗證.

在 raspberry pi 上面執行以下命令,
$ ./mjpg_streamer –i “input_testpicture.so –r 320x240 –d 500” –o “output_http.so –w www”


就可以從瀏覽器上打開 http://192.168.43.201:8080/index.html










或是從 VLC 上打開 http://192.168.43.201:8080/?action=stream


可以確認 live view 的部分是 work 的.


用 USB cam 來當作影像輸入:

mjpg-streamer 本身的 input_uvc 是有支援 USB Cam/Webcam 的. 只不過一般的 webcam 通常預設是 YUYV 的格式, 而非 MJPEG. 最簡單的方法就是修改 plugins/input_uvc/input_uvc.c 這個檔案. 把 V4L2_PIX_FMT_MJPEG 改成 V4L2_PIX_FMT_YUYV.

然後啟動 mjpg_streamer
$ ./mjpg_streamer –i “input_uvc.so –r 320x240 –d 500” –o “output_http.so –w www"
從瀏覽器打開











或是從 VLC player 連線

搭配 Raspberry Camera :

載入 raspberry pi camera driver
$ sudo modprobe bcm2835-v4l2










啟動 mjpg_streamer













可同時連線



















[NT98515] SDIO Wifi module RTL-8189ES

簡述:

又到了團團轉時間. 這一次大風吹的是 "在 NT98515 的平台上啟用 SDIO 介面的 WiFi 模組 RTL8189ES"
這部分的整合, 需要考量到幾方面, wifi module 的接線, SDIO driver 的設置, wifi driver 的設置.

SDIO wifi module :

根據 SDIO 的規格, SDIO 有一個 card detect ping, 這個 pin 並不在 SD card 的插槽上. 當有卡插入的時候, 這個 pin 會短路到 ground. 主機端從而判斷出插槽裡面有卡, 開始偵測這張卡, 並試圖啟用這張卡.


SDIO driver 的設置 :

Linux 的硬體設定, 是從 dts 傳送給核心, 在啟動相對應的驅動程式時, 傳送相關的參數. 確認過 dts (linux-kernel/arch/mips/boot/dts/novatek/nvt-na51023-evb-default.dtsi), 幸運地發現 SDIO port (mmc2) 已經設定好了.



另外, (uitron/Project/DemoKit/ModelConfig_IPCAM2_EVB.txt) 這裡面有一些 NVT_SDIO_WIFI/NVT_USB_WIFI , 不用去管它. SDIO 介面的 wifi driver 目錄是空的, USB port 上沒有接 wifi driver, 也不用特別去改設定. 總之, 改這個沒有用.

確認 SDIO driver 是否可以正常動作 :

附圖是兩個 SDIO bus, 一個有  device, 一個沒有. 很容易分辨出來.


RTL-8189ES driver 設置 :

1. 從 https://github.com/openwetek/rtl8189es 下載
2. 參考 rtl8188ftv/Makefile, 加入 NT98515 的組態
3. make
基本上沒有甚麼大問題.

2019年6月3日 星期一

[Android] AsyncTask 用法詳解

簡述:

Android 的 App, 通常只在預設的 UI Thread 運行. 當遇到一些較為耗費時間的工作時, 就必須採用 Multi Thread  的作法. 否則很容易就會遇到 ANR 的錯誤, 導致 App 被停止執行. AsyncTask 是一種 Multi Thread 的作法.

AsyncTask 的型態:

因為 AsyncTask 的目的就是提供一個線外作業的機制, 所以它會有兩個特性:  
  1. 在平行時間運行. AsyncTask 和 UI Thread 必須可以在不互相影響的狀況下各自運行.
  2. 互動. AsyncTask 的運行必須可以反映到  UI Thread (如果不能反映到 UI Thread, 又怎麼知道它執行完畢了呢 ?)
於是, 很容易可以猜想到, AsyncTask  它會接收一個起始狀態, 一個運行狀態, 一個結果回報的狀態. 這3 種狀態的參數型態,  就是這個 AsnycTask 的參數型態, 如下圖:
 
class SleepTask extends AsnycTask<String, Integer, String>, 這邊就宣告了 SleepTask 是 AsyncTask 的衍生類別, 它有 3 個參數型態, String, Integer, String. 各參數依序為起始狀態, 運行狀態, 結果狀態.
起始狀態是在執行時, 由呼叫程序傳入, 然後 AsnycTask 在呼叫 doInBackground 時, 以參數傳入. 從字面上的意義可以知道, doInBackground 是真正在計算的苦力. doInBackground  接收到起始狀態, 然後照起始狀態的指示, 開始運算. 算到一個階段 (需要通知 UI Thread 進度的時候),  就呼叫 publishProgress, 並給予運行狀態, 以便回報進度.  AsyncTask 再把這各參數轉送到 onProgressUpdate. 計算結束的時候, doInBackground 的返回值也會被送到 onPostExcute, 以便更新運算的結果.
之所以要這麼麻煩, 是因為 AsyncTask 除了要運行 doInBackground() 這個苦力程序外, 還要負責同步狀態到 UI Thread. 所以就有了 onPreExecute()/onProgressUpdate()/onPostExecute(), 這三個程序, 用來在不同的時間點更新 UI Thread. 其中除了 onPreExecute 不需要參數, onProgressUpdate()/onPostExecute() 都是把 doInBackground() 產生的狀態更新到 UI Thread.

AsyncTask 的成員函式:

衍生的 AsnycTask 類別, 需要實作以下函式
onPreExecute(), 在還沒有開始計算前, 負責準備工作.
doInBackground(), 真正的苦力運算函式.
onProgressUpdate(), 協助更新 doInBackground 的運算進度
onPostExecute(), 協助更新 doInBackground 的運算結果.

[ NT98515] CROSSCOMPILE ECLIPSE PAHO MQTT C Client

簡述: 試著把 Eclipse Paho MQTT C client  移植到 NT98515 的平台, 並且測試驗證. 下載 source: git clone https://github.com/eclipse/paho.mqtt.c make: cmake $ cmake...