2025年7月7日 星期一

[Drone]無人機 研究紀實

自從考取無人機普通操作證後 

買了一台Holybro的x500 v2(23000)來自我研究


目前買了8000mAh 90C(1700元)電池與塔圖TATTU - 1500mAh(9xx元)

準備當其主要電池與備用電池,在確定自己可以起飛之前就先這樣了

接收機 使用 radiomaster的V86 c2 (390)並已在 25/7/7 跟遙控器 radiomaster S16 MKII (6300)配對上

太過近時會出現通訊中斷的警告 = >  (尚須分析)

接下來我想就是QGroundControl與Mission Planner的配置 還有遙控器的對頻與起飛設定了

我想這個就是調參(參數調整)吧

2023年9月22日 星期五

[C++ ]Poco資料寫入資料庫SQLite解析

  Poco::Data::SQLite::Connector::registerConnector();

    // 建立会话

    Session session("SQLite", "sample.db");

    // 如果有名為abc的表存在,删除

    session << "DROP TABLE IF EXISTS abc", now;

    // 創建Table

    session << "CREATE TABLE abc (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now;

     Statement insert(session);

  //塞一筆資料 #略#

for(int i=0; i<=65535; i++)

{

    insert << "INSERT INTO abc VALUES(?, ?, ?)",use(abc.name),use(abc.address),use(abc.age);

   //在這裡每插入一筆資料 必須使用insert.exexute(); 並執行execute方法

    insert.execute();

}
當使用for loop 時 insert必須都在括弧內宣告及處理,execute使用for loop會造成效能低下

65536筆跑完必須耗時10分鐘

有關于SQLite批量寫入資料耗時的問題有很多帖子可以找

我找到這篇Reference : https://blog.darkthread.net/blog/sqlite-insert-slow/


在UnitTest時 為了達到65536筆資料來滿足line coverage必須花不少時間,因此需要介紹以下的批量寫入

在訪問了Bing大神後(Bing也有推薦此篇文章 : Poco插入大量数据到数据库的优化 | xilixili.net),有找到一種寫法 說是批量寫入需要靠"事務"進行優化

其範例程式碼如下 : 

Poco::Data::Session sess("SQLite", "test.db");
sess << "create table if not exists test ("
        " [col_a] NVARCHAR (256) NOT NULL,"
        " [col_b] NVARCHAR (256) NOT NULL)",
    Poco::Data::Keywords::now;
 
sess.begin();  <=============================重點在這兩筆
for (size_t i = 0; i < 65535; i++) {
    char bufa[64] = {0};
    char bufb[64] = {0};
    sprintf(bufa, "test col a %d %d", i, rand());
    sprintf(bufb, "test col b %d %d", i * 2, rand());
    sess << "insert into test (col_a,col_b) values (?,?)",
        Poco::Data::Keywords::use(bufa),
        Poco::Data::Keywords::use(bufb),
        Poco::Data::Keywords::now;
}
sess.commit();  <=============================重點在這兩筆

中間筆數內的詳細資訊可以略過,因個人專案不同而已 當使用for loop進行插入前後必須宣告

sess.begin(); 以及 sess.commit(); 便可快速且大量塞入資料至Poco資料庫SQLite中


2023年8月31日 星期四

[C++]C++筆記

推薦閱讀書單&網路資源

1.C++ Primer 5th

2.C++ Standard Library headers

3.語言技術:C++ Gossip

字串

reference : https://shengyu7697.github.io/std-string-substr/

using std::string;

std::string::substr  取出子字串

範例 : substr(從第幾個字節之後開始,的多少個字截截取)

std::string abc_str = "hello"

abc_str.substr(1); //扣掉第一個印出後面的 ello

abc_str.substr(1,2); //扣掉第一個印出後面兩個 el 

string m("ssx"); == string m = "ssx";

 

>> //input

<< //Output message

endl = println = \n


abcManager::abcManager(Poco::Logger &L):_logger(L)

初始化


資料型別

using namespace std; //引入標準類別庫   可使用string  => std::string aa = "";

using namespace xxx::yyy

也可寫成

using xxx:yyy

nullptr : 指標字面值

指標宣告

1.shared_ptr宣告方法 

reference :https://cplusplus.com/reference/memory/shared_ptr/operator%20bool/

h檔全宣告方式std::shared_ptr<CppObjName> abc = std::shared_ptr<CppObjName>();

h檔半宣告方式std::shared_ptr<CppObjName> abc;

cpp檔 new : abc = std::shared_ptr<CppObjName>();

abc = NULL;



p_ptr* = NULL;


2.auto_ptr宣告方法

reference :https://openhome.cc/Gossip/CppGossip/autoPtr.html

3.h檔宣告

h檔半宣告 : abc* a;

cpp檔 new : a = new abc();

[VS code]VS code 環境設定 與 好用套件&熱鍵教學

1.Code Runner 
 2.RemoteSSH 
 3.C/C++ 
 4.C/C++ Extension Pack 
 5.C/C++ Themes 
 6.GitLens -- Git supercharged 





 搜尋關鍵字在workspace的使用 雙擊(滑鼠圈選關鍵字) + Ctrl + Shift + F

2022年9月9日 星期五

[MCU開發]解決S32K編譯時發生VMA error

 Description Resource Path Location Type Ld error: section .stack VMA [20002c00,20002fff] overlaps section .heap VMA Meter_AS_MCU C/C++ Problem

"c:/nxp/s32ds_arm_v2.2/s32ds/build_tools/gcc_v6.3/gcc-6.3-arm32-eabi/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/real-ld.exe: section .stack VMA [20002d00,20002fff] overlaps section .heap VMA [20002a58,20002d57]"

這問題描述主要說的是./stack跟heap去重疊到

導致編譯錯誤


解法如下 : 

開啟S32 Design Studio 開啟專案的Project Settings->Linker files

點選S32K1xx_32_ram.ld


HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00000400;

STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00000400;

並在以下資料夾入前綴 : __attribute__ ((section(".data"))) 如下 : 

 __attribute__ ((section(".data")))m_interrupts          (RX)  : ORIGIN = 0x1FFFC000, LENGTH = 0x00000400

  __attribute__ ((section(".data")))m_text                (RX)  : ORIGIN = 0x1FFFC400, LENGTH = 0x00003C00

  /* SRAM_U */

  __attribute__ ((section(".data")))m_data                (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00003000

接著在S32K1xx_32_flash.ld

動態調整heap size跟stack size 如下 : 

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00000300;

STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00000300;

即可解決

另一種暴力的方式如下 : 

#define VAR_PUT_IN_DATA_SECTION    __attribute__((section(".data")))

2022年8月24日 星期三

[嵌入式系統]開機的順序與記憶體的跳換

開機的順序為bootloader->u-boot

bootloader 可以想像成是PC開機到windows前的GRUB開機管理程式

ARM 結構的 CPU 會從位址 0x00000000 開始執行

但是bootloader是更底層

Bootloader會針對SoC的clock rate做初始化 以及Ram的初始化

透過memory map執行跳躍到u-boot區段

其中記錄開機後bootloader載入的區段,接著u-boot 是linux提前載入的程式階段在此階段會存在很多小工具讓使用診進行診斷或使用 - busybox。

其主要程式為Start.s,分為boot loading模式及下載模式,下載模式可使用一些指令下載,如xmodem, tftp, usb等 並將其存至Ram或Flash固存中。其中透過調用lowlevel_init.S的lowlevel_init進行u-boot相關的低階初始化。

接著跳轉到kernel 這段就是linux的核心層 也就是linux最基礎的功能包含driver的環境


kernel層完之後會根據參照及傳遞值跳躍到application層。


一但到application層即代表 已經開至Userspace上層

[C語言]Stack堆疊與Heap堆積的差別

https://www.twblogs.net/a/5d1b5c70bd9eee1e5c8311ef


 Stack 與 Heap 皆為C語言中處理底層記憶體的技術


Stack是有順序的疊加


Heap則會找空的疊加


Heap需要考慮到空間釋放的問題 (GC回收機制)

2021年7月15日 星期四

[Windows] 使用ffmpeg對mp4影片進行轉檔合併

Reference : 如何在Windows 10下合併多個MP4檔案的字幕和影片 - 銳力電子實驗室 (reneelab.net)


Step1 : cd D:

Step2 : cd ffmpeg/

Step3 : cd bin/

Step4 : ffmpeg.exe -i D:/1.mp4 –f mpeg D:/1.mpg

Step5 : ffmpeg.exe -i D:/2.mp4 –f mpeg D:/2.mpg

Step6 : cd ../../

Step7 : copy /b “D:/1.mpg”+”D:/2.mpg” “D:/3.mpg”

Step8 : ffmpeg.exe -i D:/3.mpg -f mp4 D:/3.mp4

2021年4月6日 星期二

[C語言韌體]微控制器(MCU)開發雜記








C語言在MCU的開發上使用while迴圈去進行大循環
常見會有while(1){...}的用法
有時候也會出現for( ; ; ) {...}的用法 跟while(1)是一樣的


20210506 更新 do{ ... }while(0)的妙用
do                                                                                             
{                                                                                              
        code statement                                                              
} while (0)

今天在看nRF52-DK 的code時看到官方定義的code出現此環節,一般來說,mcu會以上述while(1) 或for( ; ; ) 來進行無限迴圈的應用,以do{...}while(0)的定義並不是要做無窮迴圈應用為何還是這樣使用呢? 本來以為是coding style習慣問題,在參考完下述連結後,有更多此妙用的介紹。

好處是必執行外,不需要多餘的if else壟餘code 也避免goto的危險性








使用Trace32 debug
 
 





















 












 
 
 















因葦
k
ll
lll
 
 
 

2021年3月18日 星期四

[WINDOWS] FileZilla Server(FTP伺服器)架設

Reference : https://blog.xuite.net/yh96301/blog/62868611-%E5%85%8D%E8%B2%BB%E7%9A%84FTP%E4%BC%BA%E6%9C%8D%E5%99%A8FileZilla+Server 

官網下載網址 : https://filezilla-project.org/

點選 Download File Zilla Server

下載後 一直下一步已完成安裝

(架設 host 輸入localhost 或是 127.0.0.1)

安裝完後 點選 close

接著點選File Zilla Server Interface進入主程式

輸入密碼 或不用輸入 點選Connect 登入


點選單人頭圖標進入User

在右方Users 按下Add 並加入使用者

接著在中間Account Setting 勾選 Enable account 及 Password

接著點選左邊的Shared Folder 後 並點選中間的Add 加入使用者允許存取的本機路徑後 將所有存取權限打勾

按下ok即生效



防火牆

搜尋 允許應用程式通過Windows防火牆

並點選上方的變更設定賦予 管理者權限 接著選到 安裝目錄下的 FileZillaServer.exe ,輸入後按下確定關閉視窗 - '允許應用程式通過Windows防火牆' 即可。


NAT設定 : 網路位址轉換(英語:Network Address Translation,縮寫:NAT;又稱網路掩蔽、IP掩蔽)