色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

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

STM32速成筆記(15)—串口IAP

冬至子 ? 來源:二土電子 ? 作者:二土電子 ? 2023-10-24 17:19 ? 次閱讀

一、串口IAP簡(jiǎn)介

1.1 什么是IAP

IAP,英文全稱In Application Programming,在應(yīng)用中編程。很好理解,就是在程序運(yùn)行過程中我們進(jìn)行程序的燒寫,或者叫升級(jí)。

1.2 STM32下載程序

我們都知道,STM32可以利用串口下載程序,這是因?yàn)镾T公司在產(chǎn)線上就在產(chǎn)品中內(nèi)嵌了自舉程序。所謂的自舉程序,實(shí)際就是支持我們通過串口下載程序的代碼。自舉程序被存放在系統(tǒng)存儲(chǔ)區(qū),因此如果我們需要通過串口下載程序,需要將Boot0接高電平,Boot1接低電平,讓程序從系統(tǒng)存儲(chǔ)器開始運(yùn)行,運(yùn)行自舉程序。下載完成后我們?cè)賹oot0接地,讓程序從主閃存存儲(chǔ)器開始運(yùn)行。自舉程序是我們用戶無法修改的。

二、串口IAP有什么作用

上面我們介紹了什么是IAP,那么這個(gè)IAP到底有什么作用呢?

首先介紹兩個(gè)詞——BootloaderApplication 。Bootloader實(shí)際就是一段引導(dǎo)程序,單片機(jī)上電后先執(zhí)行Bootloader程序,然后再執(zhí)行用戶編寫的應(yīng)用程序Application。介紹完這兩個(gè)詞,我們來介紹一下IAP有什么作用。比如我們生產(chǎn)了A,B兩款產(chǎn)品。A產(chǎn)品是某個(gè)精密器件的一部分,B產(chǎn)品是一款物聯(lián)網(wǎng)產(chǎn)品。我們的產(chǎn)品銷售范圍很廣,遠(yuǎn)銷海外。

某天A產(chǎn)品的某個(gè)客戶反映了一個(gè)Bug,我們編寫好了程序,需要進(jìn)行程序更新,或者叫升級(jí)。利用IAP,我們可以在程序運(yùn)行時(shí),通過預(yù)留的通信接口直接燒寫程序。而不需要再把整個(gè)設(shè)備拆開,像我們調(diào)試時(shí)那樣下載程序。甚至我們可以直接給客戶郵寄一個(gè)小設(shè)備,客戶直接進(jìn)行傻瓜式升級(jí)。

又過了一段時(shí)間,B產(chǎn)品的程序出現(xiàn)了一個(gè)Bug,風(fēng)險(xiǎn)等級(jí)比較低,但是依舊需要全體升級(jí)程序。我們總不能挨個(gè)產(chǎn)品派人去升級(jí),成本極大。這時(shí)候又輪到我們的IAP出場(chǎng)了。它可以在所有設(shè)備在線運(yùn)行的情況下,直接通過網(wǎng)絡(luò)下發(fā)升級(jí)程序,實(shí)現(xiàn)在線升級(jí),節(jié)約了大量的人力成本。

通過上面這兩個(gè)例子,大家應(yīng)該能夠基本了解IAP的用處,使用IAP讓我們不需要再使用調(diào)試器進(jìn)行下載,甚至實(shí)現(xiàn)設(shè)備的在線升級(jí)。

三、啟動(dòng)流程

在介紹如何實(shí)現(xiàn)IAP之前,我們先來簡(jiǎn)單了解以下STM32的啟動(dòng)流程。

3.1 正常啟動(dòng)流程

這里的正常啟動(dòng)流程指的是,沒有添加IAP的流程。

圖片

正常啟動(dòng)流程

程序啟動(dòng)時(shí)首先開辟??臻g,配置棧頂指針。然后配置堆空間。配置完成后,建立中斷向量表,在中斷向量表中找到復(fù)位中斷,開始執(zhí)行復(fù)位中斷服務(wù)函數(shù),然后跳轉(zhuǎn)到main函數(shù)中,執(zhí)行用戶代碼。當(dāng)用戶代碼中有中斷請(qǐng)求時(shí),會(huì)回到中斷向量表,根據(jù)中斷源執(zhí)行相應(yīng)的中斷服務(wù)函數(shù)。

3.2 加入IAP后的啟動(dòng)流程

下面是加入IAP之后的啟動(dòng)流程。

圖片

加入IAP啟動(dòng)流程

可以看到,與上面不同的是,加入IAP后,執(zhí)行完復(fù)位中斷服務(wù)函數(shù)后直接進(jìn)入IAP的main函數(shù)。在執(zhí)行完IAP之后,跳轉(zhuǎn)至新寫入程序的復(fù)位向量表,取出新程序的復(fù)位中斷向量的地址,并跳轉(zhuǎn)執(zhí)行新程序的復(fù)位中斷服務(wù)程序,隨后跳轉(zhuǎn)至新程序的main 函數(shù)。

由上面的兩個(gè)啟動(dòng)過程我們可以看出

  • ? 新程序必須在 IAP 程序之后的某個(gè)偏移量為 x 的地址開始。

  • ? 必須將新程序的中斷向量表相應(yīng)的移動(dòng),移動(dòng)的偏移量為 x。

    四、必備知識(shí)

    44.1 修改程序運(yùn)行起始地址

點(diǎn)擊魔術(shù)棒,選擇“Target”,修改運(yùn)行起始地址和代碼大小。

圖片

修改App運(yùn)行起始地址

4.2 設(shè)置中斷向量表偏移

VTOR 寄存器存放的是中斷向量表的起始地址。如果要設(shè)置中斷向量表偏移,只需要在main函數(shù)最開始添加如下語句即可

SCB- >VTOR = FLASH BASE | 偏移量:

4.3 生成.bin文件

點(diǎn)擊魔術(shù)棒,選擇“User”,按照如下配置,輸入下面的內(nèi)容

fromelf --bin -o "$L@L.bin" "#L"

圖片

生成.bin文件配置

點(diǎn)擊編譯,不報(bào)錯(cuò)就可以,去設(shè)置的輸出文件夾中就可以找到對(duì)應(yīng)的.bin文件。

圖片

編譯提示

五、串口IAP實(shí)現(xiàn)

本次的目標(biāo)是實(shí)現(xiàn)一個(gè)串口IAP,也就是編寫B(tài)ootloader,在程序運(yùn)行過程中實(shí)現(xiàn)程序的下載。Bootloader程序應(yīng)該可以通過串口接收上位機(jī)發(fā)來的.bin文件(App程序),檢查后將.bin文件寫入到Flash特定位置,然后跳轉(zhuǎn)到App程序運(yùn)行。

5.1 串口中斷服務(wù)函數(shù)

本次的串口中斷服務(wù)函數(shù)與之前不同,這里單獨(dú)貼出來。需要定義一個(gè)接收數(shù)組,接收數(shù)組的起始地址限制為0X20001000。接收數(shù)組最多可以接收55K字節(jié),可以根據(jù)需要調(diào)整。但是需要注意的是,數(shù)組的大小需要比App程序要大,而且不能超過芯片的SRAM空間大小。

/*
 *==============================================================================
 *函數(shù)名稱:USART1_IRQHandler
 *函數(shù)功能:USART1中斷服務(wù)函數(shù)
 *輸入參數(shù):無
 *返回值:無
 *備  注:無
 *==============================================================================
 */
u32 gReceCount = 0;   // 接收計(jì)數(shù)變量
// 接收數(shù)組
// 限制起始地址為0X20001000
// 保證偏移量為 0X200的倍數(shù)
// 是為了給App留SRAM空間
u8 gReceFifo[USART_RECE_MAX_LEN]__attribute__ ((at(0X20001000)));

void USART1_IRQHandler(void)  
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)   //接收到一個(gè)字節(jié)  
    {
        if (gReceCount < USART_RECE_MAX_LEN)
        {
            gReceFifo[gReceCount++] = USART1- >DR;
        }
        else
        {
            printf ("APP code out of memory!rn");
        }
    }
}

5.2 Flash寫入程序

關(guān)于Flash程序,這里就不在贅述,只是貼一下帶檢查的寫入程序。其他具體內(nèi)容可以到博主STM32速成筆記專欄查看。

/*
 *==============================================================================
 *函數(shù)名稱:Med_Flash_Write
 *函數(shù)功能:從指定地址開始寫入指定長(zhǎng)度的數(shù)據(jù)
 *輸入?yún)?shù):WriteAddr:寫入起始地址;pBuffer:數(shù)據(jù)指針;
                        NumToRead:寫入(半字)數(shù)
 *返回值:無
 *備  注:對(duì)內(nèi)部Flash的操作是以半字為單位,所以讀寫地址必須是2的倍數(shù)
 *==============================================================================
 */

// 根據(jù)中文參考手冊(cè),大容量產(chǎn)品的每一頁(yè)是2K字節(jié)
#if STM32_FLASH_SIZE < 256
    #define STM32_SECTOR_SIZE   1024   // 字節(jié)
#else 
    #define STM32_SECTOR_SIZE   2048
#endif

// 一個(gè)扇區(qū)的內(nèi)存
u16 STM32_FLASH_BUF[STM32_SECTOR_SIZE / 2];

void Med_Flash_Write (u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
    u32 secpos;   // 扇區(qū)地址
    u16 secoff;   // 扇區(qū)內(nèi)偏移地址(16位字計(jì)算)
    u16 secremain;   // 扇區(qū)內(nèi)剩余地址(16位計(jì)算)    
     u16 i;    
    u32 offaddr;   // 去掉0X08000000后的地址
    
    // 判斷寫入地址是否在合法范圍內(nèi)
    if (WriteAddr < STM32_FLASH_BASE || (WriteAddr >= (STM32_FLASH_BASE + 1024 * STM32_FLASH_SIZE)))
    {
        return;   // 非法地址
    }
    
    FLASH_Unlock();   // 解鎖
    offaddr = WriteAddr - STM32_FLASH_BASE;   // 實(shí)際偏移地址
    secpos = offaddr / STM32_SECTOR_SIZE;   // 扇區(qū)地址
    secoff = (offaddr % STM32_SECTOR_SIZE) / 2;   // 在扇區(qū)內(nèi)的偏移(2個(gè)字節(jié)為基本單位)
    secremain = STM32_SECTOR_SIZE / 2 - secoff;   // 扇區(qū)剩余空間大小
    
    if (NumToWrite <= secremain)
    {
        secremain = NumToWrite;   // 不大于該扇區(qū)范圍
    }
    
    while (1) 
    {
        // 讀出整個(gè)扇區(qū)的內(nèi)容
        Med_Flash_Read(secpos * STM32_SECTOR_SIZE + STM32_FLASH_BASE,STM32_FLASH_BUF,STM32_SECTOR_SIZE / 2);
        
        // 校驗(yàn)數(shù)據(jù)
        for (i = 0;i < secremain;i ++)
        {
            // 需要擦除 
            if (STM32_FLASH_BUF[secoff + i] != 0XFFFF)
            {
                break; 
            }    
        }
        // 需要擦除
        if (i < secremain)
        {
            FLASH_ErasePage(secpos * STM32_SECTOR_SIZE + STM32_FLASH_BASE);   // 擦除這個(gè)扇區(qū)
            
            // 復(fù)制
            for (i = 0;i < secremain;i ++)
            {
                STM32_FLASH_BUF[i + secoff] = pBuffer[i];   
            }
            
            // 寫入整個(gè)扇區(qū)
            Med_Flash_Write_NoCheck(secpos * STM32_SECTOR_SIZE + STM32_FLASH_BASE,STM32_FLASH_BUF,STM32_SECTOR_SIZE / 2);
        }
        else
        {
            // 寫已經(jīng)擦除了的,直接寫入扇區(qū)剩余區(qū)間
            Med_Flash_Write_NoCheck(WriteAddr,pBuffer,secremain);
        }
        
        if (NumToWrite == secremain)
        {
            break;   // 寫入結(jié)束了
        }
        // 寫入未結(jié)束
        else
        {
            secpos ++;   // 扇區(qū)地址增1
            secoff = 0;   // 偏移位置為0   
            pBuffer += secremain;   // 指針偏移
            WriteAddr += secremain;   // 寫地址偏移    
            NumToWrite -= secremain;   // 字節(jié)(16位)數(shù)遞減
            if (NumToWrite > (STM32_SECTOR_SIZE / 2))
            {
                secremain = STM32_SECTOR_SIZE / 2;   // 下一個(gè)扇區(qū)還是寫不完
            }
            else
            {
                secremain = NumToWrite;   // 下一個(gè)扇區(qū)可以寫完了
            }
        }  
    } 
    FLASH_Lock();   // 上鎖
}

5.3 IAP程序

IAP程序包含兩部分,一部分是將接收到的.bin文件寫入Flash,另一部分是跳轉(zhuǎn)到App執(zhí)行。

/*
 *==============================================================================
 *函數(shù)名稱:iap_write_appbin
 *函數(shù)功能:寫入.bin文件
 *輸入?yún)?shù):appxaddr:App程序起始地址;appbuf:緩存App程序的數(shù)組;
                        appsize:App程序大小
 *返回值:無
 *備  注:無
 *==============================================================================
 */
 // 對(duì)Flash操作的最小單位是16位
 u16 iapbuf[1024];   // 要寫入Flash的內(nèi)容
 
void iap_write_appbin (u32 appxaddr,u8 *appbuf,u32 appsize)
{
    u16 t;   // 臨時(shí)循環(huán)變量
    u16 i = 0;   // 自增索引
    u16 temp;   // 臨時(shí)計(jì)算變量
    
    u32 fwaddr = appxaddr;   // 當(dāng)前寫入的地址
    u8 *dfu = appbuf;   // 指向App代碼數(shù)組首地址的指針
    
    // for循環(huán),2K為單位進(jìn)行寫入
    for(t = 0;t < appsize;t += 2)
    {  
        temp = (u16)dfu[1] < < 8;
        temp += (u16)dfu[0];   
        dfu += 2;   // 偏移2個(gè)字節(jié)
        iapbuf[i++] = temp;     
        if(i == 1024)
        {
            i = 0;
            Med_Flash_Write (fwaddr,iapbuf,1024); 
            fwaddr += 2048;   // 偏移2048  16=2*8所以要乘以2
        }
    }
    if(i)
    {
        Med_Flash_Write (fwaddr,iapbuf,i);   // 將最后的一些內(nèi)容字節(jié)寫進(jìn)去
    }
}
/*
 *==============================================================================
 *函數(shù)名稱:iap_load_app
 *函數(shù)功能:跳轉(zhuǎn)到App
 *輸入?yún)?shù):appxaddr:App程序起始地址
 *返回值:無
 *備  注:無
 *==============================================================================
 */
iapfun jump2app;

void iap_load_app (u32 appxaddr)
{
    if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)   // 檢查棧頂?shù)刂肥欠窈戏?/span>
    { 
        jump2app=(iapfun)*(vu32*)(appxaddr+4);   // 用戶代碼區(qū)第二個(gè)字為程序開始地址(復(fù)位地址)  
        MSR_MSP(*(vu32*)appxaddr);   // 初始化APP堆棧指針(用戶代碼區(qū)的第一個(gè)字用于存放棧頂?shù)刂?
        jump2app();   // 跳轉(zhuǎn)到APP
    }
}

5.4 main函數(shù)

main函數(shù)設(shè)計(jì)如下

int main(void)
{
    u32 curRecCunt = 0;   // 當(dāng)前接收數(shù)量
    
    // 設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    delay_init();   // 延時(shí)初始化
    uart_init(115200);   // 串口初始化
    
    printf ("Enter the Bootloader Code!rn");
    
    while(1)
  {
        // 如果接收到內(nèi)容且傳輸完成
        if (curRecCunt == gReceCount && gReceCount != 0)
        {
            printf ("App Code reception complete!rn");
            printf ("The length of the received App code is %d!rn",gReceCount);
            
            // 開始準(zhǔn)備寫入Flash
            if(((*(vu32*)(0X20001000+4)) & 0xFF000000) == 0x08000000)   // 判斷是否為0X08XXXXXX.
            {
                iap_write_appbin(FLASH_APP1_ADDR,gReceFifo,gReceCount);   // 更新FLASH代碼  
                gReceCount = 0;   // 清零接收計(jì)數(shù)變量
                printf("Update complete!rn");
            }
            else 
            { 
                printf("Update error!rn");
            }
            
            // 準(zhǔn)備跳轉(zhuǎn)App執(zhí)行
            if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)   //判斷是否為0X08XXXXXX.
            {
                printf("Enter App!rn");
                iap_load_app(FLASH_APP1_ADDR);   //執(zhí)行FLASH APP代碼
            }else 
            {
                printf("Enter error!rn");
            } 
        }
        else   // 未傳輸完成
        {
            curRecCunt = gReceCount;   // 更新當(dāng)前接收數(shù)量
            // 延時(shí)一定要有,給串口中斷留出時(shí)間
            // 如果沒有會(huì)導(dǎo)致接收不完全
            delay_ms(10);
        }
    }
}

六、注意事項(xiàng)

需要注意的是,上面的程序中App程序是從0x8010000開始,需要配置好程序起始地址和中斷向量表偏移

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

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120424
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10901

    瀏覽量

    356195
  • 上位機(jī)
    +關(guān)注

    關(guān)注

    27

    文章

    942

    瀏覽量

    54827
  • 中斷向量
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    8945
  • flash內(nèi)存
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    2129
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于STM32串口環(huán)形隊(duì)列IAP調(diào)試

    基于STM32串口環(huán)形隊(duì)列IAP調(diào)試心得
    的頭像 發(fā)表于 09-18 15:33 ?1569次閱讀
    基于<b class='flag-5'>STM32</b>的<b class='flag-5'>串口</b>環(huán)形隊(duì)列<b class='flag-5'>IAP</b>調(diào)試

    STM32串口IAP詳細(xì)步驟

    實(shí)現(xiàn)STM32F405的串口IAP
    發(fā)表于 08-30 09:00

    STM32是如何實(shí)現(xiàn)IAP功能的

    STM32實(shí)現(xiàn)IAP功能的學(xué)習(xí)筆記最近因項(xiàng)目需求要實(shí)現(xiàn)STM32的在線升級(jí)即IAP功能,先將這幾天的學(xué)習(xí)體會(huì)和
    發(fā)表于 08-11 08:07

    求大佬分享STM32F4串口IAP學(xué)習(xí)筆記

    求大佬分享STM32F4串口IAP學(xué)習(xí)筆記
    發(fā)表于 12-08 06:41

    STM32F103學(xué)習(xí)筆記串口通信

    STM32F103學(xué)習(xí)筆記串口通信
    發(fā)表于 11-25 09:06 ?71次下載
    <b class='flag-5'>STM32</b>F103學(xué)習(xí)<b class='flag-5'>筆記</b>三   <b class='flag-5'>串口</b>通信

    STM32--STM32F051 IAP的實(shí)現(xiàn)

    一、IAP原理及過程《正點(diǎn)原子--STM32F10x串口IAP實(shí)驗(yàn)》《stm32f030 IAP
    發(fā)表于 11-29 15:06 ?33次下載
    <b class='flag-5'>STM32--STM32</b>F051 <b class='flag-5'>IAP</b>的實(shí)現(xiàn)

    [筆記]|[stm32]|[寄存器存儲(chǔ)器區(qū)別]|[PWM]|[串口]|[Timer]stm32f103筆記

    [筆記]|[stm32]|[寄存器存儲(chǔ)器區(qū)別]|[PWM]|[串口]|[Timer]stm32f103筆記
    發(fā)表于 12-06 18:51 ?10次下載
    [<b class='flag-5'>筆記</b>]|[<b class='flag-5'>stm32</b>]|[寄存器存儲(chǔ)器區(qū)別]|[PWM]|[<b class='flag-5'>串口</b>]|[Timer]<b class='flag-5'>stm32</b>f103<b class='flag-5'>筆記</b>

    STM32實(shí)現(xiàn)IAP功能的學(xué)習(xí)筆記

    最近因項(xiàng)目需求要實(shí)現(xiàn)STM32的在線升級(jí)即IAP功能,先將這幾天的學(xué)習(xí)體會(huì)和IAP的具體實(shí)現(xiàn)總結(jié)出來,分享給大家,希望對(duì)同樣實(shí)現(xiàn)IAP的童鞋有所幫助,文中
    發(fā)表于 12-27 18:41 ?11次下載
    <b class='flag-5'>STM32</b>實(shí)現(xiàn)<b class='flag-5'>IAP</b>功能的學(xué)習(xí)<b class='flag-5'>筆記</b>

    基于STM32F103的IAP串口升級(jí)源碼

    基于STM32F103的IAP串口升級(jí)源碼代碼,共兩個(gè)工程,bl+app分享
    發(fā)表于 09-23 17:08 ?49次下載

    N32WB452系列芯片串口IAP升級(jí)應(yīng)用筆記

    N32WB452系列芯片串口IAP升級(jí)應(yīng)用筆記
    發(fā)表于 11-10 19:51 ?0次下載
    N32WB452系列芯片<b class='flag-5'>串口</b><b class='flag-5'>IAP</b>升級(jí)應(yīng)用<b class='flag-5'>筆記</b>

    N32G4FR系列芯片串口IAP升級(jí)應(yīng)用筆記

    N32G4FR系列芯片串口IAP升級(jí)應(yīng)用筆記
    發(fā)表于 11-10 19:51 ?10次下載
    N32G4FR系列芯片<b class='flag-5'>串口</b><b class='flag-5'>IAP</b>升級(jí)應(yīng)用<b class='flag-5'>筆記</b>

    N32G457系列芯片串口IAP升級(jí)應(yīng)用筆記

    N32G457系列芯片串口IAP升級(jí)應(yīng)用筆記
    發(fā)表于 11-10 19:51 ?1次下載
    N32G457系列芯片<b class='flag-5'>串口</b><b class='flag-5'>IAP</b>升級(jí)應(yīng)用<b class='flag-5'>筆記</b>

    N32G455系列芯片串口IAP升級(jí)應(yīng)用筆記

    N32G455系列芯片串口IAP升級(jí)應(yīng)用筆記
    發(fā)表于 11-10 19:51 ?9次下載
    N32G455系列芯片<b class='flag-5'>串口</b><b class='flag-5'>IAP</b>升級(jí)應(yīng)用<b class='flag-5'>筆記</b>

    N32G452系列芯片串口IAP升級(jí)應(yīng)用筆記

    N32G452系列芯片串口IAP升級(jí)應(yīng)用筆記
    發(fā)表于 11-10 19:51 ?5次下載
    N32G452系列芯片<b class='flag-5'>串口</b><b class='flag-5'>IAP</b>升級(jí)應(yīng)用<b class='flag-5'>筆記</b>

    AN3965 STM32F40x和STM32F41x基于串口IAP

    AN3965 STM32F40x和STM32F41x基于串口IAP
    發(fā)表于 11-24 08:31 ?0次下載
    AN3965 <b class='flag-5'>STM32</b>F40x和<b class='flag-5'>STM32</b>F41x基于<b class='flag-5'>串口</b>的<b class='flag-5'>IAP</b>
    主站蜘蛛池模板: 一本之道高清www在线观看| 日韩精品在线观看免费| 欧美牲交A欧美牲交VDO| 亚洲精品无AMM毛片| 国产AV亚洲一区精午夜麻豆| 青柠电影高清在线观看| adc网址在线观看| 男人插曲女人身体视频| 91夫妻交友论坛| 久久视热频国产这里只有精品23| 亚洲区欧美日韩综合| 好吊射视频988gaocom| 亚洲国产精品久久无套麻豆| 国产欧美日韩综合精品一区二区| 乌克兰内射私拍| 国产三级影院| 野花日本大全免费观看3中文版| 精品久久久麻豆国产精品 | 国产特级毛片AAAAAAA高清| 小776论坛| 精品久久久久亚洲| 2019一級特黃色毛片免費看| 男人扒开添女人屁股| jizz69女士第一次| 色欲狠狠躁天天躁无码中文字幕 | 黄片a级毛片| 中文字幕精品无码一区二区| 美女胸禁止18以下看| xxx粗大长欧美| 武侠古典久久亚洲精品| 精品在线观看一区| 9久高清在线不卡免费无吗视频| 青青草原91| 国产在线观看www| 4484在线观看视频| 日韩欧美1区| 寂寞少妇直播| free18sex性自拍裸舞| 天美传媒在线观看完整高清| 精彩国产萝视频在线| caoporn 超碰在线视频|