chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

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

3天內(nèi)不再提示

Ardupilot移植的深入細節(jié)分享

RTThread物聯(lián)網(wǎng)操作系統(tǒng) ? 來源:驚覺嵌入式 ? 作者:驚覺嵌入式 ? 2021-04-30 16:14 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

接Ardupilot移植經(jīng)驗分享(2)

深入細節(jié)

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

分析HAL接口的含義,包括功能,入?yún)⒓胺祷刂档木唧w含義。

分析HAL_PX4的實現(xiàn),看看有沒有可借鑒之處。

調(diào)度接口

AP_HAL::Scheduler提供了程序調(diào)度相關(guān)的接口。主要分為兩類:

延時函數(shù)

注冊回調(diào)

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

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會比較復(fù)雜。因為通常來說,毫秒級延時是RTOS的基礎(chǔ)API,比如RT-Thread的rt_thread_mdelay。

rt_err_t rt_thread_mdelay(rt_int32_t ms);

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

typedef void(*Proc)(void);

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

這接口的功能是:注冊一個延時回調(diào)。當(dāng)某個線程調(diào)用delay進行延時時,若延時的時間大于min_time_ms,則delay函數(shù)將會調(diào)用這個延時回調(diào)。

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

其中之一是mavlink模塊。

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

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

在這里插入圖片描述

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

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

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

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

微秒級延時delay_microseconds

筆者當(dāng)初看到這接口時,有些頭疼。因為RT-Thread并沒有微秒級別的延時函數(shù),再強調(diào)一遍,這不是死等,是要睡眠讓權(quán)的。

直接看PX4的實現(xiàn):

void PX4Scheduler::delay_microseconds(uint16_t usec)

{

perf_begin(_perf_delay);

delay_microseconds_semaphore(usec);

perf_end(_perf_delay);

}

這是上節(jié)提到的delay_microseconds_semaphore的馬甲,脫了它:

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

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

調(diào)用hrt_call_after注冊一個定時器回調(diào),定時時間是usec,單位微秒?;卣{(diào)函數(shù)是信號量發(fā)送函數(shù)sem_post,回調(diào)參數(shù)是信號量wait_semaphore。

使用sem_wait等待信號量wait_semaphore,此時當(dāng)前線程會堵塞,進入睡眠狀態(tài)。

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

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

結(jié)合時序圖來理解:

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

微秒級的延時函數(shù),依賴于微秒級的定時回調(diào),也就是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沒有相應(yīng)功能而煩惱。關(guān)于定時器,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)

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

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

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

delay_microseconds_boost

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

注冊回調(diào)

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

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

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

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

注冊函數(shù)將回調(diào)指針加入到數(shù)組中。

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

在相應(yīng)線程中,定時的一一執(zhí)行。

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

那么,這線程是怎么創(chuàng)建的呢?PX4Scheduler的初始化函數(shù)中,會創(chuàng)建許多線程。

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”(可移植操作系統(tǒng)接口) 的縮寫,POSIX 是 IEEE Computer Society 為了提高不同操作系統(tǒng)的兼容性和應(yīng)用程序的可移植性而制定的一套標準。

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

串口驅(qū)動

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

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

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

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

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

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

在這里插入圖片描述

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

串口綁定

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構(gòu)造函數(shù)和set_device_path用于與具體的底層串口相綁定。HAL_PX4_Class.c中定義了綁定關(guān)系:

// 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的實現(xiàn)

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

PX4UARTDriver使用接收緩存和發(fā)送緩存來實現(xiàn)異步讀寫。

write是將數(shù)據(jù)寫入到發(fā)送緩存_writebuf之中。_writebuf是一個隊列,實質(zhì)上是環(huán)形數(shù)組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從接收緩存中提取數(shù)據(jù),若沒有則返回-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;

}

將發(fā)送緩存的數(shù)據(jù)寫入串口和從串口接收數(shù)據(jù)以填充接收緩存的工作,在PX4UARTDriver::_timer_tick函數(shù)中實現(xiàn)。而所有串口的_timer_tick由一個統(tǒng)一的串口線程來調(diào)度。

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;

}

看過前面高清大圖的,應(yīng)該對這個有印象:

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

SPI和I2C驅(qū)動

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

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

都有主從概念,每次傳輸由主機發(fā)起,由從機應(yīng)答。

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

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

在這里插入圖片描述

UML圖示說明

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

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

斜體函數(shù)為純虛函數(shù),需要由子類實現(xiàn)。

transfer

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

/*

* 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實現(xiàn)的是先寫后讀。而對于SPI來說,transfer內(nèi)部是同時讀寫。

SPIDevice和I2CDevice

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

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

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

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

Periodic Callback

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

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

各傳感器驅(qū)動通過register_periodic_callback注冊定時回調(diào),在回調(diào)之中訪問對應(yīng)的傳感器。同一總線的所有定時回調(diào)是在同一個線程中被執(zhí)行的,這就是串行化。

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

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

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

其內(nèi)部實現(xiàn),無非是創(chuàng)建線程,將回調(diào)添加到一個鏈表之中。在函數(shù)中,POSIX接口的調(diào)用清晰可見。筆者的意思是,可以直接拿來用啦。

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

Manager

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

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

小結(jié)

SPI和I2C傳輸?shù)木唧w實現(xiàn),沒啥好說的。最值得說的,是Ardupilot抽象出了Device基類,為應(yīng)用層提供串行化的訪問功能。而這串行化,是靠創(chuàng)建線程和回調(diào)鏈表來實現(xiàn)。

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

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

總結(jié)

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

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

文章出處:【微信公眾號:RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 驅(qū)動
    +關(guān)注

    關(guān)注

    12

    文章

    1916

    瀏覽量

    86914
  • 串口
    +關(guān)注

    關(guān)注

    15

    文章

    1588

    瀏覽量

    79917

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

文章出處:【微信號:RTThread,微信公眾號:RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

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

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    機智云配網(wǎng)教程第三期:單片機代碼移植實戰(zhàn)

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

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

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

    STM32G431移植FreeModbus

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

    索尼IP編碼板:技術(shù)細節(jié)與應(yīng)用探索

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

    必看!PCB出貨包裝全攻略:關(guān)鍵細節(jié)與品質(zhì)保障要點

    細節(jié),如防潮、濕度監(jiān)測、烤板處理等,直接影響著 PCB 的可用性與可靠性。接下來,讓我們深入了解這些要點。
    的頭像 發(fā)表于 02-14 11:12 ?865次閱讀
    必看!PCB出貨包裝全攻略:關(guān)鍵<b class='flag-5'>細節(jié)</b>與品質(zhì)保障要點

    詳解Object Detection Demo的移植

    繼上一篇移植了 Mediapipe 的 LLM Inference 后,這篇文章我們將繼續(xù)探索 Object Detection Demo 的移植
    的頭像 發(fā)表于 02-05 13:42 ?470次閱讀
    詳解Object Detection Demo的<b class='flag-5'>移植</b>

    臺積電分享 2nm 工藝深入細節(jié):功耗降低 35% 或性能提升15%!

    來源:IEEE 臺積電在本月早些時候于IEEE國際電子器件會議(IEDM)上公布了其N2(2nm級)制程的更多細節(jié)。該新一代工藝節(jié)點承諾實現(xiàn)24%至35%的功耗降低或15%的性能提升(在相同電壓
    的頭像 發(fā)表于 12-16 09:57 ?814次閱讀
    臺積電分享 2nm 工藝<b class='flag-5'>深入</b><b class='flag-5'>細節(jié)</b>:功耗降低 35% 或性能提升15%!

    移植Mediapipe LLM Demo到Kotlin Multiplatform

    在今年的廈門和廣州 Google I/O Extended 上,我分享了《On-Device Model 集成 (KMP) 與用例》。本文是當(dāng)時 Demo 的深入細節(jié)分析,同時也是后面幾篇同類型文章的開頭。
    的頭像 發(fā)表于 12-05 16:29 ?1149次閱讀
    <b class='flag-5'>移植</b>Mediapipe LLM Demo到Kotlin Multiplatform

    多平臺FPGA工程快速移植與構(gòu)建

    作為一名FPGA工程師,經(jīng)常需要在多個FPGA設(shè)備之間移植項目,核心的問題是IP的管理和移植,今天通過安裝和使用 FuseSoC 在多個 AMD FPGA 之間移植一個簡單的項目。從 AMD Spartan 7 更改為 AMD
    的頭像 發(fā)表于 11-20 16:12 ?1903次閱讀
    多平臺FPGA工程快速<b class='flag-5'>移植</b>與構(gòu)建

    深入解析Zephyr RTOS的技術(shù)細節(jié)

    ,Zephyr OS在嵌入式開發(fā)中的知名度逐漸增加,新的微控制器和開發(fā)板都支持Zephyr。本文將深入討論Zephyr RTOS的技術(shù)細節(jié)
    的頭像 發(fā)表于 10-22 16:47 ?2212次閱讀
    <b class='flag-5'>深入</b>解析Zephyr RTOS的技術(shù)<b class='flag-5'>細節(jié)</b>

    Nordic-RT-Thread5.1.0移植筆記

    Nordic-RT-Thread5.1.0移植筆記
    的頭像 發(fā)表于 10-16 08:09 ?1309次閱讀
    Nordic-RT-Thread5.1.0<b class='flag-5'>移植</b>筆記

    基于機智云移植STM32L496G代碼移植

    前言最近我拿到了STM32L496AGMCU,發(fā)現(xiàn)其擴展版可以連接ESP-01S。我想嘗試將開發(fā)板連接到我們的機智云上,并根據(jù)機智云提供的文檔進行程序移植。STM32CubeMX移植機智云自動生成
    的頭像 發(fā)表于 09-20 08:05 ?1182次閱讀
    基于機智云<b class='flag-5'>移植</b>STM32L496G代碼<b class='flag-5'>移植</b>

    【GD32 MCU 移植教程】9、從 STM32F10x 系列移植到 GD32F30x 系列

    對比、外設(shè)及性能對比以及從 STM32F10x 移植到 GD32F30x 的移植步驟,旨在讓開發(fā)者能夠快速從STM32F10x 移植到 GD32F30x,縮短研發(fā)周
    的頭像 發(fā)表于 09-07 09:57 ?1965次閱讀
    【GD32 MCU <b class='flag-5'>移植</b>教程】9、從 STM32F10x 系列<b class='flag-5'>移植</b>到 GD32F30x 系列

    【GD32 MCU 移植教程】8、從 STM32F4xx 系列移植到 GD32F4xx 系

    、外設(shè)及性能對比以及從 STM32F4xx 移植到 GD32F4xx 的移植步驟,旨在讓開發(fā)者能夠快速從STM32F4xx移植到 GD32F4xx,縮短研發(fā)周期,
    的頭像 發(fā)表于 09-06 09:40 ?2623次閱讀
    【GD32 MCU <b class='flag-5'>移植</b>教程】8、從 STM32F4xx 系列<b class='flag-5'>移植</b>到 GD32F4xx 系

    【GD32 MCU 移植教程】5、GD32E230 系列移植到 GD32F330 系列

    移植到 GD32F330 系列的需求,本文 檔專門針對既有的 GD32E230 代碼如何移植到 GD32F330 做一個詳細的介紹;
    的頭像 發(fā)表于 09-03 10:05 ?2612次閱讀
    【GD32 MCU <b class='flag-5'>移植</b>教程】5、GD32E230 系列<b class='flag-5'>移植</b>到 GD32F330 系列