【ARM-WINCE】WinCE5.0/6.0下,通過command line實現自動化編譯
在網上的很多論壇中都看到有人提問:應用程式如何直接讀寫Flash的扇區,或者是類似的問題。總之,就是希望應用程式能夠直接訪問Flash裝置,直接讀寫扇區的資料,或者作其他的操作。這幾天沒事,就嘗試著做了一下,把我的方法介紹給大家。
先做個簡單的介紹。WinCE支援Flash裝置,一般指Nandflash或者是NORFlash,採用的架構一般是FAL+FMD架構,我們實現FMD相關的介面函式,Flash的驅動就算完成了。當WinCE啟動以後,我們能夠看到Flash裝置的磁碟。我們可以操作磁碟上面的檔案,但是不能直接操作flash裝置,對Flash裝置的操作無非就是:讀,寫,擦除,讀ID。
現在開始介紹實現的方法。我們如果想在應用程式中直接呼叫FMD中的FMD_ReadSector(..),FMD_WriteSector(..),FMD_EraseBlock(..)是不太現實的。這裡再補充一下,這三個函式分別是Flash的讀扇區,寫扇區,擦除塊的函式。好像有點羅嗦了。但是我們可以在應用程式中呼叫到FMD_OEMIoControl(..)函式,這個是可以做到的。所以我們需要改一下Flash裝置的驅動程式,也就是改Flash裝置驅動中的FMD_OEMIoControl(..)這個函式。我的改動如下:
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
PFMDInterface pInterface = (PFMDInterface)pOutBuf;
RETAILMSG(1, (TEXT("FMD_OEMIoControl: control code is 0x%x\r\n"), dwIoControlCode));
switch(dwIoControlCode)
{
case IOCTL_FMD_GET_INTERFACE:
if (!pOutBuf || nOutBufSize < sizeof(FMDInterface))
{
DEBUGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));
return(FALSE);
}
pInterface->cbSize = sizeof(FMDInterface);
pInterface->pInit = FMD_Init;
pInterface->pDeInit = FMD_Deinit;
pInterface->pGetInfo = FMD_GetInfo;
pInterface->pGetInfoEx = NULL; //FMD_GetInfoEx;
pInterface->pGetBlockStatus = FMD_GetBlockStatus;
pInterface->pSetBlockStatus = FMD_SetBlockStatus;
pInterface->pReadSector = FMD_ReadSector;
pInterface->pWriteSector = FMD_WriteSector;
pInterface->pEraseBlock = FMD_EraseBlock;
pInterface->pPowerUp = FMD_PowerUp;
pInterface->pPowerDown = FMD_PowerDown;
pInterface->pGetPhysSectorAddr = NULL;
pInterface->pOEMIoControl = FMD_OEMIoControl;
break;
case 0xff123456:
FMD_ReadSector(..); //呼叫讀Sector函式
break;
case 0xff654321:
FMD_WriteSector(..); //呼叫寫Sector函式
break;
case 0xff123457:
FMD_EraseBlock(..); //呼叫擦除Block函式
break;
default:
DEBUGMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));
return(FALSE);
}
return(TRUE);
}
在FMD_OEMIoControl(..)函式裡面增加了3個case,這3個case裡面呼叫了讀/寫/擦除函式。至於Case的值,我是隨便定義的。這樣Flash裝置的驅動部分就改完了。
在改完Flash驅動以後,我下面會提供兩種方法,每一種方法都和Flash裝置的登錄檔配置有關:
1. 以Nandflash為例,當然對於NORFlash來說大同小異,登錄檔配置如下:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NANDFlash]
"Dll"="ep94xxnandflash.dll"
"Prefix"="DSK"
"Order"=dword:4
;"Ioctl"=dword:4
"Profile"="NSFlash"
"IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
; Override names in default profile
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash]
"Name"="Ep94xx NAND Flash"
"Folder"="NANDFlash"
"PartitionDriver"="MSPart.dll"
"AutoMount"=dword:1
"AutoPart"=dword:1
"AutoFormat"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash\FATFS]
"EnableCache"=dword:1
"CacheSize"=dword:1000
"MountBootable"=dword:1
"Flags"=dword:00000024
"CheckForFormat"=dword:1
然後編寫應用程式,主要就是通過CreateFile來開啟DSK1:裝置,然後通過DeviceIoControl(..)函式來呼叫FMD_OEMIoControl(..)函式,來達到直接讀/寫/擦除Flash裝置的目的。應用程式程式碼如下:
HANDLE hFirm;
hFirm = CreateFile(TEXT("DSK1:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(hFirm == INVALID_HANDLE_VALUE)
{
printf("Open Flash Device Failed");
return 0;
}
iRet = DeviceIoControl(hFirm, 0xff123456, para1, para2, para3, para4, para5, para6); //Read Flash Sector
iRet = DeviceIoControl(hFirm, 0xff654321, para1, para2, para3, para4, para5, para6); //Write Flash Sector
iRet = DeviceIoControl(hFirm, 0xff123457, para1, para2, para3, para4, para5, para6); //Erase Flash Block
printf("DeviceIoControl OK\r\n");
while(1)
;
通過上面的應用程式,就能夠呼叫到Flash裝置驅動中的FMD_OEMIoControl(..)函式,這樣根據不同的case就可以呼叫讀/寫/擦除函式了。
2. 以Nandflash為例,當然對於NORFlash來說大同小異,登錄檔配置如下:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NANDFlash]
"Dll"="ep94xxnandflash.dll"
"Prefix"="DSK"
"Order"=dword:4
;"Ioctl"=dword:4
"Profile"="NSFlash"
"IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
; Override names in default profile
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash]
"Name"="Ep94xx NAND Flash"
"Folder"="NANDFlash"
"PartitionDriver"="MSPart.dll"
"AutoMount"=dword:1
"AutoPart"=dword:1
"AutoFormat"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NSFlash\FATFS]
"EnableCache"=dword:1
"CacheSize"=dword:1000
"MountBootable"=dword:1
"Flags"=dword:00000024
"CheckForFormat"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\NSFlash]
"DriverPath"="Drivers\\BuiltIn\\NANDFlash"
"LoadFlags"=dword:0
"BootPhase"=dword:1
然後編寫應用程式,主要就是通過OpenStore來開啟NSFlash,然後通過DeviceIoControl(..)函式來呼叫FMD_OEMIoControl(..)函式,來達到直接讀/寫/擦除Flash裝置的目的。應用程式程式碼如下:
HANDLE hFirm;
hFirm = OpenStore(L"NSFlash");
if(hFirm == INVALID_HANDLE_VALUE)
{
printf("Open Flash Device Failed");
return 0;
}
iRet = DeviceIoControl(hFirm, 0xff123456, para1, para2, para3, para4, para5, para6);
iRet = DeviceIoControl(hFirm, 0xff654321, para1, para2, para3, para4, para5, para6);
iRet = DeviceIoControl(hFirm, 0xff123457, para1, para2, para3, para4, para5, para6);
printf("DeviceIoControl OK\r\n");
while(1)
;
通過這種方法,也可以在應用程式中呼叫到FMD_OEMIoControl(..)函式,從而達到直接訪問Flash裝置的目的。
總結一下,上面的兩種方法大致原理其實是一樣的,都是通過DeviceIoControl函式來呼叫FMD_OEMIoControl函式,然後達到直接訪問Flash驅動的目的,這樣就可以在應用程式中直接讀/寫/擦除Flash裝置了。
最後需要注意的是:你的Flash驅動裡面需要對讀/寫/擦除等直接操作Flash硬體的函式進行保護,因為Flash裝置應該是由WinCE的檔案系統來管理的,而現在你的應用程式也可以直接訪問它了,所以保險起見,新增互斥量保護避免訪問衝突。
上面的所有實現,都是在WinCE6.0上面做得,相信在WinCE5.0上面應該差不多。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-374494/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 通過自動化和現代化實現網路優化優化
- iOS自動化編譯打包iOS編譯
- Command Line Tools
- 通過Gradle自動實現Android元件化模組構建GradleAndroid元件化
- 透過 GitHub Actions 實現程式碼的自動編譯和釋出Github編譯
- 【node】command-line
- Command line is too long. Shorten command line for JooLunMallApiApplication or also for Spring Boot default configuration?APIAPPSpring Boot
- 是否只有實現了容器化、自動編排等等才算是實現了運維自動化?運維
- 通過矩陣變化實現的 3D 模型自動佈局矩陣3D模型
- 透過運維編排實現自動化智慧運維與故障自愈運維
- idea遇見Command line is too long. Shorten command line for Main or also for Application default configuration?IdeaAIAPP
- github或gitee等dev cloud使用actions通過yml配置實現自動化部署GithubGiteedevCloud
- Azure Command Line (一)入門
- Selenium自動化實現web自動化-1Web
- 使用Jenkins + git submodule 實現自動化編譯,解決程式碼安全性問題JenkinsGit編譯
- Gitee Webhook 實現自動拉取程式碼並編譯程式碼GiteeWebHook編譯
- 通過 PXE 自動化安裝 Ubuntu ServerUbuntuServer
- Error running ‘Application’Command line is too longErrorAPP
- [譯] 我如何使用 Node.js 來實現工作自動化Node.js
- 【譯】Facebook如何通過工具學習自動修復Bug ?
- 透過CRM系統實現工作流程自動化
- linux透過shell指令碼實現ssh互動式自動化Linux指令碼
- Android編譯通過,執行編譯錯誤問題總結Android編譯
- Spring Boot Intellij 執行應用的時候 Command line is too long. Shorten command line for 錯誤Spring BootIntelliJ
- IT 自動化:如何去實現
- MySQL 5.7 Command Line Client 閃屏退出MySqlclient
- Install VMware Tools in CentOS 7 command line modeCentOS
- 元件化下EventBus的訊息型別自動編譯元件化型別編譯
- Etcd 使用場景:通過分散式鎖思路實現自動選主分散式
- 如何通過python+Chrome實現自動申請某東試用PythonChrome
- IDEA命令列縮短器助你解決此問題:Command line is too long. Shorten command line...Idea命令列
- uni-app 通過命令列編譯打包APP命令列編譯
- Ubuntu20.04linux核心(5.4.0版本)編譯準備與實現過程-編譯過程(2)UbuntuLinux編譯
- 基於.net standard 的動態編譯實現編譯
- 如何實現辦公自動化?
- 使用gulp實現前端自動化前端
- iOS如何實現自動化打包iOS
- 使用 fastlane 實現自動化打包AST
- 通過佇列實現棧OR通過棧實現佇列佇列