當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]使用Xmodem有一段時間了,使用起來移植性能不夠,通過這次徹底拋離了底層通信部分,可以用在任何通信接口上面了,跟底層的通信已經(jīng)無關(guān)了,使用了大量的回調(diào),回調(diào)主要完成通信的收發(fā),以及數(shù)據(jù)存儲等功能,我

使用Xmodem有一段時間了,使用起來移植性能不夠,通過這次徹底拋離了底層通信部分,可以用在任何通信接口上面了,跟底層的通信已經(jīng)無關(guān)了,使用了大量的回調(diào),回調(diào)主要完成通信的收發(fā),以及數(shù)據(jù)存儲等功能,我目前主要使用在STM32 IAP升級(寫入到內(nèi)部flash),app升級(寫入到外部flash W25Q128),字庫以及各種編碼下載(寫入到外部flash W25Q128)。

//數(shù)據(jù)包格式比較簡單


//	Xmodem?包格式
//	Byte1?				Byte2?			Byte3?				Byte4~131?		Byte132~133
//	Start?Of?Hearder?	Packet?Number?	~(Packet?Number)?	Packet?Data?	16-Bit?CRC


//1K-Xmodem?包格式
//	Byte1?				Byte2?			Byte3?				Byte4~1027?	Byte1028~1029
//	Start?Of?Hearder?	Packet?Number?	~(Packet?Number)?	Packet?Data?	16-Bit?CRC


//c文件



/*************************************************************************************************************
?*?文件名:????????????Xmodem.c
?*?功能:????????????Xmodem協(xié)議實現(xiàn)
?*?作者:????????????cp1300@139.com
?*?創(chuàng)建時間:????????2014-08-19
?*?最后修改時間:????2017-09-05
?*?詳細(xì):????????????使用串口實現(xiàn)Xmodem協(xié)議應(yīng)用層
????????????????????2017-03-23:修改采用回調(diào)以及句柄方式,可移植性更強
????????????????????2017-04-04:增加發(fā)送延時
????????????????????2017-09-05:發(fā)送NAK與結(jié)束增加延時,防止發(fā)送過快,并且修改如果通信超時則發(fā)送NAK,大大提高通信可靠性
????????????????????2017-09-06:修復(fù)第一包數(shù)據(jù)丟失問題,增加數(shù)據(jù)包id重復(fù)檢查,大大提高數(shù)據(jù)的可靠性,防止重復(fù)的數(shù)據(jù)包
*************************************************************************************************************/
#include?"system.h"
#include?"usart.h"
#include?"main.h"
#include?"Xmodem.h"
#if?SYS_WDG_EN_
#include?"wdg.h"????
#endif????

//調(diào)試開關(guān)
#define?XMODEM_DBUG????0
#if?XMODEM_DBUG
????#include?"system.h"
????#define?xmodem_debug(format,...)????uart_printf(format,##__VA_ARGS__)
#else
????#define?xmodem_debug(format,...)????/
/
#endif????//XMODEM_DBUG



//????Xmodem?包格式
//????Byte1?????????????????Byte2?????????????Byte3?????????????????Byte4~131?????????Byte132~133
//????Start?Of?Hearder?????Packet?Number?????~(Packet?Number)?????Packet?Data?????16-Bit?CRC


//1K-Xmodem?包格式
//????Byte1?????????????????Byte2?????????????Byte3?????????????????Byte4~1027?????Byte1028~1029
//????Start?Of?Hearder?????Packet?Number?????~(Packet?Number)?????Packet?Data?????16-Bit?CRC



/*************************************************************************************************************************
*?函數(shù)????????????:????bool?XMODE_Init(XMODE_HANDLE?*pHandle,
????????????????????????bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen),?
????????????????????????int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay),?
????????????????????????void?(*pClearRxData)(void),
????????????????????????bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize),
????????????????????????bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize))
*?功能????????????:????初始化XMODE
*?參數(shù)????????????:????pHandle:句柄;
????????????????????pSendData:發(fā)送回調(diào)函數(shù)(pDataBuff:發(fā)送數(shù)據(jù)緩沖區(qū),DataLen:發(fā)送數(shù)據(jù)長度)
????????????????????pReadData:接收數(shù)據(jù)回調(diào)函數(shù),會等待直到數(shù)據(jù)被寫入到接收緩沖區(qū)(pDataBuff:接收數(shù)據(jù)緩沖區(qū),ByteTimeOut:等待的字節(jié)超時時間,單位ms,TimeOut:數(shù)據(jù)包超時時間,單位ms),pReceiveDelay:返回接收延時,單位ms
????????????????????pClearRxData:清除接收數(shù)據(jù)緩沖區(qū)回調(diào)函數(shù)
????????????????????pReceivePacket:收到一包數(shù)據(jù)后的回調(diào)函數(shù),(返回false會退出通信)用于應(yīng)用層對數(shù)據(jù)進(jìn)行存儲(pPackData:接收到的數(shù)據(jù)包,PackSize:包大??;RecDataSize:已經(jīng)接收的數(shù)據(jù)包大小,不含當(dāng)前包的數(shù)據(jù))
????????????????????pTransEnd:傳輸結(jié)束時回調(diào)函數(shù),(返回false會退出通信)用于傳輸結(jié)束的處理(isTransOK:TRUE,傳輸正常完成,F(xiàn)ALSE:傳輸錯誤結(jié)束;RecDataSize:總共收到的數(shù)據(jù)大小)
*?返回????????????:????TRUE:初始化成;FALSE:初始化錯誤
*?依賴????????????:????通信接口
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????XMODE通信協(xié)議通信接口初始化,默認(rèn)超時時間為等待啟動30秒,數(shù)據(jù)包超時2秒
;????????????????????????????????//清除接收數(shù)據(jù)緩沖區(qū)
*************************************************************************************************************************/
bool?XMODE_Init(XMODE_HANDLE?*pHandle,bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen),?int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay),?
????void?(*pClearRxData)(void),bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize),bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize))
{
????if(pHandle?==?NULL)?return?FALSE;????????????????????//錯誤,無效的指針
????pHandle->RecDataSize?=?0;????????????????????????????//接收到的數(shù)據(jù)大小
????pHandle->RecPackCnt?=?0;????????????????????????????//接收到的數(shù)據(jù)包計數(shù)
????pHandle->pSendData?=?pSendData;????????????????????????//發(fā)送回調(diào)指針,????發(fā)送數(shù)據(jù)回調(diào)函數(shù)
????pHandle->pReadData?=?pReadData;????????????????????????//讀取數(shù)據(jù)回調(diào)指針,>0返回接收到的數(shù)據(jù)長度,否則失敗
????pHandle->pClearRxData?=?pClearRxData;????????????????//清除接收數(shù)據(jù)緩沖區(qū)
????pHandle->pReceivePacket?=?pReceivePacket;????????????//收到數(shù)據(jù)包回調(diào)指針
????pHandle->pTransEnd?=?pTransEnd;????????????????????????//傳輸結(jié)束時回調(diào)(可能是出錯結(jié)束)
????pHandle->WaitStartTimeOutSer?=?30;????????????????????//等待啟動傳輸超時時間
????pHandle->PackTimeOutSer?=?2;????????????????????????//數(shù)據(jù)包超時時間
????pHandle->pXMODEM_128Pack?=?NULL;????????????????????//128B數(shù)據(jù)包指針
????pHandle->pXMODEM_1KPack?=?NULL;????????????????????????//1KB數(shù)據(jù)包指針
????pHandle->TransRetry?=?10;????????????????????????????//失敗重試次數(shù),默認(rèn)10次
????pHandle->TxByteTimeUs?=?0;????????????????????????????//發(fā)送延時默認(rèn)為0
????
????return?TRUE;
}


/*************************************************************************************************************************
*?函數(shù)????????????:????bool?XMODE_SetTimeOut(XMODE_HANDLE?*pHandle,?u16?WaitStartTimeOutSer,?u16?PackTimeOutSer,?u8?TransRetry,u8?TxByteTimeUs)
*?功能????????????:????設(shè)置XMODE超時時間
*?參數(shù)????????????:????pHandle:句柄;WaitStartTimeOutSer:等待啟動超時時間,單位秒鐘;PackTimeOutSer:數(shù)據(jù)包超時時間,單位秒鐘;TransRetry:出錯重試次數(shù),1-255次;TxByteTimeUs:發(fā)送字節(jié)延時
*?返回????????????:????TRUE:初始化成;FALSE:初始化錯誤
*?依賴????????????:????通信接口
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????設(shè)置超時時間
*************************************************************************************************************************/
bool?XMODE_SetTimeOut(XMODE_HANDLE?*pHandle,?u16?WaitStartTimeOutSer,?u16?PackTimeOutSer,?u8?TransRetry,u8?TxByteTimeUs)
{
????if(pHandle?==?NULL)?return?FALSE;????????????????????????????????????//錯誤,無效的指針
????pHandle->WaitStartTimeOutSer?=?WaitStartTimeOutSer;????????????????????//等待啟動傳輸超時時間
????if(pHandle->WaitStartTimeOutSer?<?1)?pHandle->WaitStartTimeOutSer?=?1;
????pHandle->PackTimeOutSer?=?PackTimeOutSer;????????????????????????????//數(shù)據(jù)包超時時間
????if(pHandle->PackTimeOutSer?<?1)?pHandle->PackTimeOutSer?=?1;
????pHandle->TransRetry?=?TransRetry;????????????????????????????????????//出錯重試次數(shù)
????if(pHandle->TransRetry?<?1)?pHandle->TransRetry?=?1;
????pHandle->TxByteTimeUs?=?TxByteTimeUs;????????????????????????????????//發(fā)送字節(jié)延時,用于RS485接口,發(fā)送后需要進(jìn)行延時
????
????return?TRUE;
}

/*************************************************************************************************************************
*?函數(shù)????????????:????int?XMODEM_Start(XMODE_HANDLE?*pHandle,?u8?**pRxBuff)
*?功能????????????:????發(fā)送啟動請求
*?參數(shù)????????????:????pHandle:句柄;pRxBuff:接收緩沖區(qū)(存放第一包數(shù)據(jù))
*?返回????????????:????WaitStartTimeOutSer*10;????????????//轉(zhuǎn)換為100m單位
????int?len;
????
????if(pHandle?==?NULL)?return?FALSE;
????pHandle->DataBuff[0]?=?X_CRC_MODE;????????????????????????//采用CRC模式的校驗請求頭
????while(TimeOut?--)
????{
????????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
????????pHandle->pClearRxData();????????????????????????????//清除接收
????????len?=?pHandle->pReadData(pRxBuff,10,100,NULL);????????//接收數(shù)據(jù)
????????if(len?>?0)????????????????????//等待接收
????????{
????????????pHandle->RecDataSize?=?0;????????????????????????//接收到的數(shù)據(jù)大小清零
????????????pHandle->RecPackCnt?=?0;????????????????????????//接收到的數(shù)據(jù)包計數(shù)清零
????????????return?len;
????????}????????????????
????????????
#if?SYS_WDG_EN_
????????IWDG_Feed();????????????????????????????????????????//喂狗
#endif????????????
????}
????return?-1;
}





//發(fā)送ACK
__inline?void?XMODEM_SendACK(XMODE_HANDLE?*pHandle)
{
????pHandle->DataBuff[0]?=?(u8)X_ACK;
????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
}


//發(fā)送NAK
__inline?void?XMODEM_SendNAK(XMODE_HANDLE?*pHandle)
{
????XMODEM_DelayMS(20);
????pHandle->DataBuff[0]?=?(u8)X_NAK;
????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
}


//取消傳輸
__inline?void?XMODEM_CancelTran(XMODE_HANDLE?*pHandle)
{
????XMODEM_DelayMS(20);
????pHandle->DataBuff[0]?=?(u8)X_CAN;
????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
}



//判斷是否結(jié)束
__inline?bool?XMODEM_isTranEnd(u8?Data,?XMODE_HANDLE?*pHandle)
{
????if(Data?==?X_EOT)?return?TRUE;
????else?return?FALSE;
}




/*************************************************************************************************************************
*?函數(shù)????????????:????u16?XMODEM_CRC16(u8?*pData,?u16?DataLen)
*?功能????????????:????crc16校驗
*?參數(shù)????????????:????pData:數(shù)據(jù)緩沖區(qū);DataLen:數(shù)據(jù)長度
*?返回????????????:????crc16結(jié)果
*?依賴????????????:????通信接口
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????用于通信數(shù)據(jù)校驗,僅用于XMODEM,不可與modbus-rtu協(xié)議用的crc16混用(兩者計算結(jié)果會不一致)
????????????????????多項式碼0x1021
*************************************************************************************************************************/
u16?XMODEM_CRC16(u8?*pData,?u16?DataLen)
{
????u16?crc?=?0;
????char?i;
????u16?j;

????for(j?=?0;j?<?DataLen;j?++)
????{
????????crc?=?crc?^?(int)?*pData++?<<?8;
????????i?=?8;
????????do
????????{
????????????if?(crc?&?0x8000)
????????????????crc?=?crc?<<?1?^?0x1021;
????????????else
????????????????crc?=?crc?<<?1;
????????}?while?(--i);
????}

????return?(crc);
}



/*************************************************************************************************************************
*?函數(shù)????????????:????u32?XMODEM_DownloadFile(XMODE_HANDLE?*pHandle,?u32?MaxDataSize)
*?功能????????????:????使用XMODEM下載文件
*?參數(shù)????????????:????pHandle:句柄;MaxDataSize:限制最大下載數(shù)據(jù)量
*?返回????????????:????0:錯誤;其它:接收的數(shù)據(jù)長度
*?依賴????????????:????底層
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????使用CRC校驗?zāi)J?,支?28,1K數(shù)據(jù)包
*************************************************************************************************************************/
u32?XMODEM_DownloadFile(XMODE_HANDLE?*pHandle,?u32?MaxDataSize)
{
????u16?crc16;
????u16?temp;
????u16?retry?=?0;
????int?len;
????bool?isStart?=?FALSE;
????u8?*pRxBuff;
????u8?LastPackCnt?=?0;????????????????????????//用于記錄上一次包序號,每次包序號不能重復(fù)
????
????len?=?XMODEM_Start(pHandle,?&pRxBuff);????//等待開始傳輸
????if(len?pClearRxData();????????????????????????????????????????????????????//清除接收緩沖區(qū)
????????????len?=?pHandle->pReadData(&pRxBuff,?2,pHandle->PackTimeOutSer*1000,NULL);????//接收數(shù)據(jù)
????????}
????????isStart?=?FALSE;????????????????//第一次開始傳輸狀態(tài)無效
????????if(len?pXMODEM_128Pack?=?(XMODEM_128B_PACK?*)pRxBuff;????????????????????//128B數(shù)據(jù)包指針
????????????pHandle->pXMODEM_1KPack?=?(XMODEM_1KB_PACK?*)pRxBuff;????????????????????//1KB數(shù)據(jù)包指針
????????????switch(pHandle->pXMODEM_128Pack->X_Start)
????????????{
????????????????case?X_SOH:????//128
????????????????{
????????????????????if(len?<?128)?
????????????????????{
????????????????????????XMODEM_SendNAK(pHandle);?//發(fā)送NAK?
????????????????????????retry++;
????????????????????}
????????????????????else
????????????????????{
????????????????????????crc16?=?XMODEM_CRC16(pHandle->pXMODEM_128Pack->X_PackData,?128);
????????????????????????temp?=?pHandle->pXMODEM_128Pack->X_CRC16H;
????????????????????????temp?<pXMODEM_128Pack->X_CRC16L;
????????????????????????if(crc16?!=?temp)????????????//CRC校驗錯誤,重傳
????????????????????????{
????????????????????????????XMODEM_SendNAK(pHandle);?//發(fā)送NAK?
????????????????????????????retry++;
????????????????????????}
????????????????????????else
????????????????????????{
????????????????????????????if(LastPackCnt!=pHandle->pXMODEM_128Pack->X_PackNum)?????//包序號不一樣
????????????????????????????{
????????????????????????????????LastPackCnt?=?pHandle->pXMODEM_128Pack->X_PackNum;????//記錄上一次的包序號
????????????????????????????????if(pHandle->pReceivePacket(pHandle->pXMODEM_128Pack->X_PackData,?128,?pHandle->RecDataSize)==FALSE)????//收到數(shù)據(jù)包,調(diào)用回調(diào)
????????????????????????????????{
????????????????????????????????????//用戶返回退出下載
????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調(diào)是否有效
????????????????????????????????????{
????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調(diào)用回調(diào),有錯誤
????????????????????????????????????}
????????????????????????????????????
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????xmodem_debug("用戶取消下載!rn");
????????????????????????????????????return?0;
????????????????????????????????}
????????????????????????????????
????????????????????????????????pHandle->RecDataSize?+=?128;????????????????????//接收到的數(shù)據(jù)大小增加
????????????????????????????????pHandle->RecPackCnt?++;????????????????????????????//接收到的數(shù)據(jù)包計數(shù)增加

????????????????????????????????if(pHandle->RecDataSize?>?MaxDataSize)
????????????????????????????????{
????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調(diào)是否有效
????????????????????????????????????{
????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調(diào)用回調(diào),有錯誤
????????????????????????????????????}
????????????????????????????????????
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????xmodem_debug("文件下載失敗,大小超出范圍(%dB)!rn",?MaxDataSize);
????????????????????????????????????return?0;
????????????????????????????????}
????????????????????????????}
????????????????????????????else????//故障,重復(fù)的數(shù)據(jù)包
????????????????????????????{
????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????}

????????????????????????????XMODEM_SendACK(pHandle);????????????????????????//發(fā)送ACK響應(yīng)
????????????????????????????retry?=?0;
????????????????????????}
????????????????????}????
????????????????}break;
????????????????case?X_STX:????//1k
????????????????{
????????????????????if(len?<?1024)?
????????????????????{
????????????????????????XMODEM_SendNAK(pHandle);?//發(fā)送NAK?
????????????????????????retry++;
????????????????????}
????????????????????else
????????????????????{
????????????????????????crc16?=?XMODEM_CRC16(pHandle->pXMODEM_1KPack->X_PackData,?1024);
????????????????????????temp?=?pHandle->pXMODEM_1KPack->X_CRC16H;
????????????????????????temp?<pXMODEM_1KPack->X_CRC16L;
????????????????????????if(crc16?!=?temp)????????????????????????????????????//CRC校驗錯誤,重傳
????????????????????????{
????????????????????????????XMODEM_SendNAK(pHandle);????????????????????????//發(fā)送NAK?
????????????????????????????retry++;
????????????????????????}
????????????????????????else
????????????????????????{
????????????????????????????if(LastPackCnt!=pHandle->pXMODEM_128Pack->X_PackNum)?????//包序號不一樣
????????????????????????????{
????????????????????????????????LastPackCnt?=?pHandle->pXMODEM_128Pack->X_PackNum;????//記錄上一次的包序號
????????????????????????????????
????????????????????????????????if(pHandle->pReceivePacket?!=?NULL)????//判斷回調(diào)是否有效
????????????????????????????????{
????????????????????????????????????if(pHandle->pReceivePacket(pHandle->pXMODEM_1KPack->X_PackData,?1024,?pHandle->RecDataSize)==FALSE)????//收到數(shù)據(jù)包,調(diào)用回調(diào)
????????????????????????????????????{
????????????????????????????????????????//用戶返回退出下載
????????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調(diào)是否有效
????????????????????????????????????????{
????????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調(diào)用回調(diào),有錯誤
????????????????????????????????????????}
????????????????????????????????????????
????????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????????xmodem_debug("用戶取消下載!rn");
????????????????????????????????????????return?0;
????????????????????????????????????}
????????????????????????????????}
????????????????????????????????
????????????????????????????????pHandle->RecDataSize?+=?1024;????????????????????//接收到的數(shù)據(jù)大小增加
????????????????????????????????pHandle->RecPackCnt?++;????????????????????????????//接收到的數(shù)據(jù)包計數(shù)增加
????????????????????????????????
????????????????????????????????if(pHandle->RecDataSize?>?MaxDataSize)
????????????????????????????????{
????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調(diào)是否有效
????????????????????????????????????{
????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調(diào)用回調(diào),有錯誤
????????????????????????????????????}
????????????????????????????
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????xmodem_debug("文件下載失敗,代碼超出范圍(%dB)!rn",?MaxDataSize);
????????????????????????????????????return?0;
????????????????????????????????}
????????????????????????????}
????????????????????????????else????//故障,重復(fù)的數(shù)據(jù)包
????????????????????????????{
????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????}
????????????????????????????XMODEM_SendACK(pHandle);????????????????????????//發(fā)送ACK響應(yīng)
????????????????????????????retry?=?0;
????????????????????????}
????????????????????}????
????????????????}break;
????????????????case?X_EOT:????//傳輸結(jié)束,最后一包
????????????????{
????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調(diào)是否有效
????????????????????{
????????????????????????if(pHandle->pTransEnd(TRUE,?pHandle->RecDataSize)?==?FALSE)????//傳輸完成,調(diào)用回調(diào),有錯誤則退出
????????????????????????{
????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????XMODEM_DelayMS(10);
????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結(jié)束傳輸
????????????????????????????XMODEM_DelayMS(500);
????????????????????????????xmodem_debug("用戶取消下載!rn");
????????????????????????????return?0;
????????????????????????}
????????????????????}
????????????????????XMODEM_SendACK(pHandle);
????????????????????retry?=?0;
????????????????????XMODEM_DelayMS(10);
????????????????????XMODEM_SendACK(pHandle);
????????????????????XMODEM_DelayMS(500);
????????????????????xmodem_debug("文件下載成功!rn");
????????????????????return?pHandle->RecDataSize;
????????????????}
????????????????default:XMODEM_SendNAK(pHandle);?retry++;break;
????????????}
????????}
????????
????????if(retry?>?pHandle->TransRetry)?????//重傳過多
????????{
????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調(diào)是否有效
????????????{
????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調(diào)用回調(diào),有錯誤
????????????}
????????????????????????
????????????XMODEM_CancelTran(pHandle);????????????????????????????//取消傳輸
????????????XMODEM_DelayMS(10);
????????????XMODEM_CancelTran(pHandle);????????????????????????????//取消傳輸
????????????XMODEM_DelayMS(500);
????????????xmodem_debug("下載失敗,重試次數(shù)過多!rn");
????????????return?0;
????????}
#if?SYS_WDG_EN_
????????IWDG_Feed();????????????????????????????????????????//喂狗
#endif
????}
}



//.h文件


/*************************************************************************************************************
?*?文件名:			Xmodem.h
?*?功能:			Xmodem協(xié)議實現(xiàn)
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2014-08-19
?*?最后修改時間:	2014-08-19
?*?詳細(xì):			使用串口實現(xiàn)Xmodem協(xié)議應(yīng)用層
*************************************************************************************************************/
#ifndef?_X_MODEM_H_
#define?_X_MODEM_H_
#include?"system.h"
#include?"USART.h"


#ifdef?_UCOS_II_	//支持ucos操作系統(tǒng),使用系統(tǒng)延時
#define?XMODEM_DelayMS(x)				OSTimeDlyHMSM(0,0,0,x)						//延時ms,最大延時999ms
#else
#define?XMODEM_DelayMS(x)				Delay_MS(x)						
#endif?//_UCOS_II_


//XMODEM?相關(guān)定義說明
#define?X_SOH		0x01		//?Xmodem數(shù)據(jù)頭
#define?X_STX		0x02		//?1K-Xmodem數(shù)據(jù)頭
#define?X_EOT		0x04		//?發(fā)送結(jié)束
#define?X_ACK		0x06		//?認(rèn)可響應(yīng)
#define?X_NAK		0x15		//?不認(rèn)可響應(yīng)
#define?X_CAN		0x18		//?撤銷傳送
#define?X_EOF		0x1A		//?填充數(shù)據(jù)包

//128B數(shù)據(jù)包格式
typedef?struct
{
	u8	X_Start;
	u8	X_PackNum;
	u8	X_bPackNum;
	u8	X_PackData[128];
	u8	X_CRC16H;
	u8	X_CRC16L;
}XMODEM_128B_PACK;


//1024B數(shù)據(jù)包格式
typedef?struct
{
	u8	X_Start;
	u8	X_PackNum;
	u8	X_bPackNum;
	u8	X_PackData[1024];
	u8	X_CRC16H;
	u8	X_CRC16L;
}XMODEM_1KB_PACK;



typedef?struct
{
	u32?RecDataSize;										//接收到的數(shù)據(jù)大小
	u32?RecPackCnt;											//接收到的數(shù)據(jù)包計數(shù)
	bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen);			//發(fā)送回調(diào)指針,	發(fā)送數(shù)據(jù)回調(diào)函數(shù)
	int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay);	//讀取數(shù)據(jù)回調(diào)指針,>0返回接收到的數(shù)據(jù)長度,否則失敗
	bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize);	//收到數(shù)據(jù)包回調(diào)指針,返回false會退出傳輸
	bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize);		//傳輸結(jié)束回調(diào)指針,返回false會退出傳輸
	void?(*pClearRxData)(void);								//清除接收數(shù)據(jù)緩沖區(qū)
	XMODEM_128B_PACK?*pXMODEM_128Pack;						//128bit數(shù)據(jù)包格式
	XMODEM_1KB_PACK?*pXMODEM_1KPack;						//1K數(shù)據(jù)包格式
	u16?WaitStartTimeOutSer;								//等待啟動傳輸超時時間
	u16?PackTimeOutSer;										//數(shù)據(jù)包超時時間
	u8?TxByteTimeUs;										//發(fā)送字節(jié)延時,微秒,用于RS485通信延時
	u8?DataBuff[2];											//分配的臨時緩沖區(qū)
	u8?TransRetry;											//失敗重試次數(shù),默認(rèn)10次
}XMODE_HANDLE;




//啟動傳輸校驗?zāi)J?typedef?enum
{
	X_CRC_MODE?=?'C',		//傳輸使用CRC16校驗?zāi)J?	X_ACC_MODE?=?X_NAK,		//傳輸使用累加校驗?zāi)J?}XMODEM_START_MODE;


//數(shù)據(jù)包大小
typedef?enum
{
	X_PACK128B?=?X_SOH,		//128B數(shù)據(jù)包
	X_PACK1kB?=?X_STX,		//1KB數(shù)據(jù)包
}XMODEM_PACK_MODE;

//XMODEM?通信初始化
bool?XMODE_Init(XMODE_HANDLE?*pHandle,?bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen),?int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay),?
	void?(*pClearRxData)(void),bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize),bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize));
//XMODEM?超時設(shè)置
bool?XMODE_SetTimeOut(XMODE_HANDLE?*pHandle,?u16?WaitStartTimeOutSer,?u16?PackTimeOutSer,?u8?TransRetry,u8?TxByteTimeUs);
//XMODEM?下載數(shù)據(jù)
u32?XMODEM_DownloadFile(XMODE_HANDLE?*pHandle,?u32?MaxDataSize);


#endif?/*_X_MODEM_H_*/


下面是2個下載的例子,我主要是示意通信與存儲接口格式,實際使用需要按照自己的平臺進(jìn)行移植


//例子1:下載程序到STM32內(nèi)部flash,主要提供數(shù)據(jù)收發(fā)接口,以及存儲接口示意,這些接口需要根據(jù)自己的平臺做移植
/*************************************************************************************************************
?*?文件名:			UpgradeBIOS.c
?*?功能:			升級BIOS相關(guān)
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2017-05-16
?*?最后修改時間:	2017-05-16
?*?詳細(xì):			使用xmodem直接刷STM32flash,如果失敗了請不要重啟,否則會無法進(jìn)入系統(tǒng)
*************************************************************************************************************/
#include?"system.h"
#include?"usart.h"
#include?"main.h"
#include?"xmodem.h"
#include?"UpgradeBIOS.h"
#include?"STM32Flash.h"
#include?"w25x16.h"
#include?"STM32_CRC.h"
#include?"rtu.h"
#include?"board.h"
#if?SYS_WDG_EN_
#include?"wdg.h"
#endif
#include#define?UP_PROGRAM_STM32_BIOS_ADDR		STM32_FLASH_BASE	//BIOS程序內(nèi)部flash基址


static?u32?UpgradeBiosDataSaveCnt?=?0;		//升級應(yīng)用程序已經(jīng)存儲的數(shù)據(jù)大小

//升級文件接口XMODE句柄
XMODE_HANDLE?UpgradeBIOSHandle;


//發(fā)送數(shù)據(jù)接口
bool?UpgradeBiosSendData(u8?DataBuff[],?u16?DataLen)
{
	UARTx_SendData(UART_PRINTF_CH,?DataBuff,?DataLen);
	
	return?TRUE;
}


//接收數(shù)據(jù)接口
int?UpgradeBiosReadData(u8?**pDataBuff,u8?ByteTimeOutMs,?u16?TimeOutMs,?u16?*pReceiveDelayMs)
{
	u32?cnt?=?0;
	u16?TempTime;
	
	UARTx_ClearRxCnt(UART_PRINTF_CH);	//清除串口接收緩沖區(qū),開始結(jié)束數(shù)據(jù)
	if(ByteTimeOutMs?<?1)?ByteTimeOutMs?=?1;	//字節(jié)超時時間,2個幀之間的間隔最小時間
	TimeOutMs?/=?ByteTimeOutMs;
	TimeOutMs?+=?1;
	TempTime?=?TimeOutMs;
	while(TimeOutMs?--)
	{
		cnt?=?UARTx_GetRxCnt(UART_PRINTF_CH);
		OSTimeDlyHMSM(0,0,0,ByteTimeOutMs);;
		if((cnt?>?0)?&&?(cnt?==?UARTx_GetRxCnt(UART_PRINTF_CH)))
		{
			if(pReceiveDelayMs!=NULL)	//需要返回延時
			{
				*pReceiveDelayMs?=?(TempTime-TimeOutMs)*ByteTimeOutMs;
			}
			*pDataBuff?=?SysCommBuff;						//接收緩沖區(qū)
			
			return?cnt;
		}
#if?SYS_WDG_EN_
		IWDG_Feed();										//喂狗
#endif			
	}
	
	return?0;
}


//清除接收緩沖區(qū)
void?UpgradeBiosClearData(void)
{
	UARTx_ClearRxCnt(UART_PRINTF_CH);	//清除串口緩沖區(qū)
}


//收到數(shù)據(jù)包回調(diào)-用于寫數(shù)據(jù)到內(nèi)部flash
bool?UpgradeBiosReceivePacketExitFlash(u8?*pPackData,u16?PackSize,u32?RecDataSize)
{
	if((PackSize?!=?128)?&&?(PackSize!=1024))?return?FALSE;										//xmodem只支持128字節(jié)或1024字節(jié)的數(shù)據(jù)包
	
	//寫入數(shù)據(jù)到內(nèi)部flash
	STM32FLASH_Write(UP_PROGRAM_STM32_BIOS_ADDR+RecDataSize,?(u16?*)pPackData,?(PackSize+1)/2);
	UpgradeBiosDataSaveCnt?+=?PackSize;

	return?TRUE;
}


//傳輸結(jié)束時回調(diào)(可能是出錯結(jié)束)
bool?UpgradeBiosTransEndtExitFlash(bool?isTransOK,?u32?RecDataSize)
{
	if(isTransOK==FALSE)?return?FALSE;	//失敗返回
	
	if(UpgradeBiosDataSaveCnt?==?RecDataSize)?return?TRUE;
	if(UpgradeBiosDataSaveCnt?>?RecDataSize)?return?FALSE;			//存儲的數(shù)據(jù)不能大于接收的數(shù)據(jù)
	if((RecDataSize-UpgradeBiosDataSaveCnt)?>?0)?return?FALSE;		//不能有未存儲的數(shù)據(jù)

	return?FALSE;	//存儲出錯
}



//使用XMODEM下載數(shù)據(jù)到內(nèi)部flash
//返回程序大小,如果失敗了返回<=0
int?XMODEM_DownloadFileToSTM32Flash(u32?MaxFileSize)
{
	XMODE_Init(&UpgradeBIOSHandle,?			//句柄
		UpgradeBiosSendData,?				//發(fā)送數(shù)據(jù)回調(diào)函數(shù)
		UpgradeBiosReadData,?				//讀取數(shù)據(jù)回調(diào)函數(shù)
		UpgradeBiosClearData,?				//清除接收數(shù)據(jù)緩沖回調(diào)函數(shù)
		UpgradeBiosReceivePacketExitFlash,?	//接收到數(shù)據(jù)包回調(diào)函數(shù)
		UpgradeBiosTransEndtExitFlash		//傳輸結(jié)束回調(diào)函數(shù)
		);
	UpgradeBiosDataSaveCnt?=?0;				//已經(jīng)存儲的數(shù)據(jù)大小清零
	return?XMODEM_DownloadFile(&UpgradeBIOSHandle,?MaxFileSize);
}



//使能系統(tǒng)命令行
#if?SYS_CMD_EN_
#include?"cmd.h"
#include?"string.h"

CMD_TYPE?const?CMD_UP_BIOS	=?{"UP?BIOS",?0XD3476564,?CMD_UpBIOS,?"tt升級BIOS"};				//升級BIOS程序


//進(jìn)入升級BIOS模式
void?CMD_UpBIOS(char?*pStr)
{
	cmd_printf("已經(jīng)進(jìn)入升級BIOS模式,等待連接,超時10S!rn>");
	cmd_printf("請在10S內(nèi)進(jìn)入Xmodem下載模式!rn>");
	RTC_DisableInt();									//關(guān)閉RTC中斷,防止喚醒后臺任務(wù)
	
	OSTaskSuspend(BACK_TASK_Prio);						//掛起后臺任務(wù)線程
	OSTaskSuspend(LED_TASK_Prio);						//掛起LED任務(wù)線程
	OSTaskSuspend(GPRS_TASK_Prio);						//掛起GPRS進(jìn)程
	OSTaskSuspend(COLL_TASK_Prio);						//數(shù)據(jù)采集時間查詢進(jìn)程
	OSTaskSuspend(OTHER_TASK_Prio);						//OTHER
	OSTaskSuspend(MODBUS1_TASK_Prio);					//MODBUS1	
	OSTaskSuspend(MODBUS2_TASK_Prio);					//MODBUS2
	OSTaskSuspend(KEY_TASK_Prio);						//KEY

	OSTimeDlyHMSM(0,0,0,500);							//延時500毫秒
	if(XMODEM_DownloadFileToSTM32Flash(100*1024)?==?0)//寫入BIOS程序
	{
		cmd_printf("升級BIOS失敗,重啟后將無法啟動,建議重新升級!rn");
	}
	else
	{
		cmd_printf("升級BIOS成功!rn");
	}
	CMD_Help(NULL);
	
	OSTaskResume(LED_TASK_Prio);						//恢復(fù)掛起LED任務(wù)線程
	OSTaskResume(GPRS_TASK_Prio);						//恢復(fù)掛起GPRS進(jìn)程
	OSTaskResume(COLL_TASK_Prio);						//恢復(fù)數(shù)據(jù)采集時間查詢進(jìn)程
	OSTaskResume(OTHER_TASK_Prio);						//恢復(fù)OTHER
	OSTaskResume(MODBUS1_TASK_Prio);					//恢復(fù)MODBUS1	
	OSTaskResume(MODBUS2_TASK_Prio);					//恢復(fù)MODBUS2
	OSTaskResume(KEY_TASK_Prio);						//恢復(fù)KEY
	
	RTC_EnableInt();									//恢復(fù)RTC中斷
}



#endif?//SYS_CMD_EN_



//例子2:下載字庫編碼到外部flash,使用的是SPI?接口flash,W25Q128,存儲接口稍有不同,因為我每次將數(shù)據(jù)集齊4K才進(jìn)行存儲,這樣可以提高存儲效率,降低flash損耗,當(dāng)然最后一包可能不足4K,會另外進(jìn)行處理的。

/*************************************************************************************************************
?*?文件名:			DownFont.c
?*?功能:			下載字庫相關(guān)
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2017-03-29
?*?最后修改時間:	2017-03-29
?*?詳細(xì):			使用xmodem或tFileModem下載文件
*************************************************************************************************************/
#include?"system.h"
#include?"usart.h"
#include?"main.h"
#include?"xmodem.h"
#include?"tFileModem.h"
#include?"upgrade.h"
#include?"STM32Flash.h"
#include?"STM32_CRC.h"
#if?SYS_WDG_EN_
#include?"wdg.h"
#endif
#include#include?"DownFont.h"
#include?"RTU.h"
#include?"BOARD.h"

#define?DOWN_FONT_EXIT_SECTOR		FLASH_BIN_SECTOR				//存儲到外部flash的位置


static?u32?DownFontDataSaveCnt?=?0;		//升級應(yīng)用程序已經(jīng)存儲的數(shù)據(jù)大小


//收到數(shù)據(jù)包回調(diào)-用于寫數(shù)據(jù)到外部flash
//需要使用到W25X16的4K臨時緩沖區(qū),在升級與校驗的時候確保沒有其它線程訪問W25X16,最好掛起其它線程
bool?DownFontReceivePacketExitFlash(u8?*pPackData,u16?PackSize,u32?RecDataSize)
{
	if((PackSize?!=?128)?&&?(PackSize!=1024))?return?FALSE;										//xmodem只支持128字節(jié)或1024字節(jié)的數(shù)據(jù)包
	
	memcpy(&SPI_FLASH_BUF[RecDataSize%4096],?pPackData,?PackSize);
	if(((RecDataSize+PackSize)%4096)?==?0)														//4K對齊,一次寫入到外部flash
	{
		if(W25X16_EraseSector((RecDataSize+PackSize)/4096-1?+?DOWN_FONT_EXIT_SECTOR)?==?FALSE)	//擦除一個扇區(qū)
		{
			return?FALSE;
		}
		if(W25X16_WriteNoCheck(SPI_FLASH_BUF,?DOWN_FONT_EXIT_SECTOR*4096+RecDataSize+PackSize-4096,?4096)??==?FALSE)	//寫入一個扇區(qū)
		{
			return?FALSE;
		}
		DownFontDataSaveCnt?+=?4096;
	}
	
	return?TRUE;
}


//傳輸結(jié)束時回調(diào)(可能是出錯結(jié)束)
//由于需要4K對齊,因此最后一包不足4K需要單獨進(jìn)行處理
//需要使用到W25X16的4K臨時緩沖區(qū),在升級與校驗的時候確保沒有其它線程訪問W25X16,最好掛起其它線程
bool?DownFontTransEndtExitFlash(bool?isTransOK,?u32?RecDataSize)
{
	if(isTransOK==FALSE)?return?FALSE;	//失敗返回
	
	if(DownFontDataSaveCnt?==?RecDataSize)?return?TRUE;
	if(DownFontDataSaveCnt?>?RecDataSize)?return?FALSE;			//存儲的數(shù)據(jù)不能大于接收的數(shù)據(jù)
	if((RecDataSize-DownFontDataSaveCnt)?>=?4096)?return?FALSE;	//未存儲的數(shù)據(jù)大小不能超過4K
	if(W25X16_EraseSector(DownFontDataSaveCnt/4096?+?DOWN_FONT_EXIT_SECTOR)?==?TRUE)													//擦除一個扇區(qū)
	{
		if(W25X16_WriteNoCheck(SPI_FLASH_BUF,?DOWN_FONT_EXIT_SECTOR*4096+DownFontDataSaveCnt,?RecDataSize-DownFontDataSaveCnt)??==?TRUE)	//寫入一個扇區(qū)
		{
			return?TRUE;
		}
	}

	return?FALSE;	//存儲出錯
}


//使用XMODEM下載字庫數(shù)據(jù)到外部flash
//返回程序大小,如果失敗了返回<=0
int?XMODEM_DownloadFontToExitFlash(u32?MaxFileSize)
{
	XMODE_Init(&UpgradeHandle,?			//句柄
		UpgradeSendData,?				//發(fā)送數(shù)據(jù)回調(diào)函數(shù)
		UpgradeReadData,?				//讀取數(shù)據(jù)回調(diào)函數(shù)
		UpgradeClearData,?				//清除接收數(shù)據(jù)緩沖回調(diào)函數(shù)
		DownFontReceivePacketExitFlash,?//接收到數(shù)據(jù)包回調(diào)函數(shù)
		DownFontTransEndtExitFlash		//傳輸結(jié)束回調(diào)函數(shù)
		);
	DownFontDataSaveCnt?=?0;				//已經(jīng)存儲的數(shù)據(jù)大小清零
	return?XMODEM_DownloadFile(&UpgradeHandle,?MaxFileSize);
}




//使能系統(tǒng)命令行
#if?SYS_CMD_EN_
#include?"cmd.h"
#include?"string.h"

CMD_TYPE?const?CMD_DOWN_BIN	=?{"DOWN?BIN",?0X51A36D01,?CMD_DownFont,?"t下載字庫數(shù)據(jù)"};			//下載字庫數(shù)據(jù)

//升級應(yīng)用層-需要使用到W25X16的4K臨時緩沖區(qū),在升級與校驗的時候確保沒有其它線程訪問W25X16,最好掛起其它線程
void?CMD_DownFont(char?*pStr)
{
	u32?DataSize;
	
	cmd_printf("已經(jīng)進(jìn)入升級程序模式,等待連接,超時10S!rn>");
	cmd_printf("請在10S內(nèi)進(jìn)入Xmodem下載字庫模式!rn>");
	
	RTC_DisableInt();									//關(guān)閉RTC中斷,防止喚醒后臺任務(wù)
	OSTaskSuspend(BACK_TASK_Prio);						//掛起后臺任務(wù)線程
	OSTaskSuspend(LED_TASK_Prio);						//掛起LED任務(wù)線程
	OSTaskSuspend(GPRS_TASK_Prio);						//掛起GPRS進(jìn)程
	OSTaskSuspend(COLL_TASK_Prio);						//數(shù)據(jù)采集時間查詢進(jìn)程
	OSTaskSuspend(OTHER_TASK_Prio);						//OTHER
	OSTaskSuspend(MODBUS1_TASK_Prio);					//MODBUS1	
	OSTaskSuspend(MODBUS2_TASK_Prio);					//MODBUS2
	OSTaskSuspend(KEY_TASK_Prio);						//KEY
	
	DataSize?=?XMODEM_DownloadFontToExitFlash(FLASH_BIN_SIZE);//下載字庫
	if(DataSize==0)
	{
		cmd_printf("下載字庫失敗!rn>");
	}
	else
	{
		cmd_printf("下載字庫成功(%dB)!rn",DataSize);
	}
	CMD_Help(NULL);
	OSTaskResume(LED_TASK_Prio);						//恢復(fù)掛起LED任務(wù)線程
	OSTaskResume(GPRS_TASK_Prio);						//恢復(fù)掛起GPRS進(jìn)程
	OSTaskResume(COLL_TASK_Prio);
本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉