FOTA升級差分包編譯服務器搭建

奈何公司測試組電腦沒有Linux系統,每次測試FOTA升級用的差分包都須要找我來製做,實在麻煩。本想搞個QT界面弄得專業點,後面有時間再去搞吧,如今打算先臨時寫一個應急。 html

1、Ubuntu端先搭建FTP服務器

參考以前搭建的記錄 Ubuntu14.04搭建FTP服務器記錄 - chenwr2018的博客 - CSDN博客 blog.csdn.net/chenwr2018/…java

由於還沒實現多人同時製做差分包的功能,爲了保證編譯過程當中不受影響,服務端限制了客戶端的鏈接數。 保證當前服務器只有一個IP鏈接,而且一個IP只有2個客戶端鏈接數,一個用來上傳文件,一個用來下載。 只需在vsftpd.conf中添加以下內容,重啓服務便可。linux

max_clients=2shell

max_per_ip=1ubuntu

2、Inotify工具

Inotify 是一個 Linux特性,它監控文件系統操做,好比讀取、寫入和建立。Inotify 反應靈敏,用法很是簡單,而且比 cron 任務的繁忙輪詢高效得多。windows

inotify C接口使用辦法,參考以下博客:bash

linux inotify功能和用法 - Android 系統&&驅動開發 - CSDN博客 blog.csdn.net/u013377887/…服務器

1.安裝Inotify工具

sudo apt-get install inotify-toolsapp

2.參數說明

inotifywait異步

語法:
inotifywait [-hcmrq] [-e ] [-t ] [--format ] [--timefmt ] [ ... ]
參數:
-h,--help
輸出幫助信息
@
排除不須要監視的文件,能夠是相對路徑,也能夠是絕對路徑。
--fromfile 
從文件讀取須要監視的文件或排除的文件,一個文件一行,排除的文件以@開頭。
-m, --monitor
接收到一個事情而不退出,無限期地執行。默認的行爲是接收到一個事情後當即退出。
-d, --daemon
跟--monitor同樣,除了是在後臺運行,須要指定--outfile把事情輸出到一個文件。也意味着使用了--syslog。
-o, --outfile 
輸出事情到一個文件而不是標準輸出。
-s, --syslog
輸出錯誤信息到系統日誌
-r, --recursive
監視一個目錄下的全部子目錄。
-q, --quiet
指定一次,不會輸出詳細信息,指定二次,除了致命錯誤,不會輸出任何信息。
--exclude 
正則匹配須要排除的文件,大小寫敏感。
--excludei 
正則匹配須要排除的文件,忽略大小寫。
-t , --timeout 
設置超時時間,若是爲0,則無限期地執行下去。
-e , --event 
指定監視的事件。
-c, --csv
輸出csv格式。
--timefmt 
指定時間格式,用於--format選項中的%T格式。
--format 
指定輸出格式。
%w 表示發生事件的目錄
%f 表示發生事件的文件
%e 表示發生的事件
%Xe 事件以「X"分隔 %T 使用由--timefmt定義的時間格式 複製代碼

inotifywatch

語法:
inotifywatch [-hvzrqf] [-e ] [-t ] [-a ] [-d ] [ ... ]
參數:
-h, --help
輸出幫助信息
-v, --verbose
輸出詳細信息
@
排除不須要監視的文件,能夠是相對路徑,也能夠是絕對路徑。
--fromfile 
從文件讀取須要監視的文件或排除的文件,一個文件一行,排除的文件以@開頭。
-z, --zero
輸出表格的行和列,即便元素爲空
--exclude 
正則匹配須要排除的文件,大小寫敏感。
--excludei 
正則匹配須要排除的文件,忽略大小寫。
-r, --recursive
監視一個目錄下的全部子目錄。
-t , --timeout 
設置超時時間
-e , --event 
只監聽指定的事件。
-a , --ascending 
以指定事件升序排列。
-d , --descending 
以指定事件降序排列。

可監聽事件
access	文件讀取
modify	文件更改。
attrib	文件屬性更改,如權限,時間戳等。
close_write	以可寫模式打開的文件被關閉,不表明此文件必定已經寫入數據。
close_nowrite	以只讀模式打開的文件被關閉。
close	文件被關閉,無論它是如何打開的。
open	文件打開。
moved_to	一個文件或目錄移動到監聽的目錄,即便是在同一目錄內移動,此事件也觸發。
moved_from	一個文件或目錄移出監聽的目錄,即便是在同一目錄內移動,此事件也觸發。
move	包括moved_to和 moved_from
move_self	文件或目錄被移除,以後再也不監聽此文件或目錄。
create	文件或目錄建立
delete	文件或目錄刪除
delete_self	文件或目錄移除,以後再也不監聽此文件或目錄
unmount	文件系統取消掛載,以後再也不監聽此文件系統。
複製代碼

3.實際測試

Ubuntu端

root@chenwr-pc:/home# inotifywait -rm /home/workspace/project/Build_FOTA/EC20-delta-gentools
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ OPEN 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ MODIFY 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ MODIFY 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ CLOSE_WRITE,CLOSE 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ OPEN 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,CLOSE 233
複製代碼

PC端

發送文件至Ubuntu端FTP服務器

E:\windows_to_linux_FTP
ftp> open 192.168.1.35
鏈接到 192.168.1.35。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
ftp> user FTP
331 Please specify the password.

230 Login successful.
ftp> put 1.zip /home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/666
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 發送 252 字節,用時 0.00秒 252000.00千字節/秒。
ftp> put 1.zip /home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/233
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 發送 252 字節,用時 0.00秒 252.00千字節/秒。
ftp>
複製代碼

保存日誌

inotifywait -rm /home/workspace/project/Build_FOTA/EC20-delta-gentools | tee /var/log/ftp_message

後續直接經過管道來逐行讀取就好,就不必寫到文件中。主要目的是判斷FTP接受文件完畢。

個別電腦運行的時候會出現

緣由是

find %ftplog% "Failed to establish connection" > C:\null 重定向到C盤致使 能夠修改成其餘盤符,好比find %ftplog% "Failed to establish connection" > E:\null

使用該監控文件變化會出現一個問題,PC端FTP傳輸數據都是小塊小塊的傳輸

/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,CLOSE 233
複製代碼

因此腳本執行的條件仍是判斷關鍵語句吧 /home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE

3、完整的demo

1.ubuntu端shell腳本

測試代碼: auto_build_fota.sh

#!/bin/sh
sleep 5 # wait server start
BUILD_FOTA="/home/workspace/project/Build_FOTA/EC20-delta-gentools"
SCRIPT="./update_gen.sh a"
content1="/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ CLOSE_WRITE,CLOSE targetfiles.zip"
content2="/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,CLOSE targetfiles.zip"
flag=0;
log=$BUILD_FOTA/log
echo "start auto build fota script" > $log
/usr/bin/inotifywait -rm $BUILD_FOTA \
| while read line
do
    if [ "$line" = "$content1" ]; then
        echo $(date)
        echo $line >> $log
        echo "recv targetfiles.zip suc from client pc" >> $log
        flag=1
    fi
    if [ "$line" = "$content2" ] && [ $flag = 1 ] ; then
        flag=0
        echo $line >> $log
        cd $BUILD_FOTA
        echo "cur path $(pwd)" >> $log
        echo "start build time: $(date)" >> $log
        $SCRIPT 2>&1 | tee -a $log
        if [ $? != 0 ]; then
            echo "Build Script run failded!" >> $log
        else
            echo "Build Script run success!" >> $log
            echo "Build end time: $(date)" >> $log
            cp $BUILD_FOTA/mainapp* $BUILD_FOTA/bak
            echo "60 sec after to delete mainapp_fota" >> $log
            sleep 60
            rm -f $BUILD_FOTA/mainapp*
            if [ $? != 0 ]; then
                echo "mainapp delete failed" >> $log
            else
                echo "mainapp delete success" >> $log
            fi
        fi
    fi
done
複製代碼

/usr/bin/inotifywait -rm $BUILD_FOTA | while read line 逐行讀取監控目錄的信息,一旦有新文件產生會有信息產生。經過判斷關鍵語句/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,得出該文件FTP傳輸結束,緊接着觸發編譯腳本。

設置該腳本開機自啓 簡單在/etc/rc.local文件中添加要啓動的腳本

2.PC端bat腳本

(1)auto_build_fota.bat腳本

@echo off
title mainapp_fota差分包編譯工具
mode con lines=20 cols=55
color 3f
echo.
echo             請不要關閉此窗口,耐心等待!!!
echo.

set file1=1.zip
set file2=2.zip
set ftplog=ftp_log
set ftpfilename=ftp.cfg

set b=%cd%
echo %b%
if exist %file1% (
	if exist %file2% (
		echo 文件上傳中......
		goto ftp_upload
	) else (
		echo %file2% is not exist!
		pause
		exit
	)
) else (
    echo %file1% is not exist!
	pause
	exit
)

:ftp_upload
echo open 192.168.1.35>"%ftpfilename%" 
echo user ftp>>"%ftpfilename%" 
echo 123456>>"%ftpfilename%"
echo.>>"%ftpfilename%"
echo put %file1% /home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/targetfiles.zip>>"%ftpfilename%"
echo put %file2% /home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/targetfiles.zip>>"%ftpfilename%"  
echo bye >>"%ftpfilename%" 
ftp -n -s:"%ftpfilename%" >"%ftplog%" 
del "%ftpfilename%"

find %ftplog% "Failed to establish connection" > E:\null
if "%errorlevel%"=="0" (
	goto firewall_error
) else (
	echo targetfiles.zip 文件上傳成功!
	echo.
	goto progress_bar_compile
	pause
)
goto:eof


:ftp_download
echo open 192.168.1.35>"%ftpfilename%" 
echo user ftp>>"%ftpfilename%" 
echo 123456>>"%ftpfilename%"
echo.>>"%ftpfilename%"
echo mget /home/workspace/project/Build_FOTA/EC20-delta-gentools/mainapp* >>"%ftpfilename%"
echo.>>"%ftpfilename%"
echo bye >>"%ftpfilename%" 
ftp -n -s:"%ftpfilename%" >>"%ftplog%"
del "%ftpfilename%"
find %ftplog% "mainapp_" > C:\null
IF ERRORLEVEL 1 goto download_error
echo mainapp_fota 文件下載成功!
pause
goto:eof

:progress_bar_compile
cls
set a=^set /p=■^<nul^&ping/n 2 127.1^>nul^&
echo.
echo   正在編譯中...... 
echo.
echo ┌──────────────────────────────────────┐
set/p= &emsp;<nul&%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%
echo    100%%
echo └──────────────────────────────────────┘
echo 編譯成功!!!
goto ftp_download
pause
goto:eof

:upload_error
echo 文件上傳失敗
pause
goto:eof

:firewall_error
echo 請關閉windows防火牆後,從新運行腳本。
pause
goto:eof

:download_error
echo 獲取mainapp_fota失敗,請從新運行腳本。
pause
goto:eof

echo.
pause

複製代碼

(2)腳本簡單說明

1.mode con lines=20 cols=55 是設置你批處理運行時窗口大小的

2.使用了 @echo off 以後就無需再用 @;命令前加@符號,表示不顯示@後面的命令。舉一個不和諧的例子:在入侵過程當中(使用批處理來格式化敵人的硬盤)天然不能讓對方看到你使用的命令啦。

3.FTP參數說明

FTP [-v] [-d] [-i] [-n] [-g] [-s:filename] [-a] [-A] [-x:sendbuffer] [-r:recvbuffer] [-b:asyncbuffers] [-w:windowsize] [host]

  -v              禁止顯示遠程服務器響應。
  -n              禁止在初始鏈接時自動登陸。
  -i              關閉多文件傳輸過程當中的
                  交互式提示。
  -d              啓用調試。
  -g              禁用文件名通配(請參閱 GLOB 命令)。
  -s:filename     指定包含 FTP 命令的文本文件;命令
                  在 FTP 啓動後自動運行。
  -a              在綁字數據鏈接時使用全部本地接口。
  -A              匿名登陸。
  -x:send sockbuf 覆蓋默認的 SO_SNDBUF 大小 8192。
  -r:recv sockbuf 覆蓋默認的 SO_RCVBUF 大小 8192。
  -b:async count  覆蓋默認的異步計數 3
  -w:windowsize   覆蓋默認的傳輸緩衝區大小 65535。
  host            指定主機名稱或要鏈接到的遠程主機
                  的 IP 地址。

注意:
  - mget 和 mput 命令將 y/n/q 視爲 yes/no/quit。
  - 使用 Ctrl-C 停止命令。
複製代碼

將FTP相關ip密碼等信息寫入文件中,再經過-s參數去實現命令自動運行。

4.echo.爲換行,因mget會能夠模糊從FTP服務器上傳輸文件,若是FTP服務器存在多個前綴相同的文件時此時就須要回車來確認,所以須要記得mget語句寫入文件後再增長個echo.

5.程序返回碼 echo %errorlevel% 每一個命令運行結束,能夠用這個命令行格式查看返回碼 用於判斷剛纔的命令是否執行成功 默認值爲0,通常命令執行出錯會設 errorlevel 爲1 if "%errorlevel%"=="0" ( goto firewall_error ) else ( echo No Run )

6.bat亂碼問題,在文件右鍵用「編輯」打開, 另存爲時,UTF-8保存爲ANSI格式。便可解決運行是亂碼問題。

7.pc端將FTP運行結果保存到文件中,可經過對文件的關鍵字來判斷FTP的運行狀態。

(3)BAT腳本如何判斷文件是否存在?

SET file1=1.zip
SET file2=2.zip
echo 文件上傳中......
set b=%cd%
echo %b%
if exist %file1% (
	echo %file1% is exist!
) else (
    echo %file1% is not exist!
)
if exist %file2% (
	echo %file2% is exist!
) else (
    echo %file2% is not exist!
)
複製代碼

(4)bat如何編寫函數

bat 腳本之 使用函數 - caopeng的專欄 - CSDN博客 blog.csdn.net/peng_cao/ar…

格式 :func 函數內部動做 goto:eof

實例

@echo off
@title copy sth to current filepath
mode con lines=5 cols=40

SET SourceFile=1.zip
SET GenFile1=2.zip

if exist %SourceFile% (
    if not exist %GenFile1% (
        echo %GenFile1% is no exist!
		call:hello
    ) else (
        echo %GenFile1% is exist!
    )
) else (
    echo %SourceFile% is not exist!
)

:hello
echo hello world
pause
goto:eof
echo Success
ping -n 3 127.0.0.1 > nul
pause
複製代碼

使用call會繼續執行一次函數,goto就不會。

(5)bat腳本for循環

指定次數循環 FOR /L %variable IN (start,step,end) DO command [command-parameters] 組合命令: FOR /L %variable IN (start,step,end) DO ( Command1 Command2 …… )

(6)進度條簡單實例

(如今還不清楚進度條如何同步,正在編譯的狀態暫時按照時間來計時。)

@echo off
cls
set a=^set /p=■^<nul^&ping/n 1 127.1^>nul^&

echo.
echo   正在編譯中...... 
echo.
echo ┌──────────────────────────────────────┐
:cycle
for %%i in (■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■) do (set/p=<nul&%a% goto jindu)
goto:eof
echo    100%%
echo └──────────────────────────────────────┘
echo 編譯成功!!!
pause
:jindu

goto cycle
goto:eof

複製代碼

4、參考資料

bat批處理修改cmd窗口大小、標題、字體、背景顏色 - zj0910 - CSDN博客 blog.csdn.net/zj0910/arti…

.bat文件中call命令的用法 - 村長 - CSDN博客 blog.csdn.net/a_little_a_…

在程序裏調用ftp批處理(sh)上傳文件,如何判斷文件已成功上傳-CSDN論壇 bbs.csdn.net/topics/8045…

利用windows系統ftp命令編寫的BAT文件上傳[轉] - 風之語 - BlogJava www.blogjava.net/gf7/archive…

FTP返回值詳解 - pgmsoul的專欄 - CSDN博客 blog.csdn.net/pgmsoul/art…

[轉]Bat腳本處理ftp超強案例解說 - 是誰啊? - 博客園 www.cnblogs.com/hanxianlong…

bat命令入門與高級技巧詳解_DOS/BAT_腳本之家 www.jb51.net/article/972…

inotify-tools使用方法介紹 - wangkangluo1 - 博客園 www.cnblogs.com/wangkangluo…

Linux下的文件更新觸發同步 - kenyon的我的頁面 - OSCHINA my.oschina.net/Kenyon/blog…

FTP命令詳解(含操做實例) - IndexMan的專欄 - CSDN博客 blog.csdn.net/indexman/ar…

mget命令, ftp命令詳解 - wajika - 博客園 www.cnblogs.com/wajika/p/64…

相關文章
相關標籤/搜索