日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IAP固件升级原理及实现详解

發布時間:2023/12/16 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IAP固件升级原理及实现详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是IAP升級?

IAP,即In Application Programming,IAP是用戶自己的程序在運行過程中對User Flash的部分區域進行燒寫。簡單來說,就是開發者代碼出bug了或者添加新功能了,能夠利用預留的通訊接口,對代碼進行升級

UART、SPI、IIC、USB等等,當然還有wifi、4G、藍牙等無線通訊手段,都可以作為IAP升級的方式,今天主要介紹如何使用串口對固件進行升級

STM32的代碼啟動過程

要想設計IAP,首先需要對MCU的代碼啟動過程有個了解,先來看看STM32的代碼啟動過程是怎樣的吧

此部分參考:https://www.cnblogs.com/gulan-zmc/p/12248509.html

在《Cortex-M3權威指南》有講述:芯片復位后首先會從向量表里面取出兩個值(下圖來自Cortex-M3權威指南):

  • 從0x0000 0000地址取出MSP(主堆棧寄存器)的值

  • 從0x0000 0004地址取出PC(程序計數器)的值

  • 然后取出第一條指令執行

啟動文件源代碼分析

;********************?(C)?COPYRIGHT?2011?STMicroelectronics?******************** ;*?File?Name??????????:?startup_stm32f10x_hd.s ;*?Author?????????????:?MCD?Application?Team ;*?Version????????????:?V3.5.0 ;*?Date???????????????:?11-March-2011 ;*?Description????????:?STM32F10x?High?Density?Devices?vector?table?for?MDK-ARM? ;*??????????????????????toolchain.? ;*??????????????????????This?module?performs: ;*??????????????????????(上電復位后會做下面的幾件事情) ;*??????????????????????-?Set?the?initial?SP(設置堆棧,就是設置MSP的值) ;*??????????????????????-?Set?the?initial?PC?==?Reset_Handler(設置PC的值) ;*??????????????????????-?Set?the?vector?table?entries?with?the?exceptions?ISR?address(設置中斷向量表的地址) ;*??????????????????????-?Configure?the?clock?system?and?also?configure?the?external?(設置系統時鐘;如果芯片外部由掛載SRAM,還需要配置SRAM,默認是沒有掛外部SRAM的) ;*????????????????????????SRAM?mounted?on?STM3210E-EVAL?board?to?be?used?as?data? ;*????????????????????????memory?(optional,?to?be?enabled?by?user) ;*??????????????????????-?Branches?to?__main?in?the?C?library?(which?eventually??????(調用C庫的__main函數,然后調用main函數執行用戶的) ;*????????????????????????calls?main()). ;*??????????????????????After?Reset?the?CortexM3?processor?is?in?Thread?mode, ;*??????????????????????priority?is?Privileged,?and?the?Stack?is?set?to?Main. ;*?<<<?Use?Configuration?Wizard?in?Context?Menu?>>>??? ;*******************************************************************************;?------------------分配棧空間---------------- Stack_Size??????EQU?????0x00000400??????;EQU指令是定義一個標號;標號名是Stack_Size;?值是0x00000400(有點類似于C語言的#define)。Stack_Size標號用來定義棧的大小AREA????STACK,?NOINIT,?READWRITE,?ALIGN=3??;AREA指令是定義一個段;這里定義一個?段名是STACK,不初始化,數據可讀可寫,2^3=8字節對齊的段(詳細的說明可以查看指導手冊) Stack_Mem???????SPACE???Stack_Size???;SPACE匯編指令用來分配一塊內存;這里開辟內存的大小是Stack_Size;這里是1K,用戶也可以自己修改 __initial_sp??????;在內存塊后面聲明一個標號__initial_sp,這個標號就是棧頂的地址;在向量表里面會使用到;?<h>?Heap?Configuration ;???<o>??Heap?Size?(in?Bytes)?<0x0-0xFFFFFFFF:8> ;?</h> ;?------------------分配堆空間---------------- ;和分配棧空間一樣不過大小只是512字節 Heap_Size???????EQU?????0x00000200AREA????HEAP,?NOINIT,?READWRITE,?ALIGN=3__heap_base????????;__heap_base堆的起始地址 Heap_Mem????????SPACE???Heap_Size??????;分配一個空間作為堆空間,如果函數里面有調用malloc等這系列的函數,都是從這里分配空間的 __heap_limit???????;__heap_base堆的結束地址PRESERVE8?;PRESERVE8?指令作用是將堆棧按8字節對齊THUMB;THUMB作用是后面的指令使用Thumb指令集;?------------------設置中斷向量表---------------- ;?Vector?Table?Mapped?to?Address?0?at?ResetAREA????RESET,?DATA,?READONLY??????;定義一個段,段名是RESET的只讀數據段;EXPORT聲明一個標號可被外部的文件使用,使標號具有全局屬性EXPORT??__Vectors??????????;聲明一個__Vectors標號允許其他文件引用??????????EXPORT??__Vectors_End??????;聲明一個__Vectors_End標號允許其他文件引用EXPORT??__Vectors_Size?????;聲明一個__Vectors_Size標號允許其他文件引用;DCD?指令是分配一個或者多個以字為單位的內存,并且按四字節對齊,并且要求初始化;__Vectors?標號是?0x0000?0000?地址的入口,也是向量表的起始地址 __Vectors???????DCD?????__initial_sp???????????????;*?Top?of?Stack?????定義棧頂地址;單片機復位后會從這里取出值給MSP寄存器,;*?也就是從0x0000?0000?地址取出第一個值給MSP寄存器?(MSP?=?__initial_sp)?;*?__initial_sp的值是鏈接后,由鏈接器生成DCD?????Reset_Handler??????????????;*?Reset?Handler????定義程序入口的值;單片機復位后會從這里取出值給PC寄存器,;*?也就是從0x0000?0004?地址取出第一個值給PC程序計數器(pc?=?Reset_Handler);*?Reset_Handler是一個函數,在下面定義;后面的定義是中斷向量表的入口地址了這里就不多介紹了,想要了解的可以參考《STM32中文手冊》和《Cortex-M3權威指南》DCD?????NMI_Handler????????????????;?NMI?Handler??????DCD?????HardFault_Handler??????????;?Hard?Fault?HandlerDCD?????MemManage_Handler??????????;?MPU?Fault?HandlerDCD?????BusFault_Handler???????????;?Bus?Fault?HandlerDCD?????UsageFault_Handler?????????;?Usage?Fault?Handler.....由于文件太長這里省略了部分向量表的定義,完整的可以查看工程里的啟動文件DCD?????DMA2_Channel1_IRQHandler???;?DMA2?Channel1DCD?????DMA2_Channel2_IRQHandler???;?DMA2?Channel2DCD?????DMA2_Channel3_IRQHandler???;?DMA2?Channel3DCD?????DMA2_Channel4_5_IRQHandler?;?DMA2?Channel4?&?Channel5 __Vectors_End????????????????????????????????????;__Vectors_End向量表的結束地址__Vectors_Size??EQU??__Vectors_End?-?__Vectors???;定義__Vectors_Size標號,值是向量表的大小AREA????|.text|,?CODE,?READONLY??;定義一個代碼段,段名是|.text|,屬性是只讀;PROC指令是定義一個函數,通常和ENDP成對出現(標記程序的結束)??????????????? ;?Reset?handler Reset_Handler???PROC??????????????????????????????????????;定義?Reset_Handler函數;復位后賦給PC寄存器的值就是Reset_Handler函數的入口地址值。也是系統上電后第一個執行的程序EXPORT??Reset_Handler?????????????[WEAK]??;*[WEAK]指令是將函數定義為弱定義。所謂的弱定義就是如果其他地方有定義這個函數,;*編譯時使用另一個地方的函數,否則使用這個函數;*IMPORT???表示該標號來自外部文件,跟?C?語言中的?EXTERN?關鍵字類似IMPORT??__main????????????????????????????;*__main?和?SystemInit?函數都是外部文件的標號IMPORT??SystemInit????????????????????????;*?SystemInit?是STM32函數庫的函數,作用是初始化系統時鐘LDR?????R0,?=SystemInitBLX?????R0??????????????LDR?????R0,?=__main???????????????????????;*?__main是C庫的函數,主要是初始化堆棧和代碼重定位,然后跳到main函數執行用戶編寫的代碼BX??????R0ENDP;?Dummy?Exception?Handlers?(infinite?loops?which?can?be?modified) ;下面定義的都是異常服務函中斷服務函數 NMI_Handler?????PROCEXPORT??NMI_Handler????????????????[WEAK]B???????.ENDP .....由于文件太長這里省略了部分函數的定義,完整的可以查看工程里的啟動文件 SysTick_Handler?PROCEXPORT??SysTick_Handler????????????[WEAK]B???????.ENDPDefault_Handler?PROCEXPORT??WWDG_IRQHandler????????????[WEAK]EXPORT??PVD_IRQHandler?????????????[WEAK].....由于文件太長這里省略了部分中斷服務函數的定義,完整的可以查看工程里的啟動文件EXPORT??DMA2_Channel2_IRQHandler???[WEAK]EXPORT??DMA2_Channel3_IRQHandler???[WEAK]EXPORT??DMA2_Channel4_5_IRQHandler?[WEAK]WWDG_IRQHandler PVD_IRQHandler TAMPER_IRQHandler .....由于文件太長這里省略了部分標號的定義,完整的可以查看工程里的啟動文件 DMA2_Channel1_IRQHandler DMA2_Channel2_IRQHandler DMA2_Channel3_IRQHandler DMA2_Channel4_5_IRQHandlerB???????.ENDPALIGN????;四字節對齊;******************************************************************************* ;?User?Stack?and?Heap?initialization ;******************************************************************************* ;下面函數是初始化堆棧的代碼IF??????:DEF:__MICROLIB?????;如果定義了__MICROLIB宏編譯下面這部分代碼,__MICROLIB在MDK工具里面定義;這種方式初始化堆棧是由?__main?初始化的EXPORT??__initial_sp???;棧頂地址?(EXPORT將標號聲明為全局標號,供其他文件引用)EXPORT??__heap_base????;堆的起始地址EXPORT??__heap_limit???;堆的結束地址ELSE;由用戶初始化堆;否則編譯下面的IMPORT??__use_two_region_memory??????;__use_two_region_memory?由用戶實現EXPORT??__user_initial_stackheap__user_initial_stackheapLDR?????R0,?=??Heap_Mem??????????????;堆的起始地址LDR?????R1,?=(Stack_Mem?+?Stack_Size);棧頂地址LDR?????R2,?=?(Heap_Mem?+??Heap_Size);堆的結束地址LDR?????R3,?=?Stack_Mem??????????????;棧的結束地址BX??????LRALIGNENDIFEND;*******************?(C)?COPYRIGHT?2011?STMicroelectronics?*****END?OF?FILE*****

STM32的啟動步驟如下:

  • 1、上電復位后,從 0x0000 0000 地址取出棧頂地址賦給MSP寄存器(主堆棧寄存器),即MSP = __initial_sp。這一步是由硬件自動完成的

  • 2、從0x0000 0004 地址取出復位程序的地址給PC寄存器(程序計數器),即PC = Reset_Handler。這一步也是由硬件自動完成調用SystemInit函數初始化系統時鐘

  • 3、跳到C庫的__main函數初始化堆棧(初始化時是根據前面的分配的堆空間和棧空間來初始化的)和代碼重定位(初始RW 和ZI段),然后跳到main函數執行應用程序

IAP設計思路

大體分為兩部分設計,bootloader、APP代碼設計,bootloader用于檢查APP區代碼是否需要更新,以及跳轉到APP區執行APP程序

調研了一下群里的小伙伴,下面這個流程比較通用一些,大概是下圖所示升級流程:

升級流程圖

Flash分區

是以STM32F103RET6為主控做的flash分區,主要功能:

  • boot區:0x0800 0000 到 0x0800 b7FF 地址的flash塊劃分給bootloader,用于升級固件,大小是46kb

  • 用戶參數區:0x0800 B800 到 0x0800 BFFF 的flash塊劃分為用戶參數區(parameters),用于存儲用戶的一些參數,大小是2Kb

  • APP區:0x0800 C000 到 0x0804 3FFF 的flash塊劃分為APP區 ,(application)用于存放用戶功能應用代碼,大小是224Kb

  • APP緩存區:0x0804 4000 到 0x0807 BFFF 的flash塊劃分為APP緩存區 (update region),用于暫存下發的固件,大小跟應用程序區一樣 224kb

  • 未定義:0x0807 C000 到 0x0807 FFFF 的flash塊劃分未定義區,可以根據具體用途定義,大小是16Kb

代碼實現

硬件:

  • fallingstar-board(已開源,打板驗證)

軟件:

  • 內部flash讀寫

  • 串口DMA+空閑中斷

內部flash讀寫操作

這部分比較簡單,直接上代碼:

讀flash操作:

/*************************************************************?@brief???讀取2字節數據*?@param[in]???uint32_t?faddr*?@return??NULL*?@github??*?@date????2021-xx-xx*?@version?v1.0*?@note????NULL***********************************************************/ uint16_t?BSP_FLASH_ReadHalfWord(uint32_t?raddr) {return?*(__IO?uint16_t*)raddr;? } /*************************************************************?@brief??????讀取n(uint16_t)字節數據*?@param[in]???uint32_t?ReadAddr*?@param[out]??uint16_t?*pBuffer*?@param[in]???uint16_t?len*?@return??NULL*?@github??*?@date????2021-xx-xx*?@version?v1.0*?@note????NULL***********************************************************/ void?BSP_FLASH_Read?(uint32_t?ReadAddr,?uint16_t?*pBuffer,?uint16_t?len?)???? {uint16_t?i;for(i=0;i<len;i++){pBuffer[i]=BSP_FLASH_ReadHalfWord(ReadAddr);???//讀取2個字節.ReadAddr+=2;???????????????????//偏移2個字節.?} }

寫操作,注意寫之前要保證是沒有寫過的區域即可:

/*************************************************************?@brief???寫入n(uint16_t)字節數據*?@param[in]???uint32_t?ReadAddr*?@param[out]???uint16_t?*pBuffer*?@param[in]???uint16_t?len*?@return??NULL*?@github??*?@date????2021-xx-xx*?@version?v1.0*?@note????NULL***********************************************************/ void?BSP_FLASH_Write_NoCheck?(?uint32_t?WriteAddr,?uint16_t?*?pBuffer,?uint16_t?len?)??? {????????uint16_t?i;?for(i=0;i<len;i++){HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);WriteAddr+=2;????????????????????????????????????//地址增加2.}?? }? /*************************************************************?@brief?????寫入n(uint16_t)字節數據*?@param[in]??uint32_t?WriteAddr*?@param[in]??uint16_t?*pBuffer*?@param[in]??uint16_t?len*?@return??NULL*?@github??*?@date????2021-xx-xx*?@version?v1.0*?@note????NULL***********************************************************/ void?BSP_FLASH_Write(uint32_t?WriteAddr,uint16_t?*?pBuffer,uint16_t?len?)? {uint32_t?SECTORError?=?0;uint16_t?sector_off;????//扇區內偏移地址(16位字計算)uint16_t?sector_remain;?//扇區內剩余地址(16位字計算)????uint16_t?i;????uint32_t?secor_pos;????//扇區地址uint32_t?offaddr;???//去掉0X08000000后的地址if(WriteAddr<FLASH_BASE||(WriteAddr>=(FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址HAL_FLASH_Unlock();?????????//解鎖offaddr=WriteAddr-FLASH_BASE;????//實際偏移地址.secor_pos=offaddr/STM_SECTOR_SIZE;???//扇區地址??0~127?for?STM32F103RBT6sector_off=(offaddr%STM_SECTOR_SIZE)/2;??//在扇區內的偏移(2個字節為基本單位.)sector_remain=STM_SECTOR_SIZE/2-sector_off;??//扇區剩余空間大小???if(len<=sector_remain)sector_remain=len;//不大于該扇區范圍while(1)?{?BSP_FLASH_Read(secor_pos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//讀出整個扇區的內容for(i=0;i<sector_remain;i++)//校驗數據{if(STMFLASH_BUF[sector_remain+i]!=0XFFFF)break;//需要擦除?????}if(i<sector_remain)//需要擦除{//擦除這個扇區/*?Fill?EraseInit?structure*/EraseInitStruct.TypeErase?????=?FLASH_TYPEERASE_PAGES;EraseInitStruct.PageAddress???=?secor_pos*STM_SECTOR_SIZE+FLASH_BASE;EraseInitStruct.NbPages???????=?1;HAL_FLASHEx_Erase(&EraseInitStruct,?&SECTORError);for(i=0;i<sector_remain;i++)//復制{STMFLASH_BUF[i+sector_off]=pBuffer[i];???}BSP_FLASH_Write_NoCheck(secor_pos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//寫入整個扇區??}else?BSP_FLASH_Write_NoCheck(WriteAddr,pBuffer,sector_remain);//寫已經擦除了的,直接寫入扇區剩余區間.????????if(len==sector_remain)break;//寫入結束了else//寫入未結束{secor_pos++;????//扇區地址增1sector_off=0;????//偏移位置為0???pBuffer+=sector_remain;???//指針偏移WriteAddr+=sector_remain;?//寫地址偏移????len-=sector_remain;?//字節(16位)數遞減if(len>(STM_SECTOR_SIZE/2))sector_remain=STM_SECTOR_SIZE/2;//下一個扇區還是寫不完else?sector_remain=len;//下一個扇區可以寫完了}??};?HAL_FLASH_Lock();//上鎖 }

串口DMA+空閑中斷接收不定長數據

麻煩小伙伴移步:

串口DMA+空閑中斷接收不定長數據

在上篇文章的基礎上,我們對結構體做點修改,增加bin文件數據總長度記錄,以及bin文件接收完成標志(小伙伴們可以采用其他辦法,不必拘泥于我教程中的方式):

#define?Max_RecLen?1024*3typedef?struct{uint8_t?RxBuffer[Max_RecLen];??//DMA接收緩沖區uint16_t?RecDat_len;??????//單包數據長度uint32_t?Cur_WriteAddr;?????//APP緩沖區地址uint16_t?BinLen;????????//bin文件數據長度uint8_t?rec_endFlag;??????//單包數據接收結束標志uint8_t?Binrec_endFlag;?????????//bin文件接收結束標志?uint16_t?DMA_TIMCNT;???????//bin文件下發超時計數器}UserUartDMA_Typedef;

然后在串口中斷中:

/***?@brief?This?function?handles?USART1?global?interrupt.*/ void?USART1_IRQHandler(void) {/*?USER?CODE?BEGIN?USART1_IRQn?0?*/uint32_t?idle_flag_temp?=?0;uint16_t?len_temp?=?0;/*?USER?CODE?END?USART1_IRQn?0?*/HAL_UART_IRQHandler(&huart1);/*?USER?CODE?BEGIN?USART1_IRQn?1?*/idle_flag_temp?=?__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);if(idle_flag_temp){__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_IDLE);HAL_UART_DMAStop(&huart1);UserUartDma.DMA_TIMCNT?=?0;UserUartDma.Binrec_endFlag=0;len_temp?=?__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);UserUartDma.RecDat_len?=?Max_RecLen?-?len_temp;??UserUartDma.BinLen+=UserUartDma.RecDat_len;UserUartDma.rec_endFlag?=?1;}__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);HAL_UART_Receive_DMA(&huart1,UserUartDma.RxBuffer,Max_RecLen);?/*?USER?CODE?END?USART1_IRQn?1?*/ }

IAP代碼設計

  • bootloader代碼設計

扇區擦除,用于寫入前擦除相應扇區

/****************************************************** *?Brief?????:?擦除APP區 *?Parameter?:? *???????????*startaddr:APP起始地址 *??????*pages??:要擦除的page?=?APPSIZE/PAGESIZE *?Return????:None. *******************************************************/ void?APPReigion_Erase(uint32_t?startaddr,uint16_t?pages) {uint32_t?SECTORError?=?0;//擦除APP區/*?Fill?EraseInit?structure*/EraseInitStruct.TypeErase?????=?FLASH_TYPEERASE_PAGES;EraseInitStruct.PageAddress???=?startaddr;EraseInitStruct.NbPages???????=?pages;HAL_FLASHEx_Erase(&EraseInitStruct,?&SECTORError); }

升級標志獲取與擦除

/****************************************************** *?Brief?????:?寫入升級標志 *?Parameter?:? *???????????*addr:標志存放地址 *??????*pdata:寫入的數據 *?Return????:None. *******************************************************/ void?APP_UpdateFlag_Write(uint32_t?addr,uint16_t?*pdata) {BSP_FLASH_Write(addr,pdata,1); } /****************************************************** *?Brief?????:?獲取升級標志 *?Parameter?:? *???????????*addr:標志存放地址 *?Return????:None. *******************************************************/ uint16_t?APP_UpdateFlag_Read(uint32_t?addr) {uint16_t?flag_temp;BSP_FLASH_Read(addr,&flag_temp,1);return?flag_temp; }

接下來就是APP緩沖區數據寫入,APP區與APP緩沖區數據倒騰了

/****************************************************** *?Brief?????:?Bin文件寫入app緩沖區 *?Parameter?:? *???????????StartAddr:?起始地址 *???????????*pBin_DataBuf:?要傳輸的數據 *???????????packBufLength:單包數據長度 *?Return????:?None. *******************************************************/ void?IAP_WriteBin(uint32_t?StartAddr,uint8_t?*?pBin_DataBuf,uint32_t?packBufLength) {uint16_t?pack_len,?packlen_Ctr=0,?dataTemp;uint8_t?*?pData?=?pBin_DataBuf;for?(pack_len?=?0;?pack_len?<?packBufLength;?pack_len?+=?2?){??????????dataTemp?=??(?uint16_t?)?pData[1]<<8;dataTemp?+=?(?uint16_t?)?pData[0];???pData?+=?2;??????????????????????????????????????????????????????//偏移2個字節ulBuf_Flash_App?[?packlen_Ctr?++?]?=?dataTemp;?????}?BSP_FLASH_Write?(?UserUartDma.Cur_WriteAddr,?ulBuf_Flash_App,?packlen_Ctr?);?UserUartDma.Cur_WriteAddr?+=?(packlen_Ctr*2);???????????????????????????????????????????//偏移packlen_Ctr??16=2*8.所以要乘以2.packlen_Ctr?=?0; } /****************************************************** *?Brief?????:?Bin文件從app緩沖區寫入app區 *?Parameter?:? *???????????SrcStartAddr:?app緩沖區起始地址 *???????????DstStartAddr:?APP區起始地址 *???????????BinLength:bin文件長度*?Return????:?None. *******************************************************/ void?IAP_WriteBinToAPPReigon(uint32_t?SrcStartAddr,uint32_t?DstStartAddr,uint32_t?BinLength) {uint16_t?data_temp?=?0;uint32_t?count=0;HAL_FLASH_Unlock();?????????//解鎖APPReigion_Erase(APP_START_ADDR,APPSIZE/PAGESIZE);HAL_Delay(10);for(count=0;count<BinLength;count=count+2){BSP_FLASH_Read?(SrcStartAddr,?&data_temp,?1);BSP_FLASH_Write_NoCheck(DstStartAddr,?&data_temp,1);SrcStartAddr+=2;DstStartAddr+=2;}//BSP_FLASH_Write_NoCheck(DstStartAddr,?,1);HAL_FLASH_Lock();//上鎖 }

最后,要設置APP程序的運行地址

/****************************************************** *?Brief?????:?設置棧頂指針 *?Parameter?:? *???????????ulAddr:? *?Return????:?None. *******************************************************/__asm?void?MSR_MSP?(?uint32_t?ulAddr?)? {MSR?MSP,?r0???????????????????????//set?Main?Stack?valueBX?r14 }/****************************************************** *?Brief?????:?IAP執行 *?Parameter?:? *???????????ulAddr_App:?APP起始地址 *?Return????:?None. *******************************************************/ void?IAP_ExecuteApp?(?uint32_t?ulAddr_App?) {pIapFun_TypeDef?pJump2App;?if?(?(?(?*?(?__IO?uint32_t?*?)?ulAddr_App?)?&?0x2FFE0000?)?==?0x20000000?)???//檢查棧頂地址是否合法.{?pJump2App?=?(?pIapFun_TypeDef?)?*?(?__IO?uint32_t?*?)?(?ulAddr_App?+?4?);?//用戶代碼區第二個字為程序開始地址(復位地址)??MSR_MSP(?*?(?__IO?uint32_t?*?)?ulAddr_App?);?//初始化APP堆棧指針(用戶代碼區的第一個字用于存放棧頂地址)pJump2App?();?????????????????????????????????????????????//跳轉到APP.} }??

IAP相關的代碼就這些,主要是數據的倒騰,其他倒也沒什么復雜的

目前小飛哥對整包bin文件傳輸完成判斷,單包采用DMA+空閑中斷的方式,整包文件傳輸采用的是串口中斷在5s內沒有數據過來,認為一包數據接收完成,置位接收標志,這部分小伙伴可以自行判斷

static?void?Systick_Config(void) {HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()?/?1000);?//1msHAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);HAL_NVIC_SetPriority(SysTick_IRQn,?0,?0); }void?HAL_SYSTICK_Callback(void) {UserUartDma.DMA_TIMCNT++;if(UserUartDma.DMA_TIMCNT>5000){UserUartDma.Binrec_endFlag?=?1;UserUartDma.DMA_TIMCNT?=?0;}TIMX_IRQHandler_user();? }

bin文件傳輸完成后,寫入需要更新標志,重新跳轉至boot區,檢查是否APP代碼需要更新:

uint32_t?Task_02() {if(UserUartDma.rec_endFlag){PRINT_INFO("update?firmware\n");PRINT_INFO("APP?長度:%d字節\n",?UserUartDma.RecDat_len);??UserUartDma.rec_endFlag?=?0;IAP_WriteBin(UserUartDma.Cur_WriteAddr,UserUartDma.RxBuffer,UserUartDma.RecDat_len);memset(UserUartDma.RxBuffer,0,UserUartDma.RecDat_len);UserUartDma.RecDat_len?=?0;}if(UserUartDma.BinLen!=0){if(UserUartDma.Binrec_endFlag){UserUartDma.Binrec_endFlag?=?0;APP_UpdateFlag_Write(APP_Len_ADDR,&UserUartDma.BinLen);???//寫入升級標志APP_UpdateFlag_Write(APP_UpdateFlag_ADDR,&APP_UPDATE_FLAG);???//寫入升級標志UserUartDma.BinLen?=?0;??IAP_ExecuteApp(FLASH_BASE);???//跳轉8000000,重新啟動HAL_Delay(2000);}} }

MCU復位之后,初始化執行過程中,對APP升級標志進行檢測:

PRINT_INFO("-----IAP?Menu--------------\n");PRINT_INFO("-----Download?APP?BIN------\n");PRINT_INFO("-----Restart?To?RUN?APP----\n");?PRINT_INFO("\n\n\n");if(0x5aa5==APP_UpdateFlag_Read(APP_UpdateFlag_ADDR)){PRINT_INFO("-----Restart.....5-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....4-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....3-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....2-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....1-------\n");HAL_Delay(1000);PRINT_INFO("the?device?need?update\n");IAP_WriteBinToAPPReigon(APP_Temp_ADDR,APP_START_ADDR,APP_UpdateFlag_Read(APP_Len_ADDR));?PRINT_INFO("firmware?write?OK\n");PRINT_INFO("please?double?click?the?button?the?execute?the?application\n");HAL_FLASH_Unlock();?????????//解鎖APPReigion_Erase(APP_Temp_ADDR,APPSIZE/PAGESIZE);??//擦除APP緩沖區APPReigion_Erase(Flash_UNUSED,1);??????????//清除APP更新標志?????HAL_FLASH_Lock();??????????//上鎖PRINT_INFO?(?"開始執行?APP\n"?);?//執行FLASH?APP代碼IAP_ExecuteApp(APP_START_ADDR);}?

倒計時5秒后,代碼更新,并執行

?PRINT_INFO("-----IAP?Menu--------------\n");PRINT_INFO("-----Download?APP?BIN------\n");PRINT_INFO("-----Restart?To?RUN?APP----\n");?PRINT_INFO("\n\n\n");if(0x5aa5==APP_UpdateFlag_Read(APP_UpdateFlag_ADDR)){PRINT_INFO("-----Restart.....5-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....4-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....3-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....2-------\n");HAL_Delay(1000);PRINT_INFO("-----Restart.....1-------\n");HAL_Delay(1000);PRINT_INFO("the?device?need?update\n");IAP_WriteBinToAPPReigon(APP_Temp_ADDR,APP_START_ADDR,APP_UpdateFlag_Read(APP_Len_ADDR));?PRINT_INFO("firmware?write?OK\n");PRINT_INFO("please?double?click?the?button?the?execute?the?application\n");HAL_FLASH_Unlock();?????????//解鎖APPReigion_Erase(APP_Temp_ADDR,APPSIZE/PAGESIZE);??//擦除APP緩沖區APPReigion_Erase(Flash_UNUSED,1);??????????//清除APP更新標志?????HAL_FLASH_Lock();??????????//上鎖PRINT_INFO?(?"開始執行?APP\n"?);?//執行FLASH?APP代碼IAP_ExecuteApp(APP_START_ADDR);}?else//不需要更新,執行APP{IAP_ExecuteApp(APP_START_ADDR);}

bin文件生成

輸入:

C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe --bin -o IAP.bin UART_CircleQueueTest\UART_CircleQueueTest.axf

參數意義:

  • C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe: fromelf.exe文件目錄地址,一般keil下自帶有

  • --bin -o IAP.bin :

輸出bin文件名稱

  • UART_CircleQueueTest\UART_CircleQueueTest.axf:

axf文件目錄及文件

要注意boot區的地址范圍,根據前面的設計,46K,拿出計算器....

  • APP代碼設計

APP代碼是用戶功能代碼,實現業務邏輯,本次測試用的比較簡單,接收到APP代碼之后,會自動重啟,更新APP區代碼,如下:

  • boot區代碼執行效果

  • APP1代碼執行效果

  • 接下來再進行一次更新

注意APP BIN文件的flash地址設置

OK,至此,設計部分就完成了,涉及的內容還是非常多的

本文僅僅用于原理性介紹及IAP功能演示,與工程中實際使用的還是有很大區別的,后面會繼續給大家出工程應用方便的教程,會涉及到簽名、驗簽、加解密、校驗固件完整性等等

特別感謝

感謝群友大帥比“肥嘟嘟左衛門”特為小伙伴們寫的上位機測試軟件,非常的nice,上位機軟件還在更新中,歡迎小伙伴們進群聊,催更!!!

資料獲取

歡迎關注公眾號,后臺回復“IAP”即可獲取測試boot、APP源碼,歡迎添加小飛哥好友,進群一起交流!

總結

以上是生活随笔為你收集整理的IAP固件升级原理及实现详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

freejavvideo日本免费| 午夜国产在线观看 | 色偷偷男人的天堂av | 丁香激情综合久久伊人久久 | 亚洲第一久久久 | 欧美特一级 | 免费av高清 | 99精品系列| 国产涩涩在线观看 | 欧美午夜一区二区福利视频 | 日本系列中文字幕 | 亚洲美女精品区人人人人 | 国产打女人屁股调教97 | 久久婷婷丁香 | 狠狠久久婷婷 | 亚洲精品美女在线观看 | 亚洲精品在线国产 | 日韩电影中文,亚洲精品乱码 | 午夜色大片在线观看 | 久久免费国产精品 | 美女黄久久 | 成人国产网址 | 天天玩天天干天天操 | 久久免费中文视频 | 国产1区在线观看 | 成人免费在线观看av | 永久黄网站色视频免费观看w | 成年人视频在线 | 亚洲一区精品二人人爽久久 | 日韩一区二区三区在线看 | 日韩欧美国产成人 | av一级在线 | 国产成人久久av免费高清密臂 | 天天操天天干天天综合网 | 国产成人333kkk | 国产精品久久99综合免费观看尤物 | www.午夜| 91视频电影 | 五月婷婷六月丁香在线观看 | 干亚洲少妇 | 一级一片免费视频 | 久久久午夜影院 | 在线91色 | 中文字幕在线播放第一页 | 精品国产伦一区二区三区观看方式 | 69国产精品视频免费观看 | 狠狠久久婷婷 | 蜜桃av久久久亚洲精品 | 色综合久久网 | 国产成人一区在线 | 国产精品毛片久久久久久久 | 偷拍精品一区二区三区 | 欧美日韩二区三区 | 午夜精品一区二区三区免费视频 | 精品视频一区在线 | 人人爽人人干 | 伊人视频 | 亚洲精品视 | 国产精品激情偷乱一区二区∴ | 国产精品美女在线观看 | a级一a一级在线观看 | 97色婷婷成人综合在线观看 | 国产精品观看视频 | 右手影院亚洲欧美 | 欧美先锋影音 | 午夜久久久久久久 | 在线亚洲欧美日韩 | 99久久久久国产精品免费 | 99re久久精品国产 | www.国产在线 | 有码中文在线 | 激情五月婷婷激情 | 97av色| 黄色大片av | www最近高清中文国语在线观看 | 伊色综合久久之综合久久 | 国产亚洲91| 日韩欧美在线高清 | 国产精品99在线播放 | 亚洲国产精品视频在线观看 | www.在线观看av | 久久久精品在线观看 | 国产精品久久久久久久妇 | 狠狠的操狠狠的干 | 国精产品999国精产 久久久久 | 亚洲精品欧洲精品 | 99久久精品国产亚洲 | 日韩成人一级大片 | 免费av在线播放 | 久久视频国产 | 国产精品乱看 | 韩国在线一区 | 一本—道久久a久久精品蜜桃 | 日韩欧美综合精品 | 亚洲va欧洲va国产va不卡 | 婷婷久久综合九色综合 | 在线影院中文字幕 | 又黄又爽又无遮挡的视频 | 热久久视久久精品18亚洲精品 | 欧美电影黄色 | 日韩av偷拍 | 亚洲专区 国产精品 | 99r在线播放 | 国产精品黄色在线观看 | 天天天干天天射天天天操 | 久久高清视频免费 | 在线你懂的视频 | 99色在线视频 | 成人av电影免费观看 | 黄色a在线 | 亚洲v欧美v国产v在线观看 | 国产97在线观看 | 亚洲精品欧美视频 | 国产又粗又猛又爽 | 在线视频久久 | 欧美巨大荫蒂茸毛毛人妖 | 在线观看av黄色 | 337p日本欧洲亚洲大胆裸体艺术 | 久久看免费视频 | 亚洲精品在线免费观看视频 | 在线看成人| 日韩欧美综合 | 久久歪歪| 九九综合九九综合 | 欧美亚洲免费在线一区 | 国产美女在线精品免费观看 | 久久国产成人午夜av影院宅 | www.香蕉视频在线观看 | 91在线精品观看 | 国产美女视频免费观看的网站 | 91色在线观看 | 日韩精品欧美一区 | 九色91在线| 中文字幕一区av | 91网址在线看 | 国产专区在线视频 | 亚洲精品国产精品国自产在线 | 日韩视频免费看 | 成年人免费在线观看网站 | 一区二区电影在线观看 | 国产精品第一页在线 | 国产高清视频免费观看 | 精品在线观看视频 | 99久久婷婷国产综合精品 | 久久精品日产第一区二区三区乱码 | av福利网址导航大全 | 久久免费观看少妇a级毛片 久久久久成人免费 | 日韩一区二区在线免费观看 | 成人av一区二区兰花在线播放 | 亚洲国产免费看 | 在线免费视频一区 | 久久爽久久爽久久av东京爽 | 视频国产在线观看18 | 色爽网站 | 亚洲黄色高清 | 亚洲最新av在线 | 欧美一区二区三区四区夜夜大片 | 日韩免费电影 | 热久久最新地址 | 久久精品亚洲一区二区三区观看模式 | 国产成人综合精品 | 一区久久久 | 蜜臀91丨九色丨蝌蚪老版 | 一区二区不卡 | 四虎永久免费网站 | 免费a网 | 久久久久久久久久久免费 | 国产伦精品一区二区三区四区视频 | 婷婷中文字幕 | 亚洲精品理论 | 亚洲精品字幕在线 | 欧美激情精品久久久久久免费 | 中文字幕91视频 | 一区二区三区四区在线 | 99re国产视频 | 日韩大片在线免费观看 | 最近2019好看的中文字幕免费 | 国产视频在线看 | 丁香六月激情 | 免费精品久久久 | 最近高清中文在线字幕在线观看 | 草莓视频在线观看免费观看 | 免费精品在线视频 | 色婷婷伊人 | 久久99精品热在线观看 | 欧美 日韩 久久 | 久久亚洲综合色 | 亚洲国产精彩中文乱码av | 激情丁香综合五月 | 精品国产1区二区 | 九九久久国产精品 | 欧美日韩a视频 | 91自拍91| av观看久久久 | 国产精品久久久久久久久久东京 | 亚洲综合视频在线观看 | 五月激情婷婷丁香 | 中文字幕在线观看播放 | 四虎影视国产精品免费久久 | 天天干天天插 | 在线观看av免费观看 | 免费又黄又爽 | 亚洲精品视频在线观看视频 | 中文字幕在线免费观看 | 国产亚洲精品久久久久秋 | 婷婷久久亚洲 | 亚洲影院一区 | 国语麻豆 | 日韩狠狠操| 国产va精品免费观看 | 99r在线播放 | 一级黄毛片 | 久久免费国产精品 | 日韩免费视频观看 | 国内精品久久久久影院优 | 国产精品久久99综合免费观看尤物 | 国产精品免费av | 中文字幕在线观看的网站 | 啪啪资源 | 久久免费看 | 天天摸日日操 | 91在线观看视频 | 免费久久视频 | 91精品专区 | 在线 视频 一区二区 | 国产精品18久久久久久久 | 国产高清无线码2021 | 成人性生交大片免费看中文网站 | 午夜精品一区二区三区在线播放 | 不卡国产视频 | 久久久久久99精品 | 欧美韩国日本在线观看 | 偷拍精偷拍精品欧洲亚洲网站 | 国产伦理一区 | 99九九视频 | 91漂亮少妇露脸在线播放 | 国产精品久久久久久久久久久不卡 | 日韩亚洲精品电影 | 9992tv成人免费看片 | av线上看| 久久91久久久久麻豆精品 | 久久不卡日韩美女 | 国产精品久久99精品毛片三a | 日夜夜精品视频 | 亚洲影音先锋 | 91亚色视频在线观看 | 三级动态视频在线观看 | 国产成人久久av977小说 | 国产精品18久久久久久首页狼 | 久久69精品久久久久久久电影好 | 在线视频欧美亚洲 | 午夜三级福利 | 91网免费观看 | 91麻豆精品91久久久久同性 | 免费观看视频的网站 | 婷婷激情五月综合 | 国产精品一区二区果冻传媒 | 西西www444 | 综合激情婷婷 | 国产精品久久久久久久久久久杏吧 | 黄色av在| 久久久久网址 | 日韩成人av在线 | 国产97在线播放 | 在线黄色毛片 | 美女露久久| 欧美色黄| 国产精品久久久久久久久久久久午夜片 | 最新成人av | 日韩最新中文字幕 | 欧美亚洲另类在线视频 | 99国产精品视频免费观看一公开 | 91插插插网站 | 国产精品24小时在线观看 | 在线看片a| 91在线国产观看 | 99国产精品免费网站 | 在线看小早川怜子av | 黄色av网站在线观看免费 | av日韩在线网站 | 亚洲女同videos | 亚洲精品a区 | 国产高清永久免费 | 亚州精品天堂中文字幕 | 久久在线精品 | 中文字幕 国产专区 | 亚洲精品免费观看视频 | a黄色大片 | 五月天综合色激情 | 丝袜美腿在线播放 | 九色porny真实丨国产18 | 久久99久久精品国产 | 成人小视频在线观看免费 | 91精品网站在线观看 | 天天干天天做天天爱 | 免费观看一区 | 99精品黄色 | 国产第一二区 | 国产精品一区二区在线看 | 国产在线播放不卡 | 在线观看黄色大片 | 亚洲一区二区三区毛片 | 国产婷婷在线观看 | 天天曰天天爽 | 国产视频在线观看一区 | 日韩免费在线看 | 激情一区二区三区欧美 | 一区二区三区四区在线免费观看 | 中文字幕日韩国产 | 中文字幕精品www乱入免费视频 | 狠狠狠狠狠狠狠狠 | 国产黄色片免费 | 婷婷电影在线观看 | 349k.cc看片app| 中文字幕在线观看视频一区二区三区 | 国产免费久久久久 | 日韩三级在线观看 | 成人精品久久 | 国产欧美日韩精品一区二区免费 | 91精品一区国产高清在线gif | 日韩亚洲在线观看 | 天堂久久电影网 | 欧美精彩视频在线观看 | 欧美日韩国产精品一区二区三区 | 911香蕉视频| 亚洲成人软件 | 免费www视频| 欧美巨乳波霸 | 久久伊人五月天 | 99热最新 | 日韩在线精品一区 | 亚洲成人av一区二区 | 中文字幕综合在线 | 成人国产网站 | 99国产在线观看 | 久久免费成人精品视频 | 国产精品日韩欧美一区二区 | 中文字幕91 | 最新国产精品久久精品 | 综合国产在线 | 夜色成人网 | 在线观看免费日韩 | 国产精品女视频 | 五月婷婷综合激情 | 九九免费在线看完整版 | 亚洲少妇影院 | 成人av在线播放网站 | 久久久久成人精品 | 狠狠躁18三区二区一区ai明星 | 国产直播av| 99精品在线免费观看 | 国产精品6999成人免费视频 | 欧美日韩一区二区三区视频 | 日韩在线大片 | 欧美日本一二三 | 午夜精品久久久久久久99热影院 | 美女视频黄的免费的 | 国产精品av免费 | 99九九99九九九视频精品 | 亚洲精品免费观看视频 | a级一a一级在线观看 | 欧美激情综合五月色丁香小说 | 欧美精品久久天天躁 | 日韩激情视频在线 | 91激情在线视频 | 亚洲成人免费在线观看 | 网站免费黄 | 一级黄视频 | 99精品色| 欧美日韩高清免费 | 国产精品久久久久久久7电影 | 亚洲欧美色婷婷 | 444av| 午夜av激情 | 成人黄大片视频在线观看 | 久草网在线 | 欧美最爽乱淫视频播放 | 狠狠狠色丁香婷婷综合激情 | 国产99久久久欧美黑人 | 免费在线观看午夜视频 | 久久国产精品99久久久久久老狼 | 97香蕉超级碰碰久久免费软件 | 337p日本欧洲亚洲大胆裸体艺术 | 一级特黄av | 日精品| 97精品在线 | 国产精品一区免费看8c0m | 911久久香蕉国产线看观看 | av电影免费| 一区二区在线电影 | 免费av大片| 中文字幕永久在线 | 精品一区免费 | 制服丝袜在线91 | 综合久色 | 亚洲精欧美一区二区精品 | 天天av综合网| 国产夫妻性生活自拍 | 日韩久久午夜一级啪啪 | 免费久久片 | 免费色视频在线 | 久久久国产精品视频 | 麻豆首页 | 人人擦 | 在线精品在线 | 婷婷在线视频 | japanesexxx乱女另类 | 亚洲第一av在线 | av三级在线播放 | 91看片在线观看 | 亚洲九九影院 | 夜色资源站国产www在线视频 | 日韩欧美视频在线观看免费 | 久久艹艹 | www.久久成人 | 精品视频成人 | 91久久久久久久一区二区 | 精品久久久久久亚洲综合网站 | 婷婷九九 | 亚洲综合网站在线观看 | 99热精品久久 | 91麻豆精品国产自产在线游戏 | 天天干,天天操,天天射 | 日韩欧美高清在线 | 久久成人高清 | 久久五月婷婷综合 | 日日夜夜噜 | 国产99自拍 | 国产视频一区在线免费观看 | 久久视频免费看 | 成人在线免费观看视视频 | 精品久久久久久久久久久久久 | a久久免费视频 | 国内精品久久久精品电影院 | 国产一级特黄毛片在线毛片 | 国产欧美综合视频 | 激情欧美丁香 | 九九九热精品免费视频观看 | 久热免费 | 国产亚洲精品成人av久久影院 | 亚洲女欲精品久久久久久久18 | 天天综合91 | 四虎在线观看精品视频 | 国产精品一区二区三区在线播放 | 91福利影院在线观看 | 在线观看成人一级片 | 欧美 亚洲 另类 激情 另类 | 久久在线视频在线 | 国产黑丝一区二区 | 日韩av电影一区 | 国产精品欧美 | 久久亚洲热| 麻豆影视在线免费观看 | 欧美日韩国产一二三区 | 国产亚洲综合在线 | 一区中文字幕电影 | 久久国产一区二区三区 | 国产 欧美 日产久久 | 日本在线观看中文字幕无线观看 | 亚洲精品欧美成人 | 日韩免费观看一区二区 | 国产成人久久精品 | 国产精品久久久久久69 | 亚洲人成人在线 | 国产一区在线视频播放 | 粉嫩高清一区二区三区 | 久久久视频在线 | 精品久久久久久久久久岛国gif | 成人作爱视频 | www.久久久com| 欧美va在线观看 | 黄色毛片电影 | 中文字幕网址 | 日韩av片无码一区二区不卡电影 | 久久久免费观看视频 | 麻豆影视在线观看 | 日韩免费不卡视频 | 国产一区久久 | 激情电影影院 | 日韩av电影一区 | 99精品在线直播 | av免费观看高清 | www.大网伊人 | 欧美视频不卡 | 婷婷久久丁香 | 18+视频网站链接 | 91资源在线免费观看 | 男女啪啪免费网站 | 91成人看片| japanese黑人亚洲人4k | 嫩草av影院| 91亚洲欧美激情 | 在线观看国产一区二区 | 亚洲一区欧美激情 | 国内精品久久久久影院一蜜桃 | av片一区二区| 色偷偷888欧美精品久久久 | 麻豆精品传媒视频 | 中文字幕在线播放日韩 | 国产免费人人看 | 中文字幕丝袜一区二区 | 久产久精国产品 | 中文字幕激情 | 成人黄色在线看 | 国产美女精品视频 | 国产99色| 色婷婷综合久久久中文字幕 | 中文字幕高清 | 国产欧美精品一区二区三区 | 午夜精品久久久久久久久久久久 | 黄色免费av | 美女视频黄免费网站 | 一级黄色片在线播放 | 在线视频18在线视频4k | 岛国av在线| av免费网站 | 午夜精品视频免费在线观看 | 欧美最猛性xxx | 国产精品女主播一区二区三区 | 婷婷色六月天 | 日韩精品一区二区三区免费观看视频 | 免费高清无人区完整版 | 精品免费视频123区 午夜久久成人 | 欧美超碰在线 | 99免费| 亚洲成人精品久久久 | 国产福利在线免费 | 久99精品 | 欧美一区二区三区在线 | 激情五月综合网 | 99999精品视频| 欧美a级在线 | www.久久免费视频 | 亚洲国内精品 | 久久99国产精品久久99 | 色99在线 | 国产精品久久久久久久久久ktv | 亚洲欧洲中文日韩久久av乱码 | 欧美三人交 | 久久免费看 | 国产精品va最新国产精品视频 | 在线免费观看欧美日韩 | 91福利视频免费 | 久久久免费高清视频 | 特级西西444www大胆高清无视频 | 中文字幕欧美三区 | 亚洲成av人影院 | 日本精品在线 | 亚洲成人999 | 欧美在线视频不卡 | 91人人澡人人爽人人精品 | 综合激情婷婷 | 在线成人免费电影 | 超碰精品在线 | 色橹橹欧美在线观看视频高清 | 91污视频在线观看 | 国产精品高清一区二区三区 | 久久99精品久久久久久三级 | 玖玖玖影院 | 亚洲欧洲精品一区二区 | 久久久久国产一区二区三区四区 | 毛片的网址 | 亚洲日本韩国一区二区 | 国产视频在线一区二区 | 国产一级在线观看视频 | 日韩毛片精品 | 97操碰 | 丁香六月婷 | 国产精品久久久久久一区二区 | 四虎影视成人 | 乱男乱女www7788 | 午夜精品久久一牛影视 | 色天天综合网 | 男女激情免费网站 | 夜夜视频欧洲 | 国产特级毛片aaaaaa毛片 | 99一区二区三区 | 精品免费久久久久 | 9色在线视频 | 国产福利a| 最新日本中文字幕 | 成人在线视频你懂的 | 欧美va在线观看 | 国产一二区视频 | 中文视频在线看 | 天天综合网在线观看 | 国产精品1区2区3区 久久免费视频7 | 91成人免费视频 | 中文字幕日韩国产 | 久久久免费少妇 | 国产精品 国产精品 | 免费在线h | 丁香婷婷色综合亚洲电影 | 久久久久欠精品国产毛片国产毛生 | www免费看片com| 韩国一区在线 | 97成人精品视频在线播放 | 日日夜夜天天干 | av线上看 | 精品国产免费一区二区三区五区 | 中文字幕网站视频在线 | 亚洲激情 欧美激情 | 中文字幕精品www乱入免费视频 | 久久香蕉电影网 | 丁香激情综合国产 | 就色干综合 | 国产成人av在线影院 | 九九99 | 日韩精品中文字幕av | 亚洲高清激情 | 国产一区二区三区 在线 | 日韩三区在线 | 欧美日韩中文字幕视频 | 97电影手机版| 国产剧情一区二区在线观看 | 久久久99久久 | 99精品视频在线观看播放 | 亚洲深爱激情 | 欧洲精品在线视频 | 国产精品欧美一区二区 | 97操操操| 国产专区在线播放 | 精品亚洲一区二区 | 国产中文字幕一区二区 | 国产一区二区不卡视频 | 成人黄性视频 | 国产亚洲欧美一区 | 久久久网| 不卡在线一区 | 亚洲精品国产精品国 | a黄色片| 日韩sese | 激情五月激情综合网 | 久亚洲 | 亚洲成人午夜在线 | 中文在线天堂资源 | 免费亚洲婷婷 | 成人黄色片在线播放 | 精品一区二区影视 | 欧美 日韩 国产 成人 在线 | 黄色片网站大全 | 欧美精品一区二区三区一线天视频 | 91香蕉视频720p | 91中文字幕一区 | 69国产盗摄一区二区三区五区 | 日韩首页 | 欧美日韩中文在线观看 | 狠狠狠狠狠色综合 | 免费在线观看一区 | 日韩欧美国产成人 | 免费看v片 | 久久 国产一区 | 日韩精品一区二区免费 | 成人免费观看大片 | 九九久久成人 | 国产一级在线观看视频 | 天天爽天天碰狠狠添 | 天天摸天天操天天舔 | 国产精品久久久久永久免费看 | 国产精品国产三级国产aⅴ无密码 | 99热国产在线观看 | 免费在线观看av不卡 | 国产在线色视频 | 在线午夜av | 一级欧美日韩 | 国产高清在线观看 | 国产午夜精品一区二区三区嫩草 | 欧美高清视频不卡网 | 精品国产欧美一区二区三区不卡 | 香蕉网在线观看 | 国产精品 久久 | 96久久 | 91女神的呻吟细腰翘臀美女 | 国产一区二区免费 | 制服丝袜一区二区 | 青青五月天 | 狠狠操在线 | 欧美人牲 | 外国av网| 欧美在线视频精品 | 天天操天天怕 | 高清av在线免费观看 | 亚洲精品国偷自产在线91正片 | 在线观看视频在线 | 91在线日韩 | 久久99久国产精品黄毛片入口 | 色综合天天综合网国产成人网 | 中文字幕 国产专区 | 午夜精品久久久久久久99婷婷 | 天天干,天天射,天天操,天天摸 | 高清免费在线视频 | 亚洲h在线播放在线观看h | 国产精品一区二区三区久久久 | 在线综合 亚洲 欧美在线视频 | 精品国产电影 | 久久精品视频免费观看 | 国产成人精品一区二区三区网站观看 | av动态图片 | 27xxoo无遮挡动态视频 | 国产专区视频在线 | 狠狠色丁香婷婷综合基地 | 国产专区视频在线 | 亚洲狠狠婷婷综合久久久 | 久久国产亚洲视频 | 91在线影视 | 天天噜天天色 | av不卡网站| 日批在线观看 | 日韩免费视频观看 | 久久黄视频 | 欧美天天综合网 | 在线免费观看欧美日韩 | 超碰在线资源 | 中文字幕久久精品一区 | 免费色视频网站 | 成人高清在线 | 中文十次啦 | 999久久国产 | 一区二区三区日韩在线观看 | 97av影院| 国产精品一区久久久久 | 在线免费观看av网站 | 99热国产在线观看 | 午夜久久影院 | 国产精品夜夜夜一区二区三区尤 | 99久久99久久精品国产片 | 九九九九九九精品 | 亚洲黑丝少妇 | 九九免费在线看完整版 | 国产私拍在线 | 久草网在线 | 久久99热精品这里久久精品 | 91av在线国产 | 看污网站| 久久久精品免费观看 | 欧美久久久久久久 | 99久久激情| 999国内精品永久免费视频 | 91av久久| 青青河边草观看完整版高清 | 国产中文在线观看 | 欧美午夜精品久久久久久浪潮 | 波多野结衣在线视频免费观看 | 欧美激情精品久久久久久免费 | 黄色特级毛片 | 国产不卡高清 | 日韩欧美精品在线观看视频 | 日韩亚洲国产中文字幕 | 在线免费色视频 | 欧美一级性生活视频 | 中文字幕丝袜一区二区 | 免费看片日韩 | 久草视频精品 | 亚洲资源视频 | 狂野欧美激情性xxxx欧美 | 最近中文字幕免费大全 | 日韩1级片 | 色狠狠婷婷| 婷婷日| 人人澡超碰碰 | 丁香九月激情 | 91探花系列在线播放 | 黄色大片日本免费大片 | 久久在现| 精品久久久久久久久久久久久久久久久久 | 国产精品18毛片一区二区 | 69视频国产 | 日韩免费在线观看网站 | 国内外成人免费在线视频 | 成+人+色综合 | 日韩二区在线观看 | 婷婷伊人综合 | 二区中文字幕 | 久久亚洲区 | 一区二区免费不卡在线 | 青青河边草免费直播 | 婷婷色吧| 国产精品涩涩屋www在线观看 | 超碰97网站| 日韩高清激情 | 中文视频在线看 | www国产亚洲 | 成人av视屏 | 在线观看色网 | 欧美日韩在线视频观看 | 黄在线免费看 | 亚洲国产精品久久久久久 | 日韩av高清在线观看 | 激情综合网在线观看 | 国产精品一区免费在线观看 | www视频在线播放 | 日韩欧美一区二区在线 | 免费电影播放 | 99免费在线 | 三级黄色免费片 | 日韩黄色免费在线观看 | 精品视频中文字幕 | 一本一本久久aa综合精品 | 欧美日本高清视频 | 激情综合亚洲精品 | 国产一二三区av | 97色se| av一级黄| 欧美精品国产精品 | 久久在线视频精品 | 亚洲黄色在线播放 | 精品国产亚洲在线 | 99久久99视频只有精品 | 亚洲精品国内 | 久久久精品网站 | 亚洲视频综合在线 | 天天色天天操天天爽 | 激情狠狠干 | 精品国内自产拍在线观看视频 | 韩国av一区二区 | 99精品国产aⅴ | 国产成人免费精品 | 日日干天天 | 久久成人高清视频 | 波多野结衣一区 | 国产美女网站视频 | 久久久久久久久影院 | 欧美一级小视频 | 国产精品久久久av久久久 | 探花视频在线观看免费 | 色综合天天视频在线观看 | 精品久久久久久久久久久久 | 国产一区二区在线精品 | 日韩欧美高清视频在线观看 | 亚洲综合情 | 日韩精品中文字幕在线播放 | 伊人色综合久久天天 | 一区二区三区四区在线 | 日韩精品视频第一页 | 欧美人人爱 | 激情视频国产 | 亚洲成人精品 | 亚洲视频在线免费观看 | 成人va在线观看 | 99久久久国产免费 | 日韩成人中文字幕 | 久久视频免费在线观看 | 成人黄色在线看 | 丁香久久久 | 91精品国产91久久久久 | 美女网站视频免费黄 | 福利一区二区 | 在线视频区 | 在线高清av | 毛片网站在线观看 | 久久国产精品99久久久久久丝袜 | 综合中文字幕 | 欧美性久久久 | 成人免费xxx在线观看 | 天天射天天干 | 欧美一级片在线观看视频 | 狠狠狠狠狠狠狠干 | 在线观看亚洲专区 | 黄色av电影网 | 在线影视 一区 二区 三区 | 深爱婷婷| 96国产在线 | 四虎在线永久免费观看 | 五月天丁香视频 | 99久久精品免费看国产麻豆 | 国产亚洲视频在线免费观看 | av激情五月 | 久久视影| 日韩在线视频二区 | 免费成人在线观看视频 | 国产一级性生活 | 久久精品精品电影网 | 日韩免费在线视频 | 国产黄色在线看 | 国产69久久精品成人看 | 99视频免费播放 | 麻豆一区二区 | 在线黄色观看 | 国产精品久久影院 | 91成人在线观看高潮 | 日韩在线一区二区免费 | av中文资源在线 | 天天插狠狠干 | 波多野结衣在线观看一区 | 91在线免费视频观看 | 国产精品女主播一区二区三区 | a在线一区 | 精品久久1 | 色 中文字幕 | 亚洲精品毛片一级91精品 | 综合网伊人 | 午夜电影av | av网站免费看 | 中文字幕在线免费观看视频 | 99视频免费看 | 久久一区二区三区四区 | 日韩资源在线观看 | 激情丁香久久 | 亚洲国产精品一区二区久久,亚洲午夜 | 中文永久字幕 | 亚洲精品视频在线观看免费视频 | 日本中文字幕高清 | 天天射天天操天天色 | 日日色综合 | 国产精品一区二区免费看 | 精品国产电影一区二区 | 久久久久99精品成人片三人毛片 | 天天舔夜夜操 | 欧美在线观看视频一区二区三区 | 国产亚洲情侣一区二区无 | 狠狠狠色丁香综合久久天下网 | 成人精品一区二区三区中文字幕 | 丝袜美腿在线播放 | 91久久久国产精品 | 成人午夜网 | 免费的黄色av | 97综合网| 亚洲色图 校园春色 | 亚洲人成人天堂h久久 | 国产精品1024 | 中国黄色一级大片 | 日韩精品一区二区三区丰满 | 久久国产高清视频 | 久久99精品久久久久久三级 | 久久久久久国产精品 | 在线成人性视频 | 五月天国产 | 久久这里只有精品首页 | 麻豆91网站 | 国产一区二区在线观看视频 | 久久综合九色综合久久久精品综合 | 亚洲精品黄色在线观看 | 成人av影视在线 | 亚洲每日更新 | 亚洲欧洲美洲av | 天天干,狠狠干 | 蜜桃久久久 | 日韩电影中文字幕在线 | av在线免费网站 | 国产精品久久一区二区三区不卡 | 91爱爱网址| 亚洲精品乱码白浆高清久久久久久 | 天天操婷婷 | 亚洲精品国产欧美在线观看 | 久久久国产精品麻豆 | 亚洲欧洲一级 | 欧美夫妻性生活电影 | 久久精品国产一区二区三 | 国内一区二区视频 | 日本精品免费看 | 91高清视频在线 | 在线观看国产日韩欧美 | 六月激情久久 | 91在线精品一区二区 | 天天舔天天搞 | 国产又黄又猛又粗 | 青青草久草在线 | 日韩av网址在线 | 午夜视频免费 | 免费精品国产va自在自线 | 久久久精品国产一区二区电影四季 | 免费高清在线观看成人 | 亚洲一级电影在线观看 | 99精品在线 | 丰满少妇在线 | 国内成人精品视频 | 国产色拍拍拍拍在线精品 | 黄色av电影在线观看 | 不卡国产视频 | 成人av电影在线观看 | 亚洲最大成人网4388xx | 色婷婷在线视频 | 91理论电影 | 亚洲国产婷婷 | 成人在线播放视频 | 国产精品久久久久aaaa九色 | 国产一区二区三区在线 | 国产999| 91精品久| 麻豆传媒视频在线播放 | 亚洲欧洲中文日韩久久av乱码 | 日韩精品极品视频 | www国产亚洲精品久久麻豆 | 婷婷色中文网 | 国产免费观看视频 | 国产黄色片一级三级 | 欧美成人性网 | 激情久久一区二区三区 | 有码中文字幕在线观看 | 在线观看视频99 | 国产精品久久嫩一区二区免费 | 国产精品一区二区美女视频免费看 | 久久久久亚洲天堂 | 中文字幕 国产精品 | 天天干,天天操,天天射 | 日韩精品最新在线观看 | 丁香色婷婷 | 欧美a性 |