国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Ardupilot移植的深入細節分享

RTThread物聯網操作系統 ? 來源:驚覺嵌入式 ? 作者:驚覺嵌入式 ? 2021-04-30 16:14 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

接Ardupilot移植經驗分享(2)

深入細節

是時候深入具體的HAL接口了。筆者并不打算一一講解所有的接口,而是挑選一些有代表性的來分析,主要的內容是:

分析HAL接口的含義,包括功能,入參及返回值的具體含義。

分析HAL_PX4的實現,看看有沒有可借鑒之處。

調度接口

AP_HAL::Scheduler提供了程序調度相關的接口。主要分為兩類:

延時函數

注冊回調

延時函數有3個,1個毫秒級延時,2個微秒級延時。這里的延時可不是死等,而是睡眠一段時間,在此期間讓出CPU的使用權以執行其他的線程。

virtual void delay(uint16_t ms) = 0;

virtual void delay_microseconds(uint16_t us) = 0;

virtual void delay_microseconds_boost(uint16_t us) { delay_microseconds(us); }

看似簡單的delay

大家可能會覺得,delay是最簡單的,delay_microseconds會比較復雜。因為通常來說,毫秒級延時是RTOS的基礎API,比如RT-Thread的rt_thread_mdelay。

rt_err_t rt_thread_mdelay(rt_int32_t ms);

不過Scheduler::delay除了簡單的睡眠延時,還多了一項任務。這就要先提到注冊回調接口中的一個:

typedef void(*Proc)(void);

virtual void register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms) = 0;

這接口的功能是:注冊一個延時回調。當某個線程調用delay進行延時時,若延時的時間大于min_time_ms,則delay函數將會調用這個延時回調。

這延時回調的意義是,當你睡眠的時候,正好可以執行某一個指定的任務,不要浪費時間。你可能會想,RTOS的延時本就會讓出CPU,本就會讓別的線程得以執行,何必多此一舉呢?我們看看是誰注冊了這個回調。

其中之一是mavlink模塊。

hal.scheduler-》register_delay_callback(mavlink_delay_cb_static, 5);

7b10b000-a7f7-11eb-9728-12bb97331649.png

在這里插入圖片描述

注釋里面說明了原因,這是為了在長時間的初始化函數(setup)中能進行MAVLink交互。主要的MAVLink任務是在loop()中的AP_Scheduler調度系統中執行,就是紅圈部分(不過紅圈里面沒提到MAVLink,不要介意哈)。setup()是順序執行一系列的初始化函數,想在它里面去進行MAVLink任務,就靠這register_delay_callback了。

7b43b7ca-a7f7-11eb-9728-12bb97331649.png

我們再看看PX4的實現。延時的功能依賴于一個微秒級延時的接口delay_microseconds_semaphore,不過它每次只延時1000微秒,多余的時間會去執行延時回調。

7b7388a6-a7f7-11eb-9728-12bb97331649.png

微秒級延時delay_microseconds

筆者當初看到這接口時,有些頭疼。因為RT-Thread并沒有微秒級別的延時函數,再強調一遍,這不是死等,是要睡眠讓權的。

直接看PX4的實現:

void PX4Scheduler::delay_microseconds(uint16_t usec)

{

perf_begin(_perf_delay);

delay_microseconds_semaphore(usec);

perf_end(_perf_delay);

}

這是上節提到的delay_microseconds_semaphore的馬甲,脫了它:

7b82352c-a7f7-11eb-9728-12bb97331649.png

該函數使用hrt_call_after和信號量來完成微秒級睡眠的功能。hrt是High-resolution timer的縮寫,高精度定時器

調用hrt_call_after注冊一個定時器回調,定時時間是usec,單位微秒。回調函數是信號量發送函數sem_post,回調參數是信號量wait_semaphore。

使用sem_wait等待信號量wait_semaphore,此時當前線程會堵塞,進入睡眠狀態。

到達定時時間后,底層就執行這個回調,即sem_post(&wait_semaphore)。

sem_wait接收到了信號量wait_semaphore,該線程被喚醒。

結合時序圖來理解:

7bb9300e-a7f7-11eb-9728-12bb97331649.png

微秒級的延時函數,依賴于微秒級的定時回調,也就是hrt_call_after:

/**

* Call callout(arg) after delay has elapsed.

*

* If callout is NULL, this can be used to implement a timeout by testing the call

* with hrt_called()。

*/

__EXPORT extern void hrt_call_after(struct hrt_call *entry, hrt_abstime delay, hrt_callout callout, void *arg);

hrt_call_after屬于pixhawk底層的接口。筆者一度以為是Nuttx提供的功能,并且為RT-Thread沒有相應功能而煩惱。關于定時器,RT-Thread有類似的功能,那就是rt_timer,不過這是毫秒級的。

rt_timer_t rt_timer_create(const char *name,

void (*timeout)(void *parameter),

void *parameter,

rt_tick_t time,

rt_uint8_t flag)

可能你會想,一般單片機里面不是都有硬件定時器嗎?實現微秒級的定時功能很簡單啊。確實簡單,也不簡單。因為hrt_call_after提供的定時功能是要支持并發的,千言萬語不如一圖:

7bde807a-a7f7-11eb-9728-12bb97331649.png

至于pixhawk的實現以及筆者的移植,將專門出一篇文章來講解。

delay_microseconds_boost

這個同樣依賴于hrt_call_after,只是在睡眠的時候提高了優先級,以使得自己可在第一時間被喚醒。

注冊回調

virtual void register_timer_process(AP_HAL::MemberProc) = 0;

virtual void register_io_process(AP_HAL::MemberProc) = 0;

相對來說,這兩接口就簡單的多了。它們用于注冊在timer線程和io線程中運行的回調函數。

7c070de2-a7f7-11eb-9728-12bb97331649.png

注冊函數將回調指針加入到數組中。

7c17077e-a7f7-11eb-9728-12bb97331649.png

在相應線程中,定時的一一執行。

7c46c72a-a7f7-11eb-9728-12bb97331649.png

那么,這線程是怎么創建的呢?PX4Scheduler的初始化函數中,會創建許多線程。

void PX4Scheduler::init()

{

_main_task_pid = getpid();

// setup the timer thread - this will call tasks at 1kHz

pthread_attr_t thread_attr;

struct sched_param param;

pthread_attr_init(&thread_attr);

pthread_attr_setstacksize(&thread_attr, 2048);

param.sched_priority = APM_TIMER_PRIORITY;

(void)pthread_attr_setschedparam(&thread_attr, ?m);

pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO);

pthread_create(&_timer_thread_ctx, &thread_attr, &PX4Scheduler::_timer_thread, this);

// the UART thread runs at a medium priority

pthread_attr_init(&thread_attr);

pthread_attr_setstacksize(&thread_attr, 2048);

param.sched_priority = APM_UART_PRIORITY;

(void)pthread_attr_setschedparam(&thread_attr, ?m);

pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO);

pthread_create(&_uart_thread_ctx, &thread_attr, &PX4Scheduler::_uart_thread, this);

// the IO thread runs at lower priority

pthread_attr_init(&thread_attr);

pthread_attr_setstacksize(&thread_attr, 2048);

param.sched_priority = APM_IO_PRIORITY;

(void)pthread_attr_setschedparam(&thread_attr, ?m);

pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO);

pthread_create(&_io_thread_ctx, &thread_attr, &PX4Scheduler::_io_thread, this);

// the storage thread runs at just above IO priority

pthread_attr_init(&thread_attr);

pthread_attr_setstacksize(&thread_attr, 1024);

param.sched_priority = APM_STORAGE_PRIORITY;

(void)pthread_attr_setschedparam(&thread_attr, ?m);

pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO);

pthread_create(&_storage_thread_ctx, &thread_attr, &PX4Scheduler::_storage_thread, this);

}

pthread_attr_init,pthread_create,這些是POSIX的線程接口,由Nuttx提供。POSIX 是 “Portable Operating System Interface”(可移植操作系統接口) 的縮寫,POSIX 是 IEEE Computer Society 為了提高不同操作系統的兼容性和應用程序的可移植性而制定的一套標準。

好消息是,RT-Thread從3.0版本開始提供POSIX接口。所以,當我們移植的時候,很多地方可以參考AP_HAL_PX4的代碼,甚至是直接復制它的代碼。

串口驅動

AP_HAL的串口驅動框架由4個類組成,層層分工明確。

Print的功能,如其名稱,負責打印輸出。write系列為最底層的字節輸出接口,需要由具體的HAL平臺實現。print和println系列提供打印功能。所謂的打印,比如打印float,就是以字符格式輸出float。筆者只列了幾個print接口,實際上遠比這個多。

Stream定義了輸入接口,available返回接收緩存中的字節數,read用于讀取輸入。

BetterStream添加了格式化輸出的接口,即大家熟悉的printf系列。

UARTDriver引入了與串口相關的接口,begin用于配置波特率、輸入輸出緩存,set_flow_control和get_flow_control與流控相關。

7c5553ee-a7f7-11eb-9728-12bb97331649.png

在這里插入圖片描述

除了print系列函數由AP_HAL中的類實現,其他的功能,比如read, write, begin, flow_control,都要由具體的HAL平臺實現。PX4UARTDriver就是具體的實現類。

串口綁定

Ardupilot有6個串口,定義在AP_HAL::HAL之中。

AP_HAL::UARTDriver* uartA;

AP_HAL::UARTDriver* uartB;

AP_HAL::UARTDriver* uartC;

AP_HAL::UARTDriver* uartD;

AP_HAL::UARTDriver* uartE;

AP_HAL::UARTDriver* uartF;

PX4UARTDriver構造函數和set_device_path用于與具體的底層串口相綁定。HAL_PX4_Class.c中定義了綁定關系:

// 3 UART drivers, for GPS plus two mavlink-enabled devices

static PX4UARTDriver uartADriver(UARTA_DEFAULT_DEVICE, “APM_uartA”);

static PX4UARTDriver uartBDriver(UARTB_DEFAULT_DEVICE, “APM_uartB”);

static PX4UARTDriver uartCDriver(UARTC_DEFAULT_DEVICE, “APM_uartC”);

static PX4UARTDriver uartDDriver(UARTD_DEFAULT_DEVICE, “APM_uartD”);

static PX4UARTDriver uartEDriver(UARTE_DEFAULT_DEVICE, “APM_uartE”);

static PX4UARTDriver uartFDriver(UARTF_DEFAULT_DEVICE, “APM_uartF”);

read和write的實現

大家可能認為串口的讀寫是非常簡單的操作。其實不然,Ardupilot作為一個對實時要求很高的飛控程序,在應用層調用串口讀寫函數時,是不允許堵塞的。這需要一些額外的工作來實現。

PX4UARTDriver使用接收緩存和發送緩存來實現異步讀寫。

write是將數據寫入到發送緩存_writebuf之中。_writebuf是一個隊列,實質上是環形數組RingBuffer。

/*

write one byte to the buffer

*/

size_t PX4UARTDriver::write(uint8_t c)

{

if (_uart_owner_pid != getpid()){

return 0;

}

if (!_initialised) {

try_initialise();

return 0;

}

while (_writebuf.space() == 0) {

if (_nonblocking_writes) {

return 0;

}

hal.scheduler-》delay(1);

}

return _writebuf.write(&c, 1);

}

read從接收緩存中提取數據,若沒有則返回-1。

/*

read one byte from the read buffer

*/

int16_t PX4UARTDriver::read()

{

if (_uart_owner_pid != getpid()){

return -1;

}

if (!_initialised) {

try_initialise();

return -1;

}

uint8_t byte;

if (!_readbuf.read_byte(&byte)) {

return -1;

}

return byte;

}

將發送緩存的數據寫入串口和從串口接收數據以填充接收緩存的工作,在PX4UARTDriver::_timer_tick函數中實現。而所有串口的_timer_tick由一個統一的串口線程來調度。

void *PX4Scheduler::_uart_thread(void *arg)

{

PX4Scheduler *sched = (PX4Scheduler *)arg;

pthread_setname_np(pthread_self(), “apm_uart”);

while (!sched-》_hal_initialized) {

poll(nullptr, 0, 1);

}

while (!_px4_thread_should_exit) {

sched-》delay_microseconds_semaphore(1000);

// process any pending serial bytes

((PX4UARTDriver *)hal.uartA)-》_timer_tick();

((PX4UARTDriver *)hal.uartB)-》_timer_tick();

((PX4UARTDriver *)hal.uartC)-》_timer_tick();

((PX4UARTDriver *)hal.uartD)-》_timer_tick();

((PX4UARTDriver *)hal.uartE)-》_timer_tick();

((PX4UARTDriver *)hal.uartF)-》_timer_tick();

}

return nullptr;

}

看過前面高清大圖的,應該對這個有印象:

7c61c5b6-a7f7-11eb-9728-12bb97331649.png

SPI和I2C驅動

我們再看兩個驅動,SPI驅動和I2C驅動。這兩個驅動有很多共同之處:

都有總線的概念,一條總線掛接許多設備。

都有主從概念,每次傳輸由主機發起,由從機應答。

正是由于它們非常相似,Ardupilot提取出它們的共同之處,抽象成一個基類AP_HAL::Device。下圖是Device的類圖,并非包含其所有內容,僅列出了一些重要的元素。

7c6e6f3c-a7f7-11eb-9728-12bb97331649.png

在這里插入圖片描述

UML圖示說明

上圖為UML類圖。前面提到類圖的語法,這里做一點補充。

變量和函數左邊有顏色的符號表示訪問權限,綠色圓圈是public,黃色菱形是protected。

斜體函數為純虛函數,需要由子類實現。

transfer

Ardupilot的I2C和SPI驅動主要是用于與傳感器通信,所以Device類提供了兩個常用的接口:read_register和write_register,并且實現了它們。當然,這是基于transfer接口實現的,而transfer交由子類來實現,畢竟SPI和I2C的實現是不同的。

/*

* Core transfer function. This does a single bus transaction which

* sends send_len bytes and receives recv_len bytes back from the slave.

*

* Return: true on a successful transfer, false on failure.

*/

virtual bool transfer(const uint8_t *send, uint32_t send_len,

uint8_t *recv, uint32_t recv_len) = 0;

對于I2C來說,transfer實現的是先寫后讀。而對于SPI來說,transfer內部是同時讀寫。

SPIDevice和I2CDevice

7c8186d0-a7f7-11eb-9728-12bb97331649.png

它們添加了自身獨有的接口。

SPIDevice添加了全雙工的傳輸接口transfer_fullduplex,與transfer接口所不同之處在于發送和接收緩存的長度一致。

I2CDevice中,set_address用于設置地址,set_split_transfers指定在先寫后讀的中間是否傳輸停止位。

Periodic Callback

Device的功能遠不只是為SPI和I2C定義了統一的transfer接口。最重要的,是實現了應用層訪問總線的串行化。SPI和I2C都是由一條總線掛接許多設備,無論是SPI或I2C,都不允許在同一時刻訪問多個設備。因此,Device提供了get_semaphore接口,以鎖定總線。當然,這并不算是串行化,真正的串行化,是通過register_periodic_callback來實現。

virtual PeriodicHandle register_periodic_callback(uint32_t period_usec, PeriodicCb) = 0;

各傳感器驅動通過register_periodic_callback注冊定時回調,在回調之中訪問對應的傳感器。同一總線的所有定時回調是在同一個線程中被執行的,這就是串行化。

7d495e94-a7f7-11eb-9728-12bb97331649.png

PX4在實現時,使用DeviceBus實現這個串行化的功能,其會為每一條總線創建一個線程。

7d9b24d6-a7f7-11eb-9728-12bb97331649.png

其內部實現,無非是創建線程,將回調添加到一個鏈表之中。在函數中,POSIX接口的調用清晰可見。筆者的意思是,可以直接拿來用啦。

7db1b5d4-a7f7-11eb-9728-12bb97331649.png

Manager

應用層通過Device來訪問I2C和SPI設備,那么Device對象是哪來的呢?由I2CDeviceManager和SPIDeviceManager提供,而這兩個Manager的實例可通過HAL引用訪問。

7df3cc9e-a7f7-11eb-9728-12bb97331649.png

小結

SPI和I2C傳輸的具體實現,沒啥好說的。最值得說的,是Ardupilot抽象出了Device基類,為應用層提供串行化的訪問功能。而這串行化,是靠創建線程和回調鏈表來實現。

是時候放一張高清大圖了:

7e8275b6-a7f7-11eb-9728-12bb97331649.png

總結

到目前為止,我們看了調度接口,串口驅動,SPI和I2C驅動。調度接口中的微秒級延時接口非常關鍵,因為很多地方使用了它,并且它的實現有些困難。至于串口、SPI等驅動接口,只要我們理清了它們的層級關系,明確了各接口的作用,移植時不會有什么大問題。并且,這些驅動接口的實現,很多地方可以參考PX4的實現,甚至是直接復制過來用。

原文標題:Ardupilot移植經驗分享(3)

文章出處:【微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 驅動
    +關注

    關注

    12

    文章

    1956

    瀏覽量

    88547
  • 串口
    +關注

    關注

    15

    文章

    1619

    瀏覽量

    82837

原文標題:Ardupilot移植經驗分享(3)

文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    HPM知識庫 | HPMicro Ardupilot支持包v0.1.0發布!

    ArduPilot提供一套功能全面的工具,幾乎適用于任何類型的車輛、無人機及其應用場景。作為一個開源項目,它依托廣大用戶群體的快速反饋而不斷演進。配合地面控制軟件,運行ArduPilot的無人飛行器
    的頭像 發表于 03-06 15:14 ?907次閱讀
    HPM知識庫 | HPMicro <b class='flag-5'>Ardupilot</b>支持包v0.1.0發布!

    深入解析bq32000實時時鐘:特性、應用與設計要點

    ,在消費電子等領域得到了廣泛應用。今天,我們就來深入探討一下bq32000的相關技術細節。 文件下載: bq32000.pdf 一、bq32000概述 1.1 特性亮點 自動切換備份電源 :當主電源
    的頭像 發表于 02-09 11:25 ?218次閱讀

    Ubuntu 25升級全解析!即將移植RK系列芯片,技術實踐搶先預告

    能、開發工具等維度實現了全方位突破。更重磅的是 —— 我已啟動將 Ubuntu 25 移植到 RK 系列芯片的計劃,后續會持續分享實踐細節,各位敬請期待!
    的頭像 發表于 02-06 17:07 ?3147次閱讀
    Ubuntu 25升級全解析!即將<b class='flag-5'>移植</b>RK系列芯片,技術實踐搶先預告

    2.4 GHz低通濾波器2450LP15A050:技術細節與設計考量

    2.4 GHz低通濾波器2450LP15A050:技術細節與設計考量 在高頻電路設計中,濾波器的性能直接影響著整個系統的穩定性和信號質量。今天,我們來深入探討Johanson Technology
    的頭像 發表于 02-04 16:45 ?612次閱讀

    PCB拼板三大細節要點

    提醒:拼板訂單中,只要PCB設計不是完全相同,哪怕整體外形一致,孔位、走線等細節存在微小差異,屬于不同款 PCB。 要點二:陰陽拼板需完整 陰陽拼板(同一拼板正反面為不同設計的單板)因結構特殊,對文
    發表于 01-23 14:00

    網絡跳線:細節決定成敗的網絡構建者

    在構建一個高效、穩定的網絡環境時,我們往往會關注到大型的網絡設備、復雜的網絡架構或是先進的網絡技術,而往往忽略了那些看似微不足道卻至關重要的細節——網絡跳線。然而,正是這些小小的跳線,在網絡的構建
    的頭像 發表于 01-09 10:10 ?277次閱讀

    深入Linux內核:進程調度的核心邏輯與實現細節

    在Linux系統中,進程調度就像一位精明的“CPU管理員”——它決定著哪個進程能優先使用CPU,多久切換一次進程,如何平衡系統響應速度與資源利用率。小到桌面應用的流暢點擊,大到服務器的多任務并發,背后都離不開內核調度算法的精準操控。今天,我們就從優先級、調度算法、時間片分配到底層實現,全方位拆解Linux內核進程調度的核心邏輯。 一、進程調度的“身份標識”:優先級與分類 要理解調度邏輯,首先得搞懂:進程憑什么“插隊”?答案
    的頭像 發表于 12-24 07:05 ?4313次閱讀
    <b class='flag-5'>深入</b>Linux內核:進程調度的核心邏輯與實現<b class='flag-5'>細節</b>

    高速PCB打樣必知:細節決定成敗,這些點你不能忽視!

    23年PCBA一站式行業經驗PCBA加工廠家今天為大家講講高速pcb打樣需要注意什么細節?高速pcb打樣需要注意的細節。在高速PCB(印刷電路板)打樣階段,為確保最終產品的性能和可靠性,需要注意以下
    的頭像 發表于 12-16 09:19 ?331次閱讀
    高速PCB打樣必知:<b class='flag-5'>細節</b>決定成敗,這些點你不能忽視!

    PCIe 7.0技術細節曝光

    6 月 11 日 PCI SIG官宣 PCI Express 7.0(PCIe 7.0)規范最終版已制定完畢,但幾乎沒有公開任何技術細節。不過,在 7 月 16 日,PCI-SIG 通過 BrightTalk 公開了一些更詳細的技術信息,下面就為大家介紹這些內容。
    的頭像 發表于 09-08 10:43 ?2828次閱讀
    PCIe 7.0技術<b class='flag-5'>細節</b>曝光

    恩智浦MCU教程 基于MCUXpresso和FRDM-MCXA346的RT-Thread Nano移植

    本篇還是以移植RT-Thread Nano到MCUXpresso IDE為主,移植的代碼可以在nxpic.org.cn論壇搜索到。
    的頭像 發表于 08-21 09:49 ?6766次閱讀
    恩智浦MCU教程 基于MCUXpresso和FRDM-MCXA346的RT-Thread Nano<b class='flag-5'>移植</b>

    機智云配網教程第三期:單片機代碼移植實戰

    前言本篇文章將分享單片機移植的經驗。可以下載并按步驟移植,也可以直接使用已移植好的工程文件。文中將介紹我在移植過程中遇到的問題,并提供解決方案,供大家參考。準備工作1.硬件:主控
    的頭像 發表于 07-01 17:32 ?1708次閱讀
    機智云配網教程第三期:單片機代碼<b class='flag-5'>移植</b>實戰

    STM32與機智云連接實現步驟與技巧(下篇):機智云代碼移植與優化

    在《STM32與機智云連接實現步驟與技巧(上篇)》中,我們介紹了硬件連接和通信協議配置。本篇將重點講解如何將機智云相關代碼移植到STM32,完成數據上傳和設備控制。我們將介紹如何在STM32中配置
    的頭像 發表于 05-23 18:10 ?1116次閱讀
    STM32與機智云連接實現步驟與技巧(下篇):機智云代碼<b class='flag-5'>移植</b>與優化

    從設計到打樣:PCBA 前期準備的核心細節解析

    在電子制造流程中,PCBA 貼片打樣是從設計圖紙邁向實物的關鍵一步,任何細節的疏漏都可能導致樣品與預期大相徑庭,甚至需要重新打樣,浪費時間與成本。曾有團隊因未確認元器件封裝尺寸,打樣后發現元件無法
    的頭像 發表于 04-30 17:57 ?717次閱讀

    STM32G431移植FreeModbus

    STM32G431移植FreeModbus 的代碼已通過驗證,在WeActStudio的STM32G431CoreBoard上進行多次測試,均可正常讀取寄存器數值。STM32G431CoreBoard可在我上傳的相關文件下載。
    發表于 04-19 16:50 ?2次下載

    索尼IP編碼板:技術細節與應用探索

    在數字化浪潮席卷全球的今天,高清視頻傳輸與處理技術在各行各業中扮演著至關重要的角色。索尼,作為電子產品領域的領軍企業,其IP編碼板以其卓越的性能和廣泛的應用場景,成為了市場關注的焦點。本文將深入
    的頭像 發表于 03-20 10:10 ?1116次閱讀