2020/5/29

numpy : save and load

numpy 的 save 和 load 可以作到把 save 物件的身份和資料都紀錄。
例如:complex..
import numpy as np

A = np.array([1+2j, 3+4j, 5+6j])
np.save('Adata',A)

B = np.load('Adata.npy')
print(B)
執行結果:
[1.+2.j  3.+4.j  5.+6.j]
B 從 Adata.npy load 資料後,自動成為 complex type array.

python code to command DCA1000EVM Start/Stop Record

對應上一篇,使用 DCA1000EVM_CLI_Control 對 DCA1000EVM 下開始紀錄 的命令封包,
用 python 寫依序是..
import codecs
import socket
import time

DCA1000IP = ('192.168.33.180',4096)

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

sock.sendto(codecs.decode('5aa50300060001020102031eaaee','hex'),DCA1000IP)
time.sleep(1)
sock.sendto(codecs.decode('5aa509000000aaee','hex'),DCA1000IP)
time.sleep(1)
sock.sendto(codecs.decode('5aa505000000aaee','hex'),DCA1000IP)
另外,停止的command 是..
sock.sendto(codecs.decode('5aa506000000aaee','hex'),DCA1000IP)

配合 wireshark 看,start record 後, data port (4098) 的資料。
sequence number 都是從 1 開始..

send stop command 之後,再送 start command 就可以,不用再送前面兩個 FPGA 跟 CONNECT command.
而且每次送 start command,packet num 都會從1 開始。

2020/5/26

DCA1000EVM_CLI_Control and Wireshark

用 Wireshark 看一下 DCA1000EVM_CLI_Control 的命令封包
C:\ti\mmwave_studio_02_01_00_00\mmWaveStudio\PostProc>DCA1000EVM_CLI_Control.exe fpga cf.json
FPGA Configuration command : Success
PC -> DCA1000
0000   5a a5 03 00 06 00 01 02 01 02 03 1e aa ee         Z.............
DCA1000 --> PC
0000   5a a5 03 00 00 00 aa ee                           Z.......

C:\ti\mmwave_studio_02_01_00_00\mmWaveStudio\PostProc>DCA1000EVM_CLI_Control.exe start_record cf.json
Start Record command : Success
PC --&t; DCA1000
0000   5a a5 09 00 00 00 aa ee                           Z.......
DCA1000 --> PC
0000   5a a5 09 00 00 00 aa ee                           Z.......
PC --> DCA1000
0000   5a a5 05 00 00 00 aa ee                           Z.......
DCA1000 --> PC
0000   5a a5 05 00 00 00 aa ee                           Z.......
DCA1000 --> PC
0000   01 00 00 00 00 00 00 00 00 00 c8 00 99 ff d1 ff   ................
0010   25 01 47 fe 8a ff d0 ff 39 fe f0 00 59 00 25 ff   %.G.....9...Y.%.
0020   7a 00 28 ff ed fe 7b 00 27 ff 40 00 14 01 98 fe   z.(...{.'.@.....
0030   a6 ff f9 ff 83 ff 56 00 34 00 f5 fe 75 00 1f ff   ......V.4...u...
0040   ce fe 10 01 37 00 72 ff f6 00 a0 fe a9 ff fb ff   ....7.r.........
0050   28 fe 39 01 83 00 47 ff 4c 00 ed ff 1e ff 6e 00   (.9...G.L.....n.
0060   50 ff 4f 00 12 01 d6 fe 47 ff a9 00 ad ff 4a 00   P.O.....G.....J.
0070   59 00 8e ff 3b 00 90 ff d7 fe 21 01 f5 00 27 ff   Y...;.....!...'.
0080   c7 00 6a ff 2e ff b1 00 fb fe 1d 01 da 01 6a fe   ..j...........j.
...
DCA1000 --> PC
0000   02 00 00 00 b0 05 00 00 00 00 6a 00 62 01 69 fe   ..........j.b.i.
0010   89 00 13 00 36 fe fc 01 00 00 d2 ff 12 01 7c fe   ....6.........|.
0020   c1 ff 1a 01 29 ff cd 00 cf 00 5e ff 0b 00 ff ff   ....).....^.....
0030   2a ff 1a 01 67 00 ea ff 47 01 43 ff 98 ff 35 00   *...g...G.C...5.
0040   4d 00 c9 ff b5 00 56 ff dc ff 5d 00 b3 ff 62 00   M.....V...]...b.
0050   e0 00 b1 fe 84 00 fa ff 68 fe 5d 01 c2 ff b3 00   ........h.].....
0060   39 01 80 ff 92 ff 0b 00 91 ff 4f 00 84 00 b1 ff   9.........O.....
0070   54 00 e6 ff 7b ff e6 00 ef ff 82 ff 36 00 aa ff   T...{.......6...
...
之後一堆 DCA1000 --> PC..
然後..
PC --> DCA1000
0000   5a a5 06 00 00 00 aa ee                           Z.......
DCA1000 --> PC
0000   5a a5 06 00 00 00 aa ee                           Z.......

openradar. read in frame

adc.py 的 class : DCA1000 有說明大概怎麼用。
  • Power On DCA1000 and ARW1642
  • open mmWave Studio and setup normally until tab SensorConfig or use lua script
  • Make sure to connect mmWaveStudio to the board via enternet
  • Start streaming data
  • Read in frame using class
Examples:
   dca = DCA1000()
   adc_data = dca.read(timeout=.1)
   frame = dca.organize(adc_data, 128, 4 256)
source code 中,DCA1000() class initialize function,就是設定好 socket, ip , port,和class variable。

read( ) function,把一個 frame 的空間準備好 (fill with zero)
frame size (int bytes) =
ADC_PARAMS['chirps'] * ADC_PARAMS['rx'] * ADC_PARAMS['tx'] * ADC_PARAMS['IQ'] * ADC_PARAMS['samples'] * ADC_PARAMS['bytes']
上面的dict 宣告在前面:
ADC_PARAMS = {'chirps' : 128,
              'rx'     : 4,
              'tx'     : 3,
              'samples': 128,
              'IQ'     : 2
              'bytes'  : 2}
IQ 大概是 I and Q (complex) 兩個都要,所以是 2
bytes 大概是每個數值的大小。

其實source code 中還有一個 config( ) function,是送出 UDP command 給 DCA1000,對應 DCA1000EVM_CLI_Control.exe 的命令,大概是
fpga
start_record
要下這兩個 command,DCA1000EVM 才會開始把 LVDS 資料由UDP 送出。
所以可能要加一下。

上面是讀取 frame ADC data 的大略流程。

Processing 的流程,在 Presense Applied Radar 目錄下…有一些 jupyter source ..
但是data source 都是由檔案讀取,
依照data size,方別有 txt 跟 numpy 的 np兩種格式。
所以猜測,上面用 DCA1000().read 讀入資料後,依照 numpy 的格式寫成檔案。
再用這邊的 jupyter sourece 讀取


上面的 chirps, rx, tx, samples 資料,都是送給 AWR1642BOOST 的config.
整個送給 AWR1642BOOST 的 command 可以參考dca1000 command line tool

其中有關的 command 是..

profileCfg
profileID  startFreq idleTime adcStartTime rampEndTime txOutPower txPhaseShift freqSlopeConst txStartTime numAdcSamples digOutSampleRate hpfCornerFreq1 hpfCornerFreq2 rxGain
samples 其中的 numAdcSamples : number of ADC samples collected during "ADC Sample Time". Example: 256

channelcfg
rxChannelEn txChannelEn cascading numADCBits adcOutputFmt
rx 其中的rxChannelEn :Receive antenna mask. e.g for 4 antenna, it's 0x1111b = 15

frameCfg
chirpStartIndex ChirpEndIndex NumberOfLoops numberOfFrames FramePeriodicityInMS TriggerSelect FrameTriggerDelay
chirps NumberOfLoops : 一個 frame 要重複這個設定幾次
這個決定一個 frame 有幾個 chirp,實際上和 ChirpStartIndex, ChirpEndIndex 有關,每一個 'Loop' 會從 StartIndex 的 chirp config 開始打,打到 EndIndex 的 chirp config.
所以,如果 startIndex = 0,endIndex = 1,每個 loop 就會打兩個 chirp。
如果 loop = 64 的話,每個 frame 就會有 2x 64 = 128 chirps

2020/5/22

DCA1000EVM UDP Packet and config file

DCA1000EVM CLI Software Developement Guide 有說明 UDP Packet

另外,這一篇最後,也有說明用 mmWave Studio 吃 captured data 的方法。

C:\ti\mmwave_sdk_03_03_00_03\docs\mmwave_sdk_user_guide.pdf, section 3.3.2 也有說明使用 CLI_Control 的範例。
利用mmWave Demo Visualizer 控制 AWR1642BOOST 送出LVDS,然後用 DCA1000EVM_CLI_Control.exe log data。
也有 json file 的 Example 和說明。
{
 "DCA1000Config": {
  "dataLoggingMode": "multi",
  "dataTransferMode": "LVDSCapture",
  "dataCaptureMode": "ethernetStream",
  "lvdsMode": 2,
  "dataFormatMode": 3,
  "packetDelay_us": 10,
  "ethernetConfig": {
    "DCA1000IPAddress": "192.168.33.180",
    "DCA1000ConfigPort": 4096,
    "DCA1000DataPort": 4098
  },
  "ethernetConfigUpdate": {
    "systemIPAddress": "192.168.33.30",
    "DCA1000IPAddress": "192.168.33.180",
    "DCA1000MACAddress": "12.34.56.78.90.12",
    "DCA1000ConfigPort": 4096,
    "DCA1000DataPort": 4098
  },
  "captureConfig": {
    "fileBasePath": "C:\\mySavedData",
    "filePrefix": "datacard_record",
    "maxRecFileSize_MB": 1024,
    "sequenceNumberEnable": 1,
    "captureStopMode": "infinite",
    "bytesToCapture": 1025,
    "durationToCapture_ms": 1000,
    "framesToCapture": 5
  },
  "dataFormatConfig": {
    "MSBToggle": 0,
    "reorderEnable": 1,
    "laneFmtMap": 0,
    "dataPortConfig": [
    {
      "portIdx": 0,
      "dataType": "complex"
    },
    {
      "portIdx": 1,
      "dataType": "complex"
    }, 
    {
      "portIdx": 2,
      "dataType": "complex"
    },
    {
      "portIdx": 3,
      "dataType": "complex"
    },
    {
      "portIdx": 4,
      "dataType": "complex"
    }
   ]
  }
  }
}

This json file should match user's setup and the profile.cfg that is used to configure the mmW demo running on mmWave EVM.
  • User should customize "ethernetConfig" block to match their setup
  • "dataLoggingMode" in json file should be set to "raw" if header is disabled via field in lvdsStreamCfg command in profile.cfg. "dataLoggingMode" in json file should be set to "multi" if header is enabled via field in lvdsStreamCfg co mmand in profile.cfg.
  • "lvdsMode" in json file should be set to 2 since xwr16xx/xwr18xx/xwr68xx device have 2 lvds lanes.
  • "dataFormatMode" in json file should match the 12/14/16 bit selection in field in "adcCfg" command in profile.cfg. As one would realize, value of "dataFormatMode" is ("adcCfg""numADCBits" + 1) .
  • User should customize "captureConfig" as per their needs.
  • "MSBToggle" should be set to 0.
  • "reorderEnable" should be set to 1.
  • "dataPortConfig" should set all dataType to "complex" since mmW demo configures all CBUFF/LVDS session to be complex.

2020/5/21

Wireshark - filter

whireshark 可以在 capture 時設定 filter,決定要抓哪些封包。
這篇 就是 whireshark 寫的圖文並茂的說明。

其實有分capture filter display filter,剛剛那一篇說明就有。
位置不一樣。語法好像是一樣..
大概就是
udp : 只要 udp
tcp : 只要 tcp
not XXX : 不要 XXX
另外 and, or 命令也可以用

在 linux 下啟動 wireshark 因為要對 nic 操作,所以要用 root 權限,console mode sudo 開啟。
這樣 wireshark 的 interface 欄位才會顯示正常。

DCA1000EVM, UDP and command Line, Record File format

DCA1000EVM 送 UDP Data, 有 RAW mode 跟 Data Seperate mode.

論壇說...DCA1000EVM_CLI_Control 怎麼存檔的,沒有文件,但是你可以去看 source code,
studio 2.1 版有附 source code...

/** Data Index in the buffer     - With bytes count (6 bytes)                */
#define RECORD_DATA_BUF_INDEX    10

       s32CtPktRecvSize = recvfrom(sRFDCCard_SockInfo.s32DataSock[u8DataTypeId],
                               s8ReceiveBuf, MAX_BYTES_PER_PACKET, 0,
                               (struct sockaddr *)&SenderAddr,
                               &s32SenderAddrSize);
       ...
       memcpy(&u32CtPktNum, &s8ReceiveBuf[0], sizeof(UINT32));

       memcpy(&u64BytesSentTillCtPkt, &s8ReceiveBuf[4], 6);



       writeDataToBuffer_Inline(&s8ReceiveBuf[RECORD_DATA_BUF_INDEX],
                               (s32CtPktRecvSize - RECORD_DATA_BUF_INDEX),
                                false, false);
 

所以真的就是把後面的 rawdata 存起來...


存檔格式的話,mmWave Radar Device ADC Raw Data Capture .pdf 的 6.xWR16XX and IWR6843 with DCA1000 Data Format 有說明...


因為LVDS 是一個一個 Lane 傳送的,一個lane 可以傳送兩筆資料。
因為 DCA1000 傳送 ADC 資料時,只能用 complex。
所以格式就是先兩筆 I 資料(Lane1),再兩筆 Q 資料 (Lane2)
而不是 (I.Q), (I.Q) 成對依序出現。

同樣的 pdf 檔,9.Interpreting Binary File in MATLAB 有code 證實這樣的format..
counter=1
for i=1:4:filesize-1
    LVDS(1,counter  ) = adcData(i  ) + sqrt(-1)*adcData(i+2);
    LVDS(1,counter+1) = adcData(i+1) + sqrt(-1)*adcData(i+3);
    counter = counter+2
end

2020/5/20

lvdsStreamCfg

lvdsStreamCfg: subFrameIdx enableHeader dataFmt enableSW
在 mmwave_sdk_03_03_00_03\docs\mmwave_sdk_user_guide.pdf 的 P.30 有lvdsStreamCfg 的參數說明:
  • subFrameIdx : For legacy mode, that field should be set to -1
  • enableHeader: 0 - Disable HSI header. 1 - Enable HSI header
  • dataFmt : Control HW streaming. 0 - HW STREAMING Disabled. 1 - ADC. 4 - CP_ADC_CQ
  • enable SW : 0 - Disable user data. 1 - Enable user data (SW session) <enableHeader should be set to 1, when this field is set to 1
後面那個 dataFmt,就是對應到 dss_lvds_stream.c:
  switch(datPathObj->cliCfg->lvdsStreamCfg.dataFmt)
    {
        case 1:
            sessionCfg.u.hwCfg.dataFormat = CBUFF_DataFmt_ADC_DATA;
        break;
        case 2:
            sessionCfg.u.hwCfg.dataFormat = CBUFF_DataFmt_CP_ADC;
        break;
        case 3:
            sessionCfg.u.hwCfg.dataFormat = CBUFF_DataFmt_ADC_CP;
        break;
        case 4:
            sessionCfg.u.hwCfg.dataFormat = CBUFF_DataFmt_CP_ADC_CQ;
            sessionCfg.u.hwCfg.cqSize[0] = 0;
            sessionCfg.u.hwCfg.cqSize[1] = HSIHeader_toCBUFFUnits(datPathObj->datapathCQ.sigImgMonTotalSize);
            sessionCfg.u.hwCfg.cqSize[2] = HSIHeader_toCBUFFUnits(datPathObj->datapathCQ.satMonTotalSize);
reference hwCfg.dataFormat 的好像是在 driver/cbuf


MmwDemo_DSS_DataPathObj 是一個超大structure。
其中
 /*! @brief pointer to ADC buffer */
    cmplx16ReIm_t *ADCdataBuf;
好像是 ADC buffer。

chirp interrrupt 後,先 call MmwDemo_dssChirpIntHandler()
他最後 Post Event : MMDEMO_CHRIP_EVT

這個Event 會在MmwDemo_dssDataPathProcessEvents( ) 處理。

VS Code.. Source Navigation..

看source code 的時候,VS Code 的使用方法跟 Visual Studio 有一點像,Visual Studio 是基於 Project (自己組織),VS Code 是 Folder & workspace。
所以所有用到的 source code 要放到同一個 folder (可以有次目錄)。
不然,就要用 workspace,然後把多個 folder add 到 workspace中。

Workspace

全新的 workspace 好像沒有 "New Workspace" 這個動作。
是用 "Add Folder To Workspace" 把一個一個分開的 folder 加近來。
然後用 "Save Workspace As" 存檔。
之後,檔名就會是 workpace name。

以後要開啟,就用 "Open Workspace" 就可以了

Basic Browing

看 Source Code 的時候,提供三個 "動作"
  • Back : Alt - Left Arrow
  • Forward : Alt - Right Arrow
  • Last Edit Location : Ctrl-K Ctrl-Q

顯示目前所在的 function name

顯示目前位置是在那一個 function 的 code 裡,這個要裝 extension : Scope-Bar
enable 後,在下面 status bar 會show 出 function 名稱。

2020/5/19

DCA1000 - Command Line Tool

TI 提供command line tool 經由 UDP Command 控制 DCA1000,
這個 command tool (DCA1000EVM_CLI_CONTROL.exe) 要在 mmwave studio 2.1 板才有。
STUDIO_INSTALL_PATH\mmWaveStudio\PostProc 下。
文件在 STUDIO_INSTALL_PATH\mmWaveStudio\ReferenceCode\DCA1000\Docs 下:
  • TI_DCA1000EVM_CLI_Software_DeveloperGuide.pdf
  • TI_DCA1000EVM_CLI_Software_UserGuide.pdf
簡單測試,先從 User Guide 開始。

DCA1000EVM_CLI_CONTROL 的執行格式是:
DCA1000EVM_CLI_CONTROL command cfg.json
最重要的就是 cfg.json 這個檔案,裡面有所有設定 (LVDS plane, DCA1000 IP address...etc)
EsonJohn mmWave_scriptM 裡面有 cfg.json 這個 json file 的範例。

DCA1000EVM_CLI_Control help:
fpga                            Configure FPGA
eeprom                          Update EEPROM
reset_fpga                      Reset FPGA
reset_ar_device                 Reset AR Device
start_record                    Start Record
stop_record                     Stop Record
record                          Configure Record delay
dll_version                     Read DLL version
cli_version                     Read CLI_Control tool version
fpga_version                    Read FPGA version
query_status                    Read status of record process
query_sys_status                DCA1000EVM System aliveness
-h                              List of commands supported
-q                              Quiet mode - No status display in the console
DCA1000EVM and AWR1642BOOST board setup
在使用這個命令之前,DCA1000 的 Dip SW 要 configure 成 SW_CONFIG
PC 和 DCA1000EVM 使用網路連接,同時 PC 端網路要設為 static IP : 192.168.33.30

開機上電之後..
C:\ti\mmwave_studio_02_01_00_00\mmWaveStudio\PostProc>DCA1000EVM_CLI_Control.exe fpga_version cf.json


FPGA Version : 2.7 [Record]
* cf.json 就是上面github project 內的。

要record data,要先設定 AWR1642BOOT,開使從 LVDS output ADC Data。
利用 mmwave demo visualizer 設定好,save configuration...下面是 best ranage resolution 的 config:
sensorStop
flushCfg
dfeDataOutputMode 1
channelCfg 15 3 0
adcCfg 2 1
adcbufCfg -1 0 0 1 0
profileCfg 0 77 429 7 57.14 0 0 70 1 256 5209 0 0 30
chirpCfg 0 0 0 0 0 0 0 1
chirpCfg 1 1 0 0 0 0 0 2
frameCfg 0 1 16 0 100 1 0
lowPower 0 1
guiMonitor -1 1 1 0 0 0 1
cfarCfg -1 0 0 8 4 4 0 5120
cfarCfg -1 1 0 4 2 3 0 5120
peakGrouping -1 1 1 1 1 255
multiObjBeamForming -1 1 0.5
clutterRemoval -1 0
calibDcRangeSig -1 0 -5 8 256
extendedMaxVelocity -1 0
bpmCfg -1 0 0 1
lvdsStreamCfg -1 0 1 0
nearFieldCfg -1 0 0 0
compRangeBiasAndRxChanPhase 0.0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
measureRangeBiasAndRxChanPhase 0 1.5 0.2
CQRxSatMonitor 0 3 5 123 0
CQSigImgMonitor 0 127 4
analogMonitor 1 1
sensorStart
要enable LVDS output的話,要修改一下 lvfdsStreamCfg 的參數,第三個要是 1:
lvdsStreamCfg -1 0 1 0
用 TeraTerm 連上 AWR1642BOOST後,把上面 command copy 下來 (修改 lvdsStreamCfg) ,一次送出給 AWR1642BOOT。
之後,對 DCA1000 下 command:
C:\ti\mmwave_studio_02_01_00_00\mmWaveStudio\PostProc>DCA1000EVM_CLI_Control.exe fpga cf.json

FPGA Configuration command : Success

C:\ti\mmwave_studio_02_01_00_00\mmWaveStudio\PostProc>DCA1000EVM_CLI_Control.exe start_record cf.json

Start Record command : Success
可以看到開啟一個新視窗..start record...
並且可以看到 DCA1000EVB 的第一顆 LED 閃爍。
代表 UDP 開始傳送...

之後,可以用 DCA1000EVM_CLI_CONTROL stop_record cf1.json 停止,
或是對 AWR1642BOOST 下 sensorStop 來停止 record.

cf.json 中.. 有指定 log data 的 path:
    "captureConfig": {
      "fileBasePath": ".\\Data\\",
.. 所以這個path 要先 create 好..
在裡面可以看到...
  • adc_data_Raw_0.bin
  • adc_data_Raw_LogFile.csv
有關廚存檔案的內容格式,這一篇:DCA1000EVM: Raw mode data format. How is the raw mode data ordered? 有題到:
Hi,

Alternative 2 looks right for complex data.

If you are able to capture, process with mmWave and look at packets with Wireshark.

A great exercise to determine the data format, would be to :

capture and process data
View binary data captured with header information, my case located C:\ti\mmwave_studio_02_00_00_02\mmWaveStudio\PostProc\adc_data_Raw_0.bin
View binary data captured without header information, my case located C:\ti\mmwave_studio_02_00_00_02\mmWaveStudio\PostProc\adc_data.bin
and compare the 2 files above along with the data captured with Wireshark.
A document that might help is Mmwave Radar Device ADC Raw Data Capture, look at section 5 on page 7 and 8.

Alex

或是看文件 SWRA581B : mmWave Radar Device ADC Raw Data Capture.pdf

MinGW, msys

隔了這麼多年,終於又安裝MinGW 了。(世界所有的 RD 們,什麼時候才要全面轉為 Linux ?)

現在安裝簡單多了,就 download install program,執行安裝,完成後,出現 package selection dialog,選要的。 (base system msys & MinGW)
Default 安裝是 C:\MinGW
所以要把 C:\MinGW\bin 加到 system path 中.
這部份還好,都是 compile toolchain,不會影響到 windows command。
其他 shell command 在 C:\MinGW\msys\1.0\bin,所以不能加到 system path 中。
寫一個 batch 檔setmsyspath.bat,需要得時候再 run:
set PATH=%PATH%;C:\MinGW\msys\1.0\bin
* 用字串符號括起來的話,反而會失效。
進入command 後,執行batch,就會出現新的 path.

其實,msys\bin 下有一個 batch: msys.bat,執行後就會設好一些環境,然後 run shell.exe,讓環境更像 unix


update: 2023/10/17

windows10 之後的msys2 support 更好了。
安裝完會開啟幾個default compiler 64, llvm.. 的環境。
之後安裝 package 不用再找以前難用的 msys,改用pacman
就像 apt 依樣,在msys 的console 下 pacman -S package-name 就可以了。

另外因為 msys2 focus 在console program,所以所有 X 的program 都不能run。
所以 要 將遠端 server 的 X client 導入的話,依樣要在windows 下 run 一個 Xserver ,像xming 或是 VcXsrv
然後用 ssh -X 連線,之後還要export DISPLAY=localhost:0 之後,才會正確的把 遠端 server 的 X forward 到 local 端。

在 msys 的 console 先 export DISPLAY=localhost:0,之後用 ssh -Y 連線後,會自動設置 DISPLAY 變數,這時候就會把 X protocol forward 回來 Xserver 上。

-X 和 -Y 的差異。man ssh 的說明:
     -X      Enables X11 forwarding.  This can also be specified on a per-host basis in a configuration file.

             X11 forwarding should be enabled with caution.  Users with the ability to bypass file permissions on the remote host (for the user's X authorization database)
             can access the local X11 display through the forwarded connection.  An attacker may then be
             able to perform activities such as keystroke monitoring.

             For this reason, X11 forwarding is subjected to X11 SECURITY extension restrictions by default.  Please refer to the ssh -Y option and the ForwardX11Trusted 
             directive in ssh_config(5) for more information.

             (Debian-specific: X11 forwarding is not subjected to X11 SECURITY extension restrictions by default, because too many programs currently crash in this mode.  
             Set the ForwardX11Trusted option to “no” to restore the upstream behaviour.  This may change in future depending on client-side improvements.)

     -Y      Enables trusted X11 forwarding.  Trusted X11 forwardings are not subjected to the X11 SECURITY extension controls.

             (Debian-specific: In the default configuration, this option is equivalent to -X, since ForwardX11Trusted defaults to “yes” as described above.  
             Set the ForwardX11Trusted option to “no” to restore the upstream behaviour.  This may change in future depending on client-side improvements.)

2020/5/18

Code Trace .. Output RANGE_DOPPLER_HEAT_MAP

dss_main.c:
    if (pGuiMonSel->rangeDopplerHeatMap == 1)
    {
        itemPayloadLen = obj->numRangeBins * obj->numDopplerBins * sizeof(uint16_t);
        message.body.detObj.tlv[tlvIdx].length = itemPayloadLen;
        message.body.detObj.tlv[tlvIdx].type = MMWDEMO_OUTPUT_MSG_RANGE_DOPPLER_HEAT_MAP;
        message.body.detObj.tlv[tlvIdx].address = (uint32_t) obj->detMatrix;
        tlvIdx++;

        totalPacketLen += sizeof(MmwDemo_output_message_tl) + itemPayloadLen;
    }

所以要找 rangeDopplerHearMap enable 的地方。
在mmw/mss/cli.c
static int32_t MmwDemo_CLIGuiMonSel (int32_t argc, char* argv[])
{
    MmwDemo_GuiMonSel   guiMonSel;
    MmwDemo_message     message;
    int8_t              subFrameNum;

    if(MmwDemo_CLIGetSubframe(argc, argv, 8, &subFrameNum) < 0)
    {
        return -1;
    }

    /* Initialize the guiMonSel configuration: */
    memset ((void *)&guiMonSel, 0, sizeof(MmwDemo_GuiMonSel));

    /* Populate configuration: */
    guiMonSel.detectedObjects           = atoi (argv[2]);
    guiMonSel.logMagRange               = atoi (argv[3]);
    guiMonSel.noiseProfile              = atoi (argv[4]);
    guiMonSel.rangeAzimuthHeatMap       = atoi (argv[5]);
    guiMonSel.rangeDopplerHeatMap       = atoi (argv[6]);
    guiMonSel.statsInfo                 = atoi (argv[7]);
這個function 是....
    cliCfg.tableEntry[cnt].cmd            = "guiMonitor";
    cliCfg.tableEntry[cnt].helpString     = "subFrameIdx detectedObjects logMagRange noiseProfile rangeAzimuthHeatMap rangeDopplerHeatMap statsInfo";
    cliCfg.tableEntry[cnt].cmdHandlerFxn  = MmwDemo_CLIGuiMonSel;
    cnt++;
所以是 guiMonitor 的倒數第二個參數。

git empty folder

git add 不會加 空目錄,
而且,如果用 git rm 把目錄內的 file 都刪光,只留下空目錄。
這個空目錄也會自動被刪除。
用 rm 刪檔,用 -am commit 的話,空目錄會留下。

但是clone 這格 repo 的話,空目錄都不會被 clone 下來...

所以網路上一堆git include empty folder 的說明,但是都不是自動,大多數都是加一些隱藏檔,.gitkeep, ,gitignore 之類.
所以,之後為求保險, git add * 之前,最好用 command 檢查一下..
find . -type d -empty -not -path "./.git/*"
這樣列出不包含 .git,所有的 empty folder.

然後自動產生一個 empty .gitignore
find . -type d -empty -not -path "./.git/*" | xargs -I {} touch {}/.gitignore
在每個 empty folder 都加上 .gitignore,之後再用 git add 加入 folder

2020/5/16

go , vscode extension, A Tour of Go

安裝 GO 的 compiler (?) ,follow Getting Start,download msi and run
VSCode 的 extension,search Go ,第一個出現的竟然是 MS 的。所以就裝了。

然後參考剛剛 Getting Start 寫 hello world,用 VSCode 的 debug,可以看到 debug output window 有 hello world。
另外,follow Getting Start 的說明,用 cmd, 叫 go build 來 build,然後 test run exe 也一樣 OK

這個A Tour of Go 很有趣,左邊是說明,右邊就是 code and run..
有種語言版本,也有繁體中文,建議還是用英文,因為用中文的話,'包' 是? 結果是 Package...

很有趣,大寫開頭就是 public/export function,小寫開頭就是 local/private function。所以都不用特別宣告了。

ref:

Tensorflow Lite, some bookmarks

在 github 上,有關 android 部分大概是: 這個其實就是 google 官方說明的內容。

Flutter for Android Developement in Windows

所以,即使用 VSCode,還是需要安裝 Android Studio...
上一篇後面搞了這麼九,還是失敗了。

改 ref:用VS Code建置Flutter 開發環境。 Download Android Studio,安裝的時候...Android Virtual Device 這一項,要 1G。先 uncheck 試試看。
-- SSD 安裝果然非常快速..
uncheck Virtual Device,但是 Emulator 還是要安裝。
安裝過程很不順利,一直有 socket read timeout,然後跳過,先執行下一個。
然後Retry...

Android Studio 都完成後,VSCode,接上Pixel,Debug..
出現 Error
Warning: License for package Android SDK Platform 28 not accepted.
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
> Failed to install the following Android SDK packages as some licences have not been accepted.
     build-tools;28.0.3 Android SDK Build-Tools 28.0.3
Run flutter doctor..
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at C:\Users\user\AppData\Local\Android\sdk 
   • Platform android-29, build-tools 29.0.3 
   • Java binary at: C:\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

    X Android licenses not accepted.
  To resolve this, run: flutter doctor --android-licenses
所以 開啟Cmd,run flutter doctor -- android-licenses,所有 y/N 都回答 y,一堆...
完成後,再 run flutter doctor, 剩下一個 Error:
[!] Android Studio (version 3.6)
    X Flutter plugin not installed; this adds Flutter specific functionality.
    X Dart plugin not installed; this adds Dart specific functionality.
所以..Android Studio 還是要安裝 Flutter Plugin.....
Android Studio -- Plugins -- Market -- flutter (會一併安裝 Dart)
在run 一次 flutter doctor,no issue found !
VSCode 再 run 一次 debug,.在 debug output windows 看到 install xxxx 一堆,然後最後是 build \...\app-debug.apk,
之後,pixel2 上終於啟動了..
所以這個...用 VSCode 開發 Flutter App 的想法應該是失敗了,
因為最後 Android Studio,Flutter SDK 什麼的都安裝了,就是說,要在 Android Studio 可以開發 Flutter 的狀況下,VSCode 才能開發 Flutter.

NB 修好了..Dell Inspiron N4010

因為買了新NB,所以就壞掉的舊NB 修好了!!!
老闆說主機板的 ATI Chip 壞了,果然,當初就是用它來玩Over watch,測試FPS 可以到多高....才壞的。更換主機版 2500
驗收的時候開機超...慢,3min...老闆說是HD壞了,建議換 SSD 120G,還幫我恢復windows,800。
因為很久沒當工具人了。就照老闆的意思吧...

結果開機變超快,10 sec,好像也很省電。
好像又可以當工作機了..

紀錄一下後來安裝的東西...(之後會繼續更新)
  • 新酷音..PIME 版
  • Github Desktop : 改 git for windows
  • VSCode
...其實比較想裝的是 linux...
github desktop 的話,缺 command line tool,所有 git 動作都要從 她的 desktop app 開始。


* 這一篇要感謝再也無法跟她說謝謝的一姊Zoey,非常感謝。

Flutter with VSCode : Installation

因為舊NB修好了,所以來試試 VSCode 做 Flutter 開發。
看看會不會像Android Studio 一樣慢...

VSCode 安裝 Flutter Extension,然後啟動Flutter Extension的doctor command,他說要找Flutter SDK。
所以去下載Flutter SDK zip。看安裝說明,這個 SDK 安裝其實就市一個 folder。
所以也可以用 git clone。不必用 zip 解壓縮。
安裝到 C:\flutter,然後update PATH:加上 C:\flutter\bin
開啟新cmd. 執行 flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.17.1, on Microsoft Windows [Version 6.1.7601],
    locale zh-TW)
[X] Android toolchain - develop for Android devices
    X Unable to locate Android SDK.
      Install Android Studio from:
      https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK
      components.
      (or visit
      https://flutter.dev/docs/get-started/install/windows#android-setup for
      detailed instructions).
      If the Android SDK has been installed to a custom location, set
      ANDROID_SDK_ROOT to that location.
      You may also want to add it to your PATH environment variable.
[!] Android Studio (not installed)
[√] VS Code, 64-bit edition (version 1.45.1)
[!] Connected device
    ! No devices available
! Doctor found issues in 3 categories.
應該是 OK。

回到 VSCode...
View -- Command Palette -- Flutte : Run Flutter Doctor
可以在 Output Window 看到上面一樣的內容,代表安裝 OK。



follow 接下來的Test Drive,New Project : myapp。
自動產生一個 code skeleton。
要 RUN 的話,要啟動 Emulator,在裝 flutter extension時,已經順便裝了 Android iOS emulator extension 了。
在 Windows 上,只support Android Emulator。
要在 Mac 上run VSCode,才能 support iOS Emulator。

但是.. 要 launch Android Emultor,好像還是需要Android SDK。
而且不能只download command line tool,要啟動 emulator 得話,一定要 Android Studio。
 -- 如果是連接真的 Android Phone,是否還是需要 Android Studio 呢?還是 Command Tool (adb) 就可以?
測試看看...download, unzip,裡面沒有 adb ....
adb, fastboot 是在 platform tool,SDK Platform Tool
download, unzip,add PATH 之後,adb command OK。
但是 插入 android phone缺 driver..
到 Get Google USB Driver Download,unzip..
裝置管理員,更新驅動,point to unzip folder.. OK
<br>
adb device 找到 手機 (pixel2)後,重新啟動 VSCode,下方的 NO Device 改成 Pixel2 了...
結果還是不行,要我 run flutter doctor
其實上面 run doctor 時,就有說一定要 android sdk 了...
所以,還是逃不掉安裝 Android Studio 的命運。


更新:
這一篇,flutter beta 支援 web app 了,所以可以不用emulator 或是真的 device。
所以可能真的不用 android sdk 了...

2020/5/15

docker gitlab - log

用 docker 快速啟動一個 gitlab image...

安裝docker..
  • apt install docker.io -- 結果是 19.03.6
  • 把 user 加到 docker 群組,解決permission denied 問題

開始create gitlab image..
docker pull gitlab/gitlab-ce
docekr run --detach --publish 8787:80 --name gitlab gitlab/gitlab-ce
因為是 detach,所以 run as daemon..
用 docker ps 來看..,只
$ docker ps
CONTAINER ID  IMAGE             COMMAND             CREATED        STATUS                            PORTS                                   NAMES
4d9e7128295e  gitlab/gitlab-ce  "/assets/wrapper"   8 seconds ago  Up 3 seconds (health: starting)   22/tcp, 443/tcp, 0.0.0.0:8787->80/tcp   gitlab
這時候,開啟 ip:8787 是不通的..

後來用
docker attach gitlab
進去後,會看到他在 run starting sequence 的 output,代表還沒啟動完畢...
大約等 4 min 之後,好像完成了. 其實在 1 min 的時候,http 頁面出現 502..
-- attach 一個啟動時是 daemonize 的 container,好像退不出來... 所以用 docker logs -f gitlab
之後用 any-host-ip:8787 舊可以access 到 gitlab login 畫面了。

第一個是 password 畫面,要你輸入 root 的 password,有最短限制,(所以用 full-name without '-')
之後的登入話面舊可以用 root 登入。

docker stop 停止後,再用 docker start 啟動的話,只要約 1min 舊可以正常 access..


以上是參考簡易教學 — 利用 Docker 架設 Gitlab 做的,文章沒有安裝 docker package 的部份,原來是安裝docker.io (ubuntu default package),後來因為不了解開機需要、時間,以為是 docker package 的問題。所以加入 download.docker.com repo,改裝 docker-ce 做的。

接下參考三秒教你用 Docker 安裝 GitLab,把 config. log. data 從 container image 中分離出來。


更新。
新的版本,第一次啟動已經不是 root password 了。
所以參考這一篇,在 container 中run bash,開啟 sql 設定 rooot password:
$ docker exec -it gitlab bash
root@1b10f96444f4:/# gitlab console -e production
Unknown command. Run `gitlab help` for a list of available commands.
root@1b10f96444f4:/# gitlab-rails console -e production
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
 GitLab:       14.8.2 (c7be43f6dd3) FOSS
 GitLab Shell: 13.23.2
 PostgreSQL:   12.7
------------------------------------------------------------[ booted in 20.47s ]
Loading production environment (Rails 6.1.4.6)
irb(main):001:0> user = User.where(id: 1).first
=> #<User id:1 @root>
irb(main):002:0> user.password = 'charles'
=> "charles"
irb(main):003:0> user.password_confirmation = 'charles'
=> "charles"
irb(main):004:0> user.save
=> false
irb(main):005:0> user.password = 'charles123'
=> "charles123"
irb(main):006:0> user.password_confirmation = 'charles123'
=> "charles123"
irb(main):007:0> user.save
=> true
irb(main):008:0> exit
root@1b10f96444f4:/#exit
exit


其實用 deb 安裝完 gitlab-ce 後..
efault admin account has been configured with following details:
Username: root
Password: You didn't opt-in to print initial root password to STDOUT.
Password stored to /etc/gitlab/initial_root_password. This file will be cleaned up in first reconfigure run after 24 hours.
所以,應該去這裡(/etc/gitlab/initial_root_password) 看...


官方的應該是 .. gitlab docker,有啟動,hostname, password 的設置。
sudo docker run --detach \
  --hostname gitlab.example.com \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
  gitlab/gitlab-ee:latest
要先export GITLAB_HOME

另外,lfs 要enable 要修改 gitlab.rb

tio - 另一個 serial port (tty) 連線軟

用 apt 就可以安裝,跟 picocom 類似。
Usage: tio [] 

Options:
  -b, --baudrate         Baud rate (default: 115200)
  -d, --databits 5|6|7|8      Data bits (default: 8)
  -f, --flow hard|soft|none   Flow control (default: none)
  -s, --stopbits 1|2          Stop bits (default: 1)
  -p, --parity odd|even|none  Parity (default: none)
  -o, --output-delay      Output delay (default: 0)
  -n, --no-autoconnect        Disable automatic connect
  -l, --log         Log to file
  -m, --map            Map special characters
  -v, --version               Display version
  -h, --help                  Display help

See the man page for list of supported mapping flags.

In session, press ctrl-t q to quit.

連線中,用 hotkey...
[tio 10:33:36] Key commands:
[tio 10:33:36]  ctrl-t ?   List available key commands
[tio 10:33:36]  ctrl-t b   Send break
[tio 10:33:36]  ctrl-t c   Show configuration
[tio 10:33:36]  ctrl-t h   Toggle hexadecimal mode
[tio 10:33:36]  ctrl-t l   Clear screen
[tio 10:33:36]  ctrl-t q   Quit
[tio 10:33:36]  ctrl-t s   Show statistics
[tio 10:33:36]  ctrl-t t   Send ctrl-t key code

2020/5/13

mmwave studio , lua script

mmWave Studio 提供 Lua shell, 可以 load and run lua script。
參考 studio 的 demo script,和 openradar 的 script,合併成一個可以用 studio 的 postprocess 的 capture script.

ar1.XX 的function 沒有文件,只有在 lua shell 用 help 命令查看一下,要列出所有function 也不行 (我不知道方法)

初始化
ar1.FullReset()
ar1.SOPControl(2)
ar1.Connect(15,921600,1000)
ar1.DownloadBSSFw("C:\\ti\\mmwave_studio_02_00_00_02\\mmWaveStudio\\Scripts\\..\\..\\rf_eval_firmware\\radarss\\xwr16xx_radarss.bin")
ar1.DownloadMSSFw("C:\\ti\\mmwave_studio_02_00_00_02\\mmWaveStudio\\Scripts\\..\\..\\rf_eval_firmware\\masterss\\xwr16xx_masterss.bin")
ar1.PowerOn(1,1000,0,0)
ar1.RfEnable()
設定Chirp, Frame and Capture Parameters
先看一下說明...
Int32 ar1.ChanNAdcConfig(UInt16 Tx0En, UInt16 Tx1En, UInt16 Tx2En, UInt16 Rx0En, UInt16 Rx1En, UInt16 Rx2En, UInt32 Rx3En, Int32 BitsVal, UInt32 FmtVal, UInt32 IQSwap) 
    -  Static device config API which defines configure both the Transmiter and Reciever channels of Radar device and also ADC data format output
_I_ UInt16 Tx0En  - Tx0 channel
_I_ UInt16 Tx1En  - Tx1 channel
_I_ UInt16 Tx2En  - Tx2 channel
_I_ UInt16 Rx0En  - Rx0 channel
_I_ UInt16 Rx1En  - Rx1 channnel
_I_ UInt16 Rx2En  - Rx2 channel
_I_ UInt32 Rx3En  - Rx3 channel[b15:0] + (CascadePinOutCfg[b31:16] b16:ClkOutMasterDis, b17:SynOutMasterDis, b18:ClkOutSlaveEna, b19:SynOutSlaveEna, b20:IntLOMasterEna, b21:OSCClkOutMasterDis)
_I_ Int32 BitsVal  - Number of ADC bits
_I_ UInt32 FmtVal  - ADC output format[b15:0] + FullScaleReductionFactor[b31:16]
_I_ UInt32 IQSwap  - ADC Mode[b15:0] + CascadeMode[b31:16](Single Chip: 0x0000, MultiChip Master:0x0001, MultiChip Slave:0x0002)



Int32 ar1.LPModConfig(Int32 AnaChan, Int32 LpAdcMod)
    - LP Mod Config API which defines both Configure the ADC Mode and analog filter channel format
_I_ Int32 AnaChan  - Analog filter Chananel
_I_ Int32 LpAdcMod  - ADC Mode

command ...
ar1.ChanNAdcConfig(1, 1, 0, 1, 1, 1, 1, 2, 1, 0)
ar1.LPModConfig(0, 1)
ar1.RfInit()

2020/5/5

mmwave sdk 3.4, build demo project

好像沒有用 3.4 的 project (能 import) 的,所以只好用 command line build..
結果出現 Error:
[R4 Device/Type: iwr68xx/xwr68xx] Building file: ./mss/mss_main.c
"./mss/mss_main.c", line 1853: error: identifier "SOC_XWR16XX_MSS_ADCBUF_BASE_ADDRESS" is undefined
SOC_XWR16XX_MSS_ADCBUF_BASE_ADDRESS 定義在 /common/sys_common_xwr16xx_mss.h
included in ./common/sys_common_xwr16xx.h:
#if (defined(SOC_XWR16XX))

#ifdef SUBSYS_MSS
#include 
#endif

所以要找 SOC_XWR16XX 有沒有 define:
mmwave_sdk.mak:# PLATFORM_DEFINE       : SOC_XWR14XX, SOC_XWR16XX, SOC_XWR18XX, SOC_XWR68XX
mmwave_sdk_xwr16xx.mak:PLATFORM_DEFINE         = SOC_XWR16XX
mmwave_sdk.make:
ifeq ($(MMWAVE_SDK_DEVICE), awr14xx)
include $(MMWAVE_SDK_INSTALL_PATH)/ti/common/mmwave_sdk_xwr14xx.mak
else ifeq ($(MMWAVE_SDK_DEVICE), awr16xx)
include $(MMWAVE_SDK_INSTALL_PATH)/ti/common/mmwave_sdk_xwr16xx.mak
..
所以要找 MMWAVE_SDK_DEVICE..



最後用 diff 的方式,找到.. setenv.bat
@REM Select your device. Options (case sensitive) are: awr14xx, iwr14xx, awr16xx, iwr16xx, awr18xx, iwr18xx, awr68xx, iwr68xx
set MMWAVE_SDK_DEVICE=iwr68xx
要改 awr16xx

這樣就成功了...
call C:/ti/mmwave_sdk_03_04_00_03/packages\scripts\ImageCreator\append_bin_crc\gen_bincrc32.exe xwr16xx_mmw_demo.bin

2020/5/4

yield in python

Python 的另一個 function return(?) 指令 : yield

和 return 不一樣的是..
return 後,function 就退出了。
yield 的話,function 暫停 (或是說suspend了),把 yield 值交給 caller。
然後用 next( ) 時,這格 function 會從 上次 暫停 (也就是 yield) 的地方繼續下去...

>>>def new_range(n):
...   print('start')
...   i = 0
...   while i < n:
...      print('a')
...      yield i
...      i += 1
...
...c = new_range(10)
...print(next(c))
start
a
0
...print(next(c))
a
1
可以對照一下function 內的 print('start') 和 print('a') 出現的位置。

實際上,yield 可以用來產生一個 range list 的 iterator,直接拿來用,而不用真的把整個 list 先做出來

用 yield 的 function 還有一些其他功能,可以參考這一篇