锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 鍦–E4.2/5.0閲岄潰婊氭墦澶氬勾鐨勫厔寮熷簲璇ョ粡甯哥敤榪欎釜鍑芥暟鍚с傝繖涓嚱鏁版柟渚塊┍鍔ㄥ拰搴旂敤紼嬪簭鑼冨洿浠諱綍鐨勭墿鐞嗗湴鍧錛屽寘鎷墿鐞嗗唴瀛樺晩錛岃澶囨帶鍒跺櫒鐨勫瘎瀛樺櫒鍟婏紝鐢氳嚦GPIO涔熷彲浠ュ湪AP閲岄潰闅忎究鎷変笂鎷変笅銆?/font> 榪欎釜鍑芥暟铏界劧鏂逛究錛屼絾鏄茍涓嶅畨鍏紝浣犳兂浣犲ソ涓嶅鏄撴妸涓涓姛鑳藉畬鍠勭殑image緇檅uild鍑烘潵浜嗭紝緇撴灉紕板埌浜嗕竴涓啓AP鐨?#8220;楂樻墜”錛屾妸浣犵殑瀵勫瓨鍣ㄥ拰鍏變韓鍐呭瓨涓殑鏁版嵁淇敼寰椾竴濉岀硦娑傦紝鏈鍚庢姤鍑篵ug鏉ヨ浣犻┍鍔ㄧ殑浣犱細涓嶄細鏅曞掞紒 榪樺ソ浠嶤E6.0寮濮嬫垜浠彲浠ュ畨鏋曟棤蹇т簡錛屽洜涓篈P鍐嶄篃涓嶈兘璋冪敤VirtualCopy鍑芥暟鏉ョ洿鎺ヨ闂墿鐞嗗湴鍧浜嗭紝浣嗗洜姝ゅ甫鏉ヤ簡涓浜涘簲鐢ㄤ笂鐨勪笉渚褲?/font> VirtualCopy鐨勯檺鍒舵潵婧愪簬CE6.0涔嬪悗kernel鐨勫法澶у彉闈╋紝鍦–E5.0涔嬪墠鐨刉indows CE鎿嶄綔緋葷粺涓紝kenrel灝變粎浠呮槸kern.exe錛坣k.exe錛夛紝榪欎釜exe鍏跺疄鏄疧AL銆並ITL鍜孠ernel涓変釜鐨勫悎浣擄紝nk.exe鏄繍琛屼簬鍐呮牳妯″紡錛坘ernel mode錛夛紝涔熷氨鍏鋒湁浜嗚闂壒孌婂湴鍧鐨勬潈闄愶紝鐒跺悗闄ゆ涔嬪鐨勪唬鐮侀粯璁ら兘鏄繍琛屼簬鐢ㄦ埛妯″紡錛坲ser mode錛夛紝鎵浠ュ畠浠殑椹卞姩鍜孉P閮芥槸絳夌駭鐨勶紝閮藉湪鐢ㄦ埛妯″紡榪愯錛岃榪愯鍦╧ernel妯″紡涔熷彲浠ワ紝璋冪敤涓涓狝PI SetKmode錛堬級灝辮浜嗐傚洜涓洪┍鍔ㄦ槸鑲畾瑕佽闂墿鐞嗗湴鍧鐨勶紝鎵浠E5.0浠ュ墠鐨凮S閮芥槸榪愯鐢ㄦ埛妯″紡鐨勭▼寮忚闂墿鐞嗗湴鍧鐨勶紝鐒跺悗鍙堜負浜嗘柟渚垮仛浠庣墿鐞嗗湴鍧鍒拌櫄鎷熷湴鍧鐨勬槧灝勶紝灝辨彁渚涗簡涓緋誨垪鐨勫府鍔╁嚱鏁幫紝virtualcopy灝辨槸鏈甯哥敤鐨勫嚱鏁頒箣涓銆?/font> CE6.0寮濮嬶紝kernel妯″紡鍙樺緱姣旇緝姝h錛岀被浼間簬鍙板紡鏈轟笂鐨剋indows緋葷粺浜嗭紝椹卞姩鍜宎p鐨勬潈闄愭槸涓ユ牸鍖哄垎鐨勶紝澶ч儴鍒嗙殑椹卞姩紼嬪簭榪愯鍦╧ernel妯″紡錛屽畠浠彲浠ョ敤virtualcopy璇誨啓鐗╃悊鍦板潃瀵瑰簲鐨勭墿鐞嗚澶囷紝浣嗙敤鎴鋒ā寮忕殑AP灝嗕粠姝ゆ病鏈夌洿鎺ヨ闂墿鐞嗗湴鍧鐨勬潈闄愶紝virtualcopy姣忔璋冪敤閮戒細澶辮觸榪斿洖銆?/font> 鍦ㄨ繖閲岃繕瑕佹敞鎰忕殑鏄紝鍏跺疄騫朵笉鏄敤鎴鋒ā寮忓氨涓嶈兘浣跨敤virtualcopy錛寁irtualcopy鍙槸涓嶈兘鍦ㄧ敤鎴鋒ā寮忕殑AP涓嬌鐢紝浣嗘槸鍗磋繕鍙互鍦ㄧ敤鎴鋒ā寮忕殑椹卞姩浣跨敤錛屼絾鏄湪鐢ㄦ埛妯″紡鐨勯┍鍔ㄤ腑浣跨敤涔熸湁鏉′歡錛岄偅灝辨槸蹇呴』鍦ㄥ搴旂殑娉ㄥ唽琛ㄤ腑璁劇疆鍙互璁塊棶鐨勫唴瀛樺湴鍧鐨勮寖鍥存墠琛屻?/font> 鍦ㄦ煇浜涘満鍚堬紝涓浜涚壒孌婂姛鑳界殑AP紜疄闇瑕佽闂墿鐞嗗湴鍧鐨勶紝姣斿璁劇疆淇濆瓨鐗╃悊鍐呭瓨鎸囧畾浣嶇疆鐨勫叏灞鍙橀噺錛屽紑鍙戣鍐橤PIO鐨勬祴璇曞伐鍏風瓑絳夈傚湪榪欑鎯呭喌涓嬩竴縐嶇畝鍗曠殑鏂規硶鏄疄鐜頒竴涓渶綆鍗曠殑璺戝湪kernel妯″紡鐨勬祦椹卞姩錛屾彁渚涗竴涓猟eviceiocontrol鐨勬帴鍙f潵甯姪AP鐢寵瀵瑰簲浜庣墿鐞嗗唴瀛樺湴鍧鐨勮櫄鎷熷唴瀛樺湴鍧銆?/font> 闄や簡virtualcopy涔嬪錛孋E6涓嬭繕鏈夊緢澶欰PI鏄疉P鍜寀ser妯″紡鐨勯┍鍔ㄤ笉鑳借皟鐢ㄧ殑錛岀粰澶у鍙傝冧竴涓嬶紝澶у瑕佹妸CE50涓嬬殑AP縐繪鍒?.0涓嬩竴瀹氳娉ㄦ剰鎵懼埌鏇夸唬 Virtual Memory APIs File System APIs Power APIs Miscellaneous APIs 銆銆Windows CE 6.0鐨勬柊鍙橀潻 銆銆Windows CE 6.0渚濇棫鎶婄溂鍏夋姇娉ㄥ湪ARM鏋舵瀯涓紝鏂扮殑BSP涓庣紪璇戝櫒涔熼兘鏀寔浜咥RM鐨勬渶鏂頒綋緋伙紝浣嗘槸鍏跺畠宓屽叆寮?/font>澶勭悊鍣ㄧ殑鏀寔涔熸病鏈夎蹇借錛屽▉鐩涘叕鍙告渶鏂扮殑澶勭悊鍣ㄤ篃鍦ㄤ笉涔呭墠瀹gО鏀寔浜?a target=_blank>Windows CE 6.0鎿嶄綔緋葷粺銆傝?.0鐗堜篃鏄?a target=_blank>寰蔣棣栦釜瀵煎叆嬈′笘浠f。妗堢郴緇烢xFAT鐨?a target=_blank>鎿嶄綔緋葷粺錛岃櫧鐒跺埌鐩墠涓烘鍏剁粏鑺傝繕涓嶆槑浜嗭紝浣嗘槸鏍規嵁宸叉湁鐨勪俊鎭寚鍑猴紝ExFAT鍦?a target=_blank>Windows CE 6.0涓紝鎷呭綋浜嗘葷鎵鏈夊鎺ュ偍瀛樺獟浣撶殑涓晫灞傜殑瑙掕壊錛屽箍涓轟駭涓氱晫鎵縐拌禐鐨勬槸錛岃繖鑳藉瑙i櫎榪囧幓浼犵粺FAT妗f緋葷粺鐨?2GB鍗曚竴瀹歸噺闄愬埗銆侲xFAT鍚屾牱涔熻В闄や簡鍗曚竴妗f鍙兘鍦?GB浠ヤ笅鐨勯檺鍒訛紝榪欏浜庣‖浠跺巶鍟嗕互Windows CE鍙戝睍澶у閲忓偍瀛樼鐞嗕己鏈嶆灦鏋勶紝鏈夎憲鐩稿綋澶х殑甯姪銆傚姞涓婁竴浜涘畨鍏ㄦ満鍒訛紝鎴戜滑鍙互鎶奅xFAT瑙嗕負Windows CE 6.0涓婄殑NTFS鍔犲己鐗堛?/p>
銆銆VoIP涔熸槸Windows CE 6.0鍙︿竴涓寔緇姞寮虹殑閲嶇偣錛岄櫎浜嗗湪搴旂敤紼嬪簭灞傜殑鏁村悎鏇磋繘涓姝ヤ互澶栵紝鎿嶄綔緋葷粺鏍稿績涔熷叿澶囩洿鎺ユ敮鎸佺殑鑳藉姏錛屽洜姝ょ‖浠跺紑鍙戜笂鍙互鏇村鏄撶殑鍦?a target=_blank>Windows CE鐜涓婅繘琛屽悇縐嶇綉緇滅殑璇煶閫氳鏈嶅姟銆傝屽洜搴旇繖鏍風殑瓚嬪娍錛?.0鐗堣嚜鐒朵篃鎶婅繃鍘?.0鐗堢殑緙哄け琛ユ榪囨潵錛屽湪緗戠粶鍫嗗彔鍗忓畾鏂歸潰錛岀洿鎺ユ敮鎸佷簡802.11i銆乄AP2銆?02.11e錛堟棤綰縌oS錛夈佽摑鐗橝2DP/AVRCP鐨凙ES鍔犲瘑絳夌瓑錛屼負鏃犵嚎閫氳寤虹珛浜嗕竴涓ǔ瀹氥佸畨鍏ㄤ互鍙婂彲闈犵殑搴旂敤鐜銆?/p>
銆銆鑰屼粠浣跨敤鑰呰鐐規潵鐪嬶紝Windows CE 6.0鎵╁睍浜嗚秴瓚婁互寰鐗堟湰鎬誨拰鐨勬壙璇猴紝榪欎簺鍔熻兘鍖呮嫭浜嗘渶鏂扮殑澶氬獟浣撹兘鍔涳紝璇稿Windows Media 10/11鐨勬敮鎸併侊紝瀵逛簬緗戠粶澶氬獟浣撹緗殑鍘熺敓鏁村悎鑳藉姏錛屽湪Platform Builder寮鍙戝伐鍏蜂腑錛岀敋鑷充篃鍔犲叆浜嗚鍔ㄥ獟浣撲腑蹇冪殑鏀寔錛屽彲浠ヨ棄鐢?a target=_blank>Windows Media Connect 2.0澶у箙寮哄寲澶氬獟浣撳簲鐢ㄧ殑鏀寔鑳藉姏錛屽茍涓斿彲浠ヤ笌鍏跺畠寰蔣鐨?a target=_blank>鎿嶄綔緋葷粺鎴栫‖浠惰緗仛鍚屾緇熷悎鐨勫姩浣溿傝繖浜涘姛鑳藉寘鍚簡浠ヤ笅欏圭洰錛?/p>
銆銆鈻?TIFF緙栬В鐮佸櫒鐨勬敮鎸?br>銆銆鈻?HD-DVD鐨勮В鐮佸櫒鏀寔 銆銆铏界劧鍦ㄦ牳蹇冮儴鍒嗗仛鍑鴻繖涔堝ぇ鐨勬洿鏂幫紝浣嗘槸Windows CE 6.0鐨勫偍瀛樹笂騫舵病鏈夊寰蔣鍏跺畠鎿嶄綔緋葷粺鑸殑椋炴定錛圴ista鐢氳嚦闇瑕佽秴榪?0GB鐨勫垵濮嬪偍瀛樺畨瑁呯┖闂達紒錛夛紝鐩歌緝璧?.0鐗堬紝6.0鍦ㄤ綋縐笂涔熶笉榪囧鍔犱簡5錛呭乏鍙籌紝铏界劧榪欏宓屽叆寮?/font>緋葷粺浜т笟鏉ヨ鏄悊鎵褰撶劧錛屼絾瀵逛簬寰蔣鍙互璇存槸鍙︿竴欏瑰榪廣?/p>
銆銆Windows CE 6.0甯︾粰寮鍙戣呯殑濂藉 銆銆鍦ㄥ紑鏀懼師濮嬬爜鐨勫巻鍙蹭腑錛?a target=_blank>寰蔣瑕佸啓涓嬪彟涓涓柊鐨勯噷紼嬬錛?00錛呭浜у搧寮鍙戣呴噴鏀懼嚭鍘熷鐮侊紝涓斿彲鍏佽鍘傚晢榪涜鑷鐨勫彉鏇存垨璁㈠仛錛岃屾棤欏婚噴鏀懼嚭緇忚繃淇敼鐨勭▼搴忕爜錛岃櫧鐒跺湪騫夸箟涓婂茍涓嶈兘瑙嗕負鐪熸寮鏀撅紝浣嗘槸涓鴻繖浜涘枩嬈㈣棌縐佺暀涓鎵嬬殑鍘傚晢鏉ヨ錛屾棤鐤戞槸澧炲姞绔炰簤鍔涚殑鏈浣蟲墜孌典箣涓銆傝屼綔涓哄紑鍙戝伐鍏風殑Visual Studio 2005 PRO灝嗕細浣滀負Windows CE 6.0鐨勬暣浣撳浠朵箣涓錛屽唴寤虹殑璁稿寮鍙戝伐鍏蜂笌瀹氫箟瀵逛簬寮鍙戣呮潵璇寸浉瀵逛究鍒╄澶氥?/p>
銆銆Windows CE 6.0鏀寔浜?a target=_blank>Windows .NET Compact Framework 2.0浣滀負搴旂敤紼嬪簭綆$悊寮鍙戜互鍙奧in32銆?MFC銆?ATL銆?WTL鍜孲TL絳?a target=_blank>紼嬪簭寮鍙?/font>鐣岄潰鎻愪緵緇欏紑鍙戝師鐢熷簲鐢ㄧ▼搴忕殑寮鍙戣呬嬌鐢ㄣ傚叿澶囦簡濡傛鍔垮姏搴炲ぇ浠ュ強瀹屾暣鐨勫紑鍙戠幆澧冧綔涓烘敮鎸侊紝寮鍙戣呬笌鍒墮犲晢涔熷彲紜繚鍚庣畫鐨勬敮鎸佷笉铏炲尞涔忋?/p>
銆銆鑰屽湪紜歡鏂歸潰錛屾牴鎹?a target=_blank>寰蔣鏂歸潰鐨勮娉曪紝鍦ㄤ笉鍙樻洿鍘熸湁鐨勭‖浠舵灦鏋勪箣涓嬶紝瀵煎叆Windows CE 6.0鍙互澶у箙鏀瑰杽鍘熸湁紼嬪簭鐨勬墽琛屾晥鐜囷紝騫朵笖涔熷璁稿悓鏃墮棿鏈夋洿澶氱▼搴忓悓姝ユ墽琛岋紝鐢變簬姣忎釜紼嬪簭閮藉叿澶囨湁鐙珛鐨勬墽琛岀┖闂達紝鐗瑰畾紼嬪簭褰撴帀錛屼篃涓嶄細褰卞搷鍒板叾瀹冨簲鐢ㄧ▼搴忔垨緋葷粺鎵ц錛屾彁渚涚粰浣跨敤鑰呮瘮璧蜂互寰鏃х増緋葷粺鏇村己鐨勭ǔ鍥烘т笌鏇村ぇ鐨勫脊鎬с傝岀洰鍓嶉愭笎椋庤鐨勫鏍稿績澶勭悊鏋舵瀯涓婏紝Windows CE 6.0涔熷彲浠ュ湪涓嶅彉鏇?a target=_blank>紼嬪簭寮鍙?/font>鑰呭師鏈夌▼搴忔ā鍨嬬殑鐘跺喌涔嬩笅錛屾彁渚涙渶浣沖寲鐨勬牳蹇冨伐浣滆嚜鍔ㄥ垎閰嶄笌鎸囧畾錛屽綋鐒訛紝濡傛灉鏈夐渶姹傜殑璇濓紝紼嬪簭寮鍙?/font>鑰呬緷鐒跺彲浠ヨ嚜琛屽喅瀹氭寚瀹氭牳蹇冪殑鏂瑰紡銆?/p>
銆銆甯傚満涓婄殑瀹為檯搴旂敤涓庣粨璁?/p>
銆銆鎴嚦鐩墠涓烘錛屽彴婀懼凡緇忔湁鐮斿崕縐戞妧鍦ㄩ拡瀵圭墿嫻併佷粨鍌ㄧ鐞嗐佸叕鍏辨湇鍔′互鍙婇鍩熺淮鎶ゆ柟闈㈢殑搴旂敤錛岃繘琛屽熀浜?a target=_blank>Windows CE 6.0鎿嶄綔緋葷粺涓嬬殑宸ヤ笟綰ф帉涓婂瀷緇堢鏈虹殑寮鍙戯紝鑰岀簿鎶璁$畻鏈哄垯鏄紑鍙戜簡鍙簲鐢ㄤ簬鎼滈泦璧勬枡銆丷FID銆丅arCode綆$悊鐨勫瀭鐩村競鍦篜DA錛岄噰鐢?a target=_blank>Windows CE 6.0涓殑cell core鍏冧歡錛岀緝鐭璆PRS绔殑璧勬枡浼犺緭璁捐鏃剁▼銆傝屽悇澶ф墜鎸佸紡鏅鴻兘瑁呯疆鐨勫紑鍙戣呬篃閮藉凡緇忓湪鐫鎵嬪鍏?a target=_blank>Windows CE 6.0錛屽疄闄呬駭鍝侀璁″皢浼氫簬2007騫寸浜屽涔嬪悗閫愭笎嫻幇鍙伴潰銆?/p>
銆銆100錛呭紑鏀懼師濮嬬爜鐨勫垱涓懼浜?a target=_blank>寰蔣鏉ヨ鏄釜鐩稿綋澶х殑紿佺牬錛岃櫧鐒惰繖鏈変竴澶ч儴鍒嗘槸鍥犱負宓屽叆寮?/font>Linux鎵甯︽潵鐨勭珵浜夋寫鎴樻墍鑷達紝浣嗘槸楣殞鐩鎬簤鐨勭粨鏋滐紝甯︾粰寮鍙戜紮浼寸殑濂藉涔熻繙澶т簬榪囧幓閲囩敤灝侀棴妯″紡鐨勬祦紼嬶紝鑰屽歡緇繃鍘?a target=_blank>Windows CE 5.0鐨勬垚鏋滐紝Windows CE 6.0涔熷皢浼氱戶緇湪宓屽叆寮?/font>搴旂敤銆佽鍔ㄨ緗丟PS銆佹櫤鑳藉瀷鎵嬫満絳夊競鍦虹戶緇敾鍩庢帬鍦幫紝涓嶈繃鍦ㄩ潰瀵瑰競鍦轟笂璇稿瀵規墜鐨勭珵浜夛紝寰蔣浠嶉』鍋氬嚭鏇村鐨勬敼榪涖傛瘮濡傚湪淇婕忔礊鏂歸潰鍙互鏇村揩閫熺殑鍙嶅簲銆佸茍涓旀彁渚涚粰寮鍙戣呮洿澶х殑鏀寔鍔涘害絳夌瓑錛屽綋寮鍙戣呯敎澶村悆鐨勫澶氾紝鑷劧涔熶細瀵?a target=_blank>Windows CEWindows CE鏋舵瀯鏇翠負蹇犺瘹錛屽嚭鐜板湪甯傞潰涓婄殑浜у搧鑷劧涔熶細鏇翠負鎴愮啛銆?br> OEMAddressTable閲屽畾涔夌殑鏄犲皠鍏崇郴鏄粰ARM MMU鐢ㄧ殑,鏄湪KernelStart(source code鍙傝僿ince420private鐩綍)鏃跺緩绔嬬殑,鍙WINCE榪樺湪璺?灝變笉浼氳В闄? 濡傛灉浣犵殑鍦板潃鏄繖鏍峰0鏄庣殑: 聽
CeVirtualSharedAlloc
LockPages
LockPagesEx
UnlockPages
UnlockPagesEx
VirtualAllocCopyEx
VirtualCopyEx
VirtualSetAttributes
CreateStaticMapping
NKDeleteStaticMapping
VirtualCopy
ReadRegistryFromOEM
SetStoreQueueBase
WriteRegistryToOEM
PowerOffSystem 錛堝緢澶氭祴璇旳P鐢ㄥ埌錛?/font>
SetOOMEvent
]]>
閲嶆柊璁捐浜咾ernel錛屾敮鎸佺殑榪涚▼鏁頒粠32涓墿灞曞埌32000
姣忎釜榪涚▼鐨勫湴鍧絀洪棿浠?2MB鎵╁睍鍒?GB
寰堝緋葷粺妯″潡錛堝鏂囦歡緋葷粺鍜岃澶囩鐞嗗櫒錛夊皢榪愯鍦╧ernel妯″紡錛孫AL涔熶粠kernel鐙珛鍑烘潵錛宒river鍙互榪愯鍦╧ernel妯″紡鍜寀ser妯″紡
Visual Studio 2005涓撲笟鐗堝皢鍖呮嫭涓涓縐頒負Platform Builder鐨勫姛鑳藉己澶х殑鎻掍歡錛屽畠鏄竴涓笓闂ㄤ負宓屽叆寮忓鉤鍙版彁渚涚殑“闆嗘垚寮鍙戠幆澧?#8221;銆傝繖涓泦鎴愬紑鍙戠幆澧冧嬌寰楁暣涓紑鍙戦摼铻嶄負涓浣擄紝騫舵彁渚涗簡涓涓粠璁懼鍒板簲鐢ㄩ兘鏄撲簬浣跨敤鐨勫伐鍏鳳紝鏋佸ぇ鍦板姞閫熶簡璁懼寮鍙戠殑涓婂競
Windows Embedded CE 6.0鍔犲叆浜嗘柊鐨勫崟鍏冩牳蹇冩暟鎹拰璇煶緇勪歡
Windows Embedded CE 6.0鍖呭惈鐨勭粍浠舵洿渚夸簬寮鍙戣呭垱寤洪氳繃Windows Vista™鍐呯疆鍔熻兘鏃犵嚎榪炴帴鍒拌繙紼嬫闈㈠叡浜綋楠岀殑鎶曞獎浠?br>
鏉ヨ嚜 http://develop.csai.cn/ebd/200702031135001231.htm
Windows CE 6.0澶у箙鏀瑰彉浜嗘牳蹇冨畾鍧浠ュ強璧勬簮鍒嗛厤鐨勬満鍒訛紝鏃х増CE鍚屾椂闂村彧鑳芥湁32涓▼搴忔墽琛屼簬鍚勮嚜鍒嗛厤鐨?2MB铏氭嫙瀛樺偍鍣ㄧ┖闂翠腑錛?.0鐗堝垯鏄ぇ騫呮斁瀹戒簡闄愬埗錛屾渶澶у彲鍚屾椂鎵ц32,000涓▼搴忥紝鑰屼笖姣忎釜紼嬪簭鍙嫢鏈夌嫭绔嬪垎閰嶇殑2GB铏氭嫙瀛樺偍鍣紝鍦ㄦ鍚屾椂錛屾牳蹇冩湇鍔°佺‖浠惰緗殑椹卞姩紼嬪簭銆佽紿楃粯鍥句互鍙婁簨浠跺瓙緋葷粺銆佹。妗堢郴緇熺瓑鏈嶅姟閮借杞Щ鍒扮郴緇熸牳蹇冧繚鐣欑┖闂翠腑銆備笉榪囪繖鏍風殑鏀瑰彉涔熶細甯︾粰浣跨敤鑰呯枒铏戯紝姣曠珶榪囧幓NT 4.0灝辨浘緇忎笂婕旇繃綾諱技鐨勬垙鐮侊紝灝嗛┍鍔ㄧ▼搴忎粠浣跨敤鑰呮ā寮忚漿縐誨埌鏍稿績妯″紡錛岃櫧鐒跺彲浠ュぇ騫呮敼榪涘簲鐢ㄧ殑閫熷害錛屼絾鏄竴涓綋璐ㄤ笉鑹殑椹卞姩紼嬪簭錛屽彲鑳藉氨浼氭嫋鍨暣涓郴緇燂紝鍥犳鍦ㄧ‖浠墮┍鍔ㄧ▼搴忕殑寮鍙戜笂錛屽氨蹇呴渶瑕佹湁涓湁鏁?a target=_blank>鏍囧噯鏉ヨ鑼冿紝鏈濂借繕瑕佸鍏ュWHQL涔嬬被鐨勯┍鍔ㄧ▼搴忛獙璇佹湇鍔★紝浠ラ伩鍏嶅獎鍝嶆暣涓郴緇熺殑紼沖畾鎬с?
銆銆鈻?MPEG-2瑙g爜鍣?br>銆銆鈻?鏇村鐨勫獎闊崇紪鐮佷笌鏍煎紡鏀寔
銆銆鈻?UDF 2.5鏍煎紡鐨勬敮鎸?br>銆銆鈻?铏氭嫙鐜粫澹伴亾鐨勬敮鎸?br>銆銆鈻?澶氳建闊蟲晥鐨勬敮鎸?br>銆銆鈻?寮哄寲DirectDraw錛屽彲鏀寔鐢佃浣跨敤鐨勪氦閿欐樉紺烘ā寮?br>銆銆鈻?USB OTG鍔熻兘鍔犲叆錛屽彲浣滀負USB鐨勬帶鍒剁
]]>
]]>
wy12218 鍙戣〃浜?2006-11-9 18:17:00
OEMAddressTable閲岀殑Virtual Addr鍜孭hysical Addr鏄ARM鏉ヨ鐨? 鍏跺疄瀵逛簬WINCE,灝卞彧鑳借闂埌瀹冪殑Virtual address. 涔熷氨鏄,OEMAddressTable閲岀殑Virtual address瀵筗INCE 緋葷粺鏉ヨ鎵嶆槸Physical Address.
緇忚繃OEMAddressTable鏄犲皠鍚庣殑緋葷粺鐨勭墿鐞嗗湴鍧,鍦?x80000000~0x9fffffff涔嬮棿.鏄痗aching and buffering鐨勫湴鍧,榪欎釜鍦板潃鍔犱笂0x20000000,灝辨槸瀹冪殑cache & buffering disabled鍦板潃.鎵鏈夌殑紜歡瀵勫瓨鍣ㄧ殑鍦板潃閮藉湪榪欎釜鍦板潃孌典笂,鍙桵MU淇濇姢鐨?
涓婇潰璁茬殑緋葷粺鐨勭墿鐞嗗湴鍧,浠?x80000000~0xbfffffff,鍦↘ernel Mode涓嬮兘鍙互鐩存帴璁塊棶. ISR鏄湪KERNEL閲?涔熷氨鍙互鐩存帴璁塊棶榪欎簺緋葷粺鐨勭墿鐞嗗湴鍧.鏃犳墍璋?鍥犱負ISR鍙兘璁塊棶闈欐佹槧灝勭殑铏氭嫙鍦板潃".
涓婇潰璇磋繃,瀵逛簬ARM鏉ヨ,鏈夎櫄鎷熷湴鍧鍜岀墿鐞嗗湴鍧涔嬪垎,瀵逛簬WINCE鏉ヨ,涔熸湁铏氭嫙鍦板潃鍜岀墿鐞嗗湴鍧涔嬪垎. 鍙互榪欎箞璇?ARM鐨勮櫄鎷熷湴鍧灝辨槸WINCE緋葷粺鐨勭墿鐞嗗湴鍧.
32浣嶇殑OS鎬誨叡鏈?G鐨勮櫄鎷熷湴鍧絀洪棿,WINCE涔熶笉渚嬪. 鍏朵腑,0x00000000~0x80000000鏄疉pplication Space; 0x80000000~0xffffffff鏄疭ystem Reserved. 緋葷粺鐨勭墿鐞嗗湴鍧灝卞湪System Reserved鐨勮繖孌?鍙兘鍦↘ERNEL MODE璁塊棶. 閭d箞,褰揂PPLICATION鍜孌RIVER(閮芥槸榪愯鍦║SER MODE)瑕佽闂繖浜涘湪System Reserved鍦板潃孌電殑紜歡瀵勫瓨鍣ㄦ垨MEMORY鎬庝箞鍔炲憿? 鍙ソ鍐嶅緩绔嬩竴灞傛槧灝勫叧緋?鍦ˋpplication Space閲屽垎閰嶄竴孌電┖闂?鎶婂畠鏄犲皠鍒癝ystem Reserved閲岀殑鍦板潃涓?榪欏氨鏄疺irtualAlloc/Copy鍜孧mMapIoSpace騫茬殑浜嬫儏.
#define RTC_COUNTER *((volatile unsigned *)0x91000000)
閭d箞鐩存帴璇誨啓灝卞彲浠ヤ簡,姣斿:
int nRtc = RTC_COUNTER;
RTC_COUNTER = nRtc;
鍚﹀垯,鍙互鐢?
int nRtc = READ_REGISTER_ULONG(0x91000000);
WRITE_REGISTER_ULONG(0X91000000, nRtc);
鍏跺疄榪欎袱縐嶆柟寮忕殑鏈川鏄竴鏍風殑,閮芥槸鎶婂湴鍧澹版槑鎴愭煇涓暟鎹被鍨?鐒跺悗灝卞彲浠ョ洿鎺ヨ鍐欎簡.涓嬮潰鏄疪EAD_REGISTER_ULONG()鍜學RITE_REGISTER_ULONG()鐨勫畾涔?
#define READ_REGISTER_ULONG(reg) (*(volatile unsigned long * const)(reg))
#define WRITE_REGISTER_ULONG(reg, val) (*(volatile unsigned long * const)(reg)) = (val)
]]>
]]>
銆銆濡傛灉鎮ㄦ湁鎶鏈棶棰樺悜鎴戝挩璇紝璇風櫥褰?a target="_blank">澶╂瀬緗戝祵鍏ュ紡寮鍙戣鍧?/font>錛屾湰浜哄皢鍦ㄦ璁哄潧鍥炲鎮ㄧ殑闂銆傚湪璁哄潧涓婁氦嫻佷細鏇存柟渚夸簺錛屽叾瀹冪綉鍙嬩篃鍙互鍥炵瓟鍙備笌錛屽譏琛ヤ簡鎴戠殑涓嶈凍銆?/p>銆銆姝f枃
銆銆姝eCE鐨勫府鍔╂枃妗f墍璦錛屽垱寤篛AL鏄竴涓潪甯稿鏉傜殑浠誨姟錛岃岄氬父鐨勫姙娉曟槸澶嶅埗鍘熸湁鐨勭浉鍚屽鉤鍙扮殑OAL浠g爜錛岀劧鍚庝慨鏀規潵閫傚簲騫沖彴鐨勭壒孌婅姹傘備篃灝辨槸璇村浜庢病鏈夌壒孌婅姹傜殑騫沖彴錛屽鍒跺師鏈夌浉鍚屽鉤鍙扮殑OAL浠g爜灝辮凍澶熶簡銆傜敱浜嶰AL鐨勫鏉傛у湪榪欑瘒鏂囩珷涓垜鍙瑙e父鐢ㄧ殑閮ㄥ垎銆?
銆銆涓銆佸疄鐜癐SR
銆銆1. ISR鐨勬蹇?br />
銆銆ISR錛坕nterrupt service routine錛夋槸澶勭悊IRQs錛坕nterrupt request line錛夌殑紼嬪簭銆俉indows CE鐢ㄤ竴涓狪SR鏉ュ鐞嗘墍鏈夌殑IRQ璇鋒眰銆傚綋涓涓腑鏂彂鐢熸椂錛屽唴鏍哥殑寮傚父澶勭悊紼嬪簭鍏堣皟鐢ㄥ唴鏍窱SR錛屽唴鏍窱SR紱佺敤鎵鏈夊叿鏈夌浉鍚屼紭鍏堢駭鍜岃緝浣庝紭鍏堢駭鐨勪腑鏂紝鐒跺悗璋冪敤宸茬粡娉ㄥ唽鐨凮AL ISR紼嬪簭錛屼竴鑸琁SR鏈変笅鍒楃壒寰侊細
銆銆1) 鎵ц鏈灝忕殑涓柇澶勭悊錛屾渶灝忕殑涓柇澶勭悊鎸囪兘澶熸楠屻佺瓟澶嶄駭鐢熶腑鏂殑紜歡錛岃屾妸鏇村鐨勫鐞嗗伐浣滅暀緇橧ST錛坕nterrupt service thread錛夈?br />
銆銆2) 褰揑SR瀹屾垚鏃惰繑鍥炰腑鏂璉D錛堜腑鏂璉D澶ч儴鍒嗘槸棰勫畾涔夌殑錛夈?br />
銆銆2. X86騫沖彴鐨処SR緇撴瀯
銆銆X86騫沖彴鐨処SR淇濆瓨鍦?_WINCEROOT%\PUBLIC\COMMON\OAK\CSP\I486\OAL\fwpc.c涓紝鍑芥暟鍚嶄負PeRPISR銆備笅闈㈠垎鏋愪竴涓嬫鍑芥暟鐨勪富瑕佷唬鐮侊細ULONG PeRPISR(void)
{
銆ULONG ulRet = SYSINTR_NOP; ///榪斿洖鍊鹼紝鏃腑鏂璉D錛堜互SYSINTR_涓哄墠緙錛?br />銆UCHAR ucCurrentInterrupt; ///褰撳墠涓柇鍙?br />銆if (fIntrTime) ////// fIntrTime 鐢ㄤ簬嫻嬭瘯SR鍜孖ST鐨勫歡鏃舵椂闂達紝嫻嬭瘯宸ュ叿涓篒LTiming.exe銆?br />銆銆......
銆銆ucCurrentInterrupt = PICGetCurrentInterrupt(); ////榪斿洖褰撳墠涓柇IRQ
銆if (ucCurrentInterrupt == INTR_TIMER0) ///IRQ0錛孖RQ0涓虹郴緇熸椂閽燂紙system tick錛変腑鏂紝鍏蜂綋瑙佲滀簩銆佸疄鐜扮郴緇熸椂閽熲?br />銆......
銆if (dwRebootAddress) ////鏄惁闇瑕侀噸鍚姩
銆銆RebootHandler();
銆銆......
銆if(ucCurrentInterrupt == INTR_RTC) ////IRQ8錛宺eal-time clock鐨勪腑鏂?br />銆銆......
銆else if (ucCurrentInterrupt <= INTR_MAXIMUM) ///濡傛灉涓柇灝忎簬 INTR_MAXIMUM
銆{
銆銆ulRet = NKCallIntChain(ucCurrentInterrupt); ////璋冪敤涓柇閾?br />銆銆if (ulRet == SYSINTR_CHAIN) ///濡傛灉涓柇閾炬湭鍖呭惈涓柇
銆銆銆ulRet = OEMTranslateIrq(ucCurrentInterrupt); ////鍦↖RQ 鍜孲YSINTR涔嬮棿杞崲錛屾鍑芥暟榪斿洖IRQ瀵瑰簲鐨凷YSINTR
銆銆銆......
銆銆銆PICEnableInterrupt(ucCurrentInterrupt, FALSE); ///鍚敤闄ゅ綋鍓嶄腑鏂互澶栫殑鎵鏈変腑鏂?br />銆} ///else if
銆OEMIndicateIntSource(ulRet); ///閫氱煡鍐呮牳宸茬粡鍙戠敓SYSINTR涓柇
}
銆銆浠庝互涓婁唬鐮佷笉闅劇湅鍑篒SR鐨勪換鍔″氨鏄繑鍥炰互鈥淪YSINTR_鈥濅負鍓嶇紑鐨勪腑鏂璉D錛屽鏋滀笉闇瑕佽繘涓姝ユ墽琛孖ST錛岄偅涔堝氨榪斿洖SYSINTR_NOP銆?br />
銆銆3. 涓柇娉ㄥ唽姝ラ
銆銆鍙傝僗86騫沖彴鐨勪唬鐮侊紝涓柇娉ㄥ唽姝ラ濡備笅錛?br />
銆銆1) 鐢⊿ETUP_INTERRUPT_MAP瀹忓叧鑱擲YSINTR鍜孖RQ銆備互鈥淪YSINTR_鈥濅負鍓嶇紑鐨勫父閲忕敱鍐呮牳浣跨敤錛岀敤浜庡敮涓鏍囪瘑鍙戠敓涓柇鐨勭‖浠躲傚湪Nkintr.h鏂囦歡涓瀹氫箟浜嗕竴浜汼YSINTR錛孫EM鍙互鍦∣alintr.h鏂囦歡涓嚜瀹氫箟SYSINTR銆?br />
銆銆2) 鐢℉ookInterrupt鍑芥暟鍏寵仈紜歡涓柇鍙峰拰ISR銆傝繖閲岀殑紜歡涓柇鍙蜂負鐗╃悊涓柇鍙鳳紝鑰岄潪閫昏緫涓柇鍙稩RQ銆傚湪InitPICs鍑芥暟錛堝拰涓婅堪ISR浣嶄簬鍚屼竴鏂囦歡錛夌殑鏈鍚庤皟鐢ㄤ簡HookInterrupt鍑芥暟錛屽涓嬶細for (i = 64; i < 80; i++)
銆HookInterrupt(i, (void *)PeRPISR); ///鐢↖SR鍏寵仈16涓腑鏂彿
銆銆4. 涓柇澶勭悊姝ラ
銆銆1) 璋冪敤InterruptInitialize鍑芥暟鍏寵仈SYSINTR鍜孖ST錛屽叿浣撴槸鍏寵仈IST絳夊緟鐨勪簨浠躲備竴鑸湪椹卞姩紼嬪簭涓寜濡備笅緙栧啓錛?br />hEvent = CreateEvent(...) ///鍒涘緩涓涓簨浠跺璞?br />InterruptInitialize(SYSINTR_SERIAL, hEvent, ...) ///鍏寵仈涓涓覆鍙d腑鏂璉D鍜岃繖涓簨浠?br />hThd = CreateThread(..., MyISTRoutine, hEvent, ...) ///鍒涘緩涓涓嚎紼嬶紙IST錛?br />CeSetThreadPriority(hThd, 152); ///鎻愰珮姝ょ嚎紼嬬殑浼樺厛綰?/td>
銆銆2) IST鎵цI/O鎿嶄綔錛屼竴鑸琁ST鎸夊涓嬬紪鍐欙細for(;;) ///椹卞姩紼嬪簭涓鐩村浜庢湇鍔$姸鎬?br />{
銆WaitForSingleObject(hEvent, INFINITE); ////鏃犻檺絳夊緟浜嬩歡
銆...... //// I/O鎿嶄綔
銆InterruptDone(InterruptId); ///緇撴潫褰撳墠涓柇澶勭悊
}
銆銆3) ISR鍜孖ST涔嬮棿鏁版嵁浼犺緭
銆銆鍋囧鎴戜滑瑕佷粠涓涓澶囬綣佺殑璇誨彇鏁版嵁鑰屾瘡嬈¤鍙栭噺闈炲父灝戯紝閭d箞姣忔璇誨彇閮借璋冪敤IST浼氶檷浣庢ц兘銆備綔涓鴻В鍐蟲柟妗堬紝ISR鍙互鍋氳鍙栧伐浣滐紙瀛樻斁鍒扮紦鍐插尯錛夛紝騫跺湪緙撳啿鍖哄瓨鏀炬弧鍚庣敱IST鍒扮紦鍐插尯璇誨彇銆傚洜涓篒SR榪愯鍦ㄥ唴鏍告ā寮忚孖ST榪愯鍦ㄧ敤鎴鋒ā寮忥紝IST涓嶈兘杞繪槗鍦拌闂甀SR鐨勭紦鍐插尯錛屼負姝E鎻愪緵浜嗕竴涓姙娉曪紙鍙傝鏍囬涓衡淧assing Data between an ISR and an IST鈥濈殑甯姪鏂囨。錛夛紝鎮ㄤ篃鍙互鍒?a target="_blank">澶╂瀬緗戝祵鍏ュ紡寮鍙戣鍧?/font>璇㈤棶銆?br />
銆銆浜屻佸疄鐜扮郴緇熸椂閽?/b>
銆銆1. 緋葷粺鏃墮挓錛坰ystem tick錛夋蹇?br />
銆銆緋葷粺鏃墮挓鏄唴鏍擱渶瑕佺殑鍞竴涓柇錛圛RQ0錛夛紝緋葷粺鏃墮挓姣忔縐掍駭鐢熶竴涓腑鏂紝褰撳彂鐢熶腑鏂椂鍐呮牳鍦↖SR涓瘡璁★紝鍒?000鐨勫嶆暟灝辨槸榪囦簡涓縐掗挓銆傚湪澶勭悊緋葷粺鏃墮挓鐨処SR涓笉浠呰绱璁℃暟錛岃繕瑕佸喅瀹氭槸鍚﹂氱煡鍐呮牳寮濮嬮噸鏂拌皟搴﹀綋鍓嶆墍鏈夌殑綰跨▼銆傝瀹炵幇涓涓狾AL錛岀郴緇熸椂閽熸槸絎竴涓繀欏誨仛鐨勪簨銆?br />
銆銆2. X86騫沖彴緋葷粺鏃墮挓涓柇鐨勫鐞嗗伐浣?緋葷粺鏃墮挓鐢盜nitClock鍑芥暟璐熻矗鍒濆鍖栧伐浣滐紝涓鑸槸鍦∣EMInit鍑芥暟涓皟鐢ㄣ傚綋鍙戠敓涓柇鏃訛紝ISR棣栧厛鐢ㄤ笅鍒楄鍙ョ瘡璁¤鏁幫細CurMSec += SYSTEM_TICK_MS; /////SYSTEM_TICK_MS = 1
銆銆鐒跺悗鏍規嵁涓嬪垪璇彞鍒ゆ柇搴旇榪斿洖浠涔堝鹼細if ((int) (dwReschedTime 鈥?CurMSec) >= 0)
銆return SYSINTR_RESCHED; ///閲嶆柊璋冨害
else
銆return SYSINTR_NOP; ///涓嶅啀鎵ц浠諱綍鎿嶄綔
銆銆涓婅堪浠g爜涓叏灞鍙橀噺dwReschedTime鍦╯chedule.c涓畾涔夛紝涔熷氨鏄敱鍐呮牳鐨勮皟搴︽ā鍧楀喅瀹氬湪浣曟椂寮濮嬮噸鏂拌皟搴︾嚎紼嬨侰urMSec绱浜嗕粠WindowsCE鍚姩鍒板綋鍓嶆誨叡浜х敓浜嗗灝戜釜system tick銆傚疄鐜扮郴緇熸椂閽熷悗榪樿瀹炵幇OEMIdle鍑芥暟錛屽綋娌℃湁綰跨▼鍑嗗榪愯鏃禣EMIdle琚皟鐢紝OEMIdle鍑芥暟灝咰PU緗簬絀洪棽妯″紡錛屼絾鍦ㄧ┖闂叉ā寮忎笅浠嶇劧瑕佺瘡璁$郴緇熸椂閽熴?br />
銆銆涓夈両/O鎺у埗浠g爜
銆銆1. I/O鎺у埗浠g爜浣滅敤
銆銆搴旂敤杞歡鎴栬呴┍鍔ㄧ▼搴忓彲浠ヨ皟鐢↘ernelIoControl鍑芥暟涓嶰AL灞傞氫俊錛岃孠ernelIoControl鍦ㄥ唴閮ㄨ皟鐢∣EMIoControl鍑芥暟銆侽EMIoControl鏄竴涓狾AL API錛孫EM鍙互鍦∣EMIoControl涓紪鍐欒嚜宸辯殑I/O鎺у埗浠g爜瀹炵幇涓浜涘姛鑳斤紝鎴栬呰涓庡簲鐢ㄨ蔣浠墮氫俊銆侷/O鎺у埗浠g爜甯哥敤鐨勪緥瀛愬閲嶅惎璁$畻鏈恒佸緱鍒扮郴緇熶俊鎭佽緗甊TC銆佸緱鍒拌澶嘔D絳夈傝繕鏈変竴浜涚郴緇熺▼搴忎嬌鐢ㄧ殑鐗規畩鐨処/O鎺у埗浠g爜銆傚湪榪欓噷璇存槑涓涓嬶紝鎴戠粡榪囧疄楠岃瘉瀹濩E鎻愪緵鐨勫緱鍒拌澶嘔D鏂規硶騫墮潪鏈夋晥銆?br />
銆銆2. 緙栧啓鑷繁鐨処/O鎺у埗浠g爜姝ラ
銆銆1) 鍦╬kfuncs.h鎴栬呮柊緙栧啓涓涓?h鏂囦歡涓寜濡備笅鏍煎紡瀹氫箟錛?br />#define IOCTL_MY_CONTROL CTL_CODE(FILE_DEVICE_HAL, 3000, METHOD_NEITHER, FILE_ANY_ACCESS)
銆銆2) 鍦╫emioctl.c涓慨鏀筄EMIoControl鍑芥暟錛屾坊鍔犲涓嬩唬鐮侊細case IOCTL_MY_CONTROL:
......
銆銆3) 鍦ㄥ簲鐢ㄧ▼搴忎腑璋冪敤KernelIoControl鍑芥暟錛屽叿浣撳弬鏁板弬瑙佸府鍔╂枃妗?img src ="http://m.shnenglu.com/milkyway/aggbug/18267.html" width = "1" height = "1" />
]]>
NOR鍜孨AND鏄幇鍦ㄥ競鍦轟笂涓ょ涓昏鐨勯潪鏄撳け闂瓨鎶鏈侷ntel浜?988騫撮鍏堝紑鍙戝嚭NOR flash鎶鏈紝褰誨簳鏀瑰彉浜嗗師鍏堢敱EPROM鍜孍EPROM涓緇熷ぉ涓嬬殑灞闈€傜揣鎺ョ潃錛?989騫達紝涓滆姖鍏徃鍙戣〃浜哊AND flash緇撴瀯錛屽己璋冮檷浣庢瘡姣旂壒鐨勬垚鏈紝鏇撮珮鐨勬ц兘錛屽茍涓旇薄紓佺洏涓鏍峰彲浠ラ氳繃鎺ュ彛杞繪澗鍗囩駭銆備絾鏄粡榪囦簡鍗佸騫翠箣鍚庯紝浠嶇劧鏈夌浉褰撳鐨勭‖浠跺伐紼嬪笀鍒嗕笉娓匩OR鍜孨AND闂瓨銆?
鐩糕渇lash瀛樺偍鍣ㄢ濈粡甯稿彲浠ヤ笌鐩糕淣OR瀛樺偍鍣ㄢ濅簰鎹嬌鐢ㄣ傝澶氫笟鍐呬漢澹篃鎼炰笉娓呮NAND闂瓨鎶鏈浉瀵逛簬NOR鎶鏈殑浼樿秺涔嬪錛屽洜涓哄ぇ澶氭暟鎯呭喌涓嬮棯瀛樺彧鏄敤鏉ュ瓨鍌ㄥ皯閲忕殑浠g爜錛岃繖鏃禢OR闂瓨鏇撮傚悎涓浜涖傝孨AND鍒欐槸楂樻暟鎹瓨鍌ㄥ瘑搴︾殑鐞嗘兂瑙e喅鏂規銆?
NOR鐨勭壒鐐規槸鑺墖鍐呮墽琛?XIP, eXecute In Place)錛岃繖鏍峰簲鐢ㄧ▼搴忓彲浠ョ洿鎺ュ湪flash闂瓨鍐呰繍琛岋紝涓嶅繀鍐嶆妸浠g爜璇誨埌緋葷粺RAM涓侼OR鐨勪紶杈撴晥鐜囧緢楂橈紝鍦?锝?MB鐨勫皬瀹歸噺鏃跺叿鏈夊緢楂樼殑鎴愭湰鏁堢泭錛屼絾鏄緢浣庣殑鍐欏叆鍜屾摝闄ら熷害澶уぇ褰卞搷浜嗗畠鐨勬ц兘銆?
NAND緇撴瀯鑳芥彁渚涙瀬楂樼殑鍗曞厓瀵嗗害錛屽彲浠ヨ揪鍒伴珮瀛樺偍瀵嗗害錛屽茍涓斿啓鍏ュ拰鎿﹂櫎鐨勯熷害涔熷緢蹇傚簲鐢∟AND鐨勫洶闅懼湪浜巉lash鐨勭鐞嗗拰闇瑕佺壒孌婄殑緋葷粺鎺ュ彛銆?
鎬ц兘姣旇緝
flash闂瓨鏄潪鏄撳け瀛樺偍鍣紝鍙互瀵圭О涓哄潡鐨勫瓨鍌ㄥ櫒鍗曞厓鍧楄繘琛屾摝鍐欏拰鍐嶇紪紼嬨備換浣昮lash鍣ㄤ歡鐨勫啓鍏ユ搷浣滃彧鑳藉湪絀烘垨宸叉摝闄ょ殑鍗曞厓鍐呰繘琛岋紝鎵浠ュぇ澶氭暟鎯呭喌涓嬶紝鍦ㄨ繘琛屽啓鍏ユ搷浣滀箣鍓嶅繀欏誨厛鎵ц鎿﹂櫎銆侼AND鍣ㄤ歡鎵ц鎿﹂櫎鎿嶄綔鏄崄鍒嗙畝鍗曠殑錛岃孨OR鍒欒姹傚湪榪涜鎿﹂櫎鍓嶅厛瑕佸皢鐩爣鍧楀唴鎵鏈夌殑浣嶉兘鍐欎負0銆?
鐢變簬鎿﹂櫎NOR鍣ㄤ歡鏃舵槸浠?4锝?28KB鐨勫潡榪涜鐨勶紝鎵ц涓涓啓鍏?鎿﹂櫎鎿嶄綔鐨勬椂闂翠負5s錛屼笌姝ょ浉鍙嶏紝鎿﹂櫎NAND鍣ㄤ歡鏄互8锝?2KB鐨勫潡榪涜鐨勶紝鎵ц鐩稿悓鐨勬搷浣滄渶澶氬彧闇瑕?ms銆?
鎵ц鎿﹂櫎鏃跺潡灝哄鐨勪笉鍚岃繘涓姝ユ媺澶т簡NOR鍜孨ADN涔嬮棿鐨勬ц兘宸窛錛岀粺璁¤〃鏄庯紝瀵逛簬緇欏畾鐨勪竴濂楀啓鍏ユ搷浣?灝ゅ叾鏄洿鏂板皬鏂囦歡鏃?錛屾洿澶氱殑鎿﹂櫎鎿嶄綔蹇呴』鍦ㄥ熀浜嶯OR鐨勫崟鍏冧腑榪涜銆傝繖鏍鳳紝褰撻夋嫨瀛樺偍瑙e喅鏂規鏃訛紝璁捐甯堝繀欏繪潈琛′互涓嬬殑鍚勯」鍥犵礌銆?
鈼?NOR鐨勮閫熷害姣擭AND紼嶅揩涓浜涖?
鈼?NAND鐨勫啓鍏ラ熷害姣擭OR蹇緢澶氥?
鈼?NAND鐨?ms鎿﹂櫎閫熷害榪滄瘮NOR鐨?s蹇?
鈼?澶у鏁板啓鍏ユ搷浣滈渶瑕佸厛榪涜鎿﹂櫎鎿嶄綔銆?
鈼?NAND鐨勬摝闄ゅ崟鍏冩洿灝忥紝鐩稿簲鐨勬摝闄ょ數璺洿灝戙?
鎺ュ彛宸埆
NOR flash甯︽湁SRAM鎺ュ彛錛屾湁瓚沖鐨勫湴鍧寮曡剼鏉ュ鍧錛屽彲浠ュ緢瀹規槗鍦板瓨鍙栧叾鍐呴儴鐨勬瘡涓涓瓧鑺傘?
NAND鍣ㄤ歡浣跨敤澶嶆潅鐨処/O鍙f潵涓茶鍦板瓨鍙栨暟鎹紝鍚勪釜浜у搧鎴栧巶鍟嗙殑鏂規硶鍙兘鍚勪笉鐩稿悓銆?涓紩鑴氱敤鏉ヤ紶閫佹帶鍒躲佸湴鍧鍜屾暟鎹俊鎭?
NAND璇誨拰鍐欐搷浣滈噰鐢?12瀛楄妭鐨勫潡錛岃繖涓鐐規湁鐐瑰儚紜洏綆$悊姝ょ被鎿嶄綔錛屽緢鑷劧鍦幫紝鍩轟簬NAND鐨勫瓨鍌ㄥ櫒灝卞彲浠ュ彇浠g‖鐩樻垨鍏朵粬鍧楄澶囥?
瀹歸噺鍜屾垚鏈?
NAND flash鐨勫崟鍏冨昂瀵稿嚑涔庢槸NOR鍣ㄤ歡鐨勪竴鍗婏紝鐢變簬鐢熶駭榪囩▼鏇翠負綆鍗曪紝NAND緇撴瀯鍙互鍦ㄧ粰瀹氱殑妯″叿灝哄鍐呮彁渚涙洿楂樼殑瀹歸噺錛屼篃灝辯浉搴斿湴闄嶄綆浜嗕環鏍箋?
NOR flash鍗犳嵁浜嗗閲忎負1锝?6MB闂瓨甯傚満鐨勫ぇ閮ㄥ垎錛岃孨AND flash鍙槸鐢ㄥ湪8锝?28MB鐨勪駭鍝佸綋涓紝榪欎篃璇存槑NOR涓昏搴旂敤鍦ㄤ唬鐮佸瓨鍌ㄤ粙璐ㄤ腑錛孨AND閫傚悎浜庢暟鎹瓨鍌紝NAND鍦–ompactFlash銆丼ecure Digital銆丳C Cards鍜孧MC瀛樺偍鍗″競鍦轟笂鎵鍗犱喚棰濇渶澶с?
鍙?鎬у拰鑰愮敤鎬?
閲囩敤flahs浠嬭川鏃朵竴涓渶瑕侀噸鐐硅冭檻鐨勯棶棰樻槸鍙?鎬с傚浜庨渶瑕佹墿灞昅TBF鐨勭郴緇熸潵璇達紝Flash鏄潪甯稿悎閫傜殑瀛樺偍鏂規銆傚彲浠ヤ粠瀵垮懡(鑰愮敤鎬?銆佷綅浜ゆ崲鍜屽潖鍧楀鐞嗕笁涓柟闈㈡潵姣旇緝NOR鍜孨AND鐨勫彲*鎬с?
瀵垮懡(鑰愮敤鎬?
鍦∟AND闂瓨涓瘡涓潡鐨勬渶澶ф摝鍐欐鏁版槸涓鐧句竾嬈★紝鑰孨OR鐨勬摝鍐欐鏁版槸鍗佷竾嬈°侼AND瀛樺偍鍣ㄩ櫎浜嗗叿鏈?0姣?鐨勫潡鎿﹂櫎鍛ㄦ湡浼樺娍錛屽吀鍨嬬殑NAND鍧楀昂瀵歌姣擭OR鍣ㄤ歡灝?鍊嶏紝姣忎釜NAND瀛樺偍鍣ㄥ潡鍦ㄧ粰瀹氱殑鏃墮棿鍐呯殑鍒犻櫎嬈℃暟瑕佸皯涓浜涖?
浣嶄氦鎹?
鎵鏈塮lash鍣ㄤ歡閮藉彈浣嶄氦鎹㈢幇璞$殑鍥版壈銆傚湪鏌愪簺鎯呭喌涓?寰堝皯瑙侊紝NAND鍙戠敓鐨勬鏁拌姣擭OR澶?錛屼竴涓瘮鐗逛綅浼氬彂鐢熷弽杞垨琚姤鍛婂弽杞簡銆?
涓浣嶇殑鍙樺寲鍙兘涓嶅緢鏄庢樉錛屼絾鏄鏋滃彂鐢熷湪涓涓叧閿枃浠朵笂錛岃繖涓皬灝忕殑鏁呴殰鍙兘瀵艱嚧緋葷粺鍋滄満銆傚鏋滃彧鏄姤鍛婃湁闂錛屽璇誨嚑嬈″氨鍙兘瑙e喅浜嗐?
褰撶劧錛屽鏋滆繖涓綅鐪熺殑鏀瑰彉浜嗭紝灝卞繀欏婚噰鐢ㄩ敊璇帰嫻?閿欒鏇存(EDC/ECC)綆楁硶銆備綅鍙嶈漿鐨勯棶棰樻洿澶氳浜嶯AND闂瓨錛孨AND鐨勪緵搴斿晢寤鴻浣跨敤NAND闂瓨鐨勬椂鍊欙紝鍚屾椂浣跨敤EDC/ECC綆楁硶銆?
榪欎釜闂瀵逛簬鐢∟AND瀛樺偍澶氬獟浣撲俊鎭椂鍊掍笉鏄嚧鍛界殑銆傚綋鐒訛紝濡傛灉鐢ㄦ湰鍦板瓨鍌ㄨ澶囨潵瀛樺偍鎿嶄綔緋葷粺銆侀厤緗枃浠舵垨鍏朵粬鏁忔劅淇℃伅鏃訛紝蹇呴』浣跨敤EDC/ECC緋葷粺浠ョ‘淇濆彲*鎬с?
鍧忓潡澶勭悊
NAND鍣ㄤ歡涓殑鍧忓潡鏄殢鏈哄垎甯冪殑銆備互鍓嶄篃鏇炬湁榪囨秷闄ゅ潖鍧楃殑鍔姏錛屼絾鍙戠幇鎴愬搧鐜囧お浣庯紝浠d環澶珮錛屾牴鏈笉鍒掔畻銆?
NAND鍣ㄤ歡闇瑕佸浠嬭川榪涜鍒濆鍖栨壂鎻忎互鍙戠幇鍧忓潡錛屽茍灝嗗潖鍧楁爣璁頒負涓嶅彲鐢ㄣ傚湪宸插埗鎴愮殑鍣ㄤ歡涓紝濡傛灉閫氳繃鍙?鐨勬柟娉曚笉鑳借繘琛岃繖欏瑰鐞嗭紝灝嗗鑷撮珮鏁呴殰鐜囥?
鏄撲簬浣跨敤
鍙互闈炲父鐩存帴鍦頒嬌鐢ㄥ熀浜嶯OR鐨勯棯瀛橈紝鍙互鍍忓叾浠栧瓨鍌ㄥ櫒閭f牱榪炴帴錛屽茍鍙互鍦ㄤ笂闈㈢洿鎺ヨ繍琛屼唬鐮併?
鐢變簬闇瑕両/O鎺ュ彛錛孨AND瑕佸鏉傚緱澶氥傚悇縐峃AND鍣ㄤ歡鐨勫瓨鍙栨柟娉曞洜鍘傚鑰屽紓銆?
鍦ㄤ嬌鐢∟AND鍣ㄤ歡鏃訛紝蹇呴』鍏堝啓鍏ラ┍鍔ㄧ▼搴忥紝鎵嶈兘緇х畫鎵ц鍏朵粬鎿嶄綔銆傚悜NAND鍣ㄤ歡鍐欏叆淇℃伅闇瑕佺浉褰撶殑鎶宸э紝鍥犱負璁捐甯堢粷涓嶈兘鍚戝潖鍧楀啓鍏ワ紝榪欏氨鎰忓懗鐫鍦∟AND鍣ㄤ歡涓婅嚜濮嬭嚦緇堥兘蹇呴』榪涜铏氭嫙鏄犲皠銆?
杞歡鏀寔
褰撹璁鴻蔣浠舵敮鎸佺殑鏃跺欙紝搴旇鍖哄埆鍩烘湰鐨勮/鍐?鎿︽搷浣滃拰楂樹竴綰х殑鐢ㄤ簬紓佺洏浠跨湡鍜岄棯瀛樼鐞嗙畻娉曠殑杞歡錛屽寘鎷ц兘浼樺寲銆?
鍦∟OR鍣ㄤ歡涓婅繍琛屼唬鐮佷笉闇瑕佷換浣曠殑杞歡鏀寔錛屽湪NAND鍣ㄤ歡涓婅繘琛屽悓鏍鋒搷浣滄椂錛岄氬父闇瑕侀┍鍔ㄧ▼搴忥紝涔熷氨鏄唴瀛樻妧鏈┍鍔ㄧ▼搴?MTD)錛孨AND鍜孨OR鍣ㄤ歡鍦ㄨ繘琛屽啓鍏ュ拰鎿﹂櫎鎿嶄綔鏃墮兘闇瑕丮TD銆?
浣跨敤NOR鍣ㄤ歡鏃舵墍闇瑕佺殑MTD瑕佺浉瀵瑰皯涓浜涳紝璁稿鍘傚晢閮芥彁渚涚敤浜嶯OR鍣ㄤ歡鐨勬洿楂樼駭杞歡錛岃繖鍏朵腑鍖呮嫭M-System鐨凾rueFFS椹卞姩錛岃椹卞姩琚玏ind River System銆丮icrosoft銆丵NX Software System銆丼ymbian鍜孖ntel絳夊巶鍟嗘墍閲囩敤銆?
椹卞姩榪樼敤浜庡DiskOnChip浜у搧榪涜浠跨湡鍜孨AND闂瓨鐨勭鐞嗭紝鍖呮嫭綰犻敊銆佸潖鍧楀鐞嗗拰鎹熻楀鉤琛?img src ="http://m.shnenglu.com/milkyway/aggbug/18266.html" width = "1" height = "1" />
]]>
WINCE鐨勫唴瀛橈紙鍖呮嫭SDRAM鍙奆LASH錛夌殑閰嶇疆鍖呭惈涓や釜鏂歸潰錛氭簮浠g爜(鍖呮嫭C鍜屾眹緙?涓殑瀹氫箟,鍙婄郴緇熼厤緗枃浠禖ONFIG.BIB涓殑瀹氫箟銆傛簮浠g爜涓渶瑕佸畾涔夊唴瀛樼殑鐗╃悊鍙婅櫄鎷熷湴鍧錛屽ぇ灝忥紝騫跺垵濮嬪寲鍚嶄負OEMAddressTable鐨勭粨鏋勬暟緇勶紝浠ュ憡鐭ョ郴緇熺墿鐞嗗湴鍧涓庤櫄鎷熷湴鍧鐨勫搴斿叧緋伙紝緋葷粺鏍規嵁鍏惰緗敓鎴怣MU欏佃〃銆傝孋ONFIG.BIB涓竴鑸細灝嗗唴瀛樺畾涔夋垚涓嶅悓鐨勬錛屽悇孌電敤浣滀笉鍚岀殑鐢ㄩ斻?br />
CONFIG.BIB鏂囦歡
CONFIG.BIB鏂囦歡鍒嗕袱涓儴鍒嗭紝鎴戜滑涓旂О涔嬩負孌碉紝MEMORY孌靛拰CONFIG孌點侻EMORY孌靛畾涔夊唴瀛樼殑鍒嗙墖鏂規硶錛孋ONFIG孌靛畾涔夌郴緇熷叾瀹冪殑涓浜涘睘鎬с備互涓嬫槸涓涓狢ONFIG銆侭IB鏂囦歡MEMORY孌電殑渚嬪瓙錛?br />MEMORY
錛?鍚嶇О 璧峰鍦板潃 澶у皬 灞炴?br />RESERVED 80000000 00008000 RESERVED
DRV_GLB 80008000 00001000 RESERVED
CS8900 80010000 00030000 RESERVED
EDBG 80040000 00080000 RESERVED
NK 800C0000 00740000 RAMIMAGE
RAM 81000000 00800000 RAM
鍚嶇О鍘熷垯涓婂彲浠ュ彇浠繪剰瀛楃涓詫紝ROMIMAGE閫氳繃涓涓唴瀛樼墖鐨勫睘鎬ф潵鍒ゆ柇瀹冪殑鐢ㄩ斻俁ESERVE灞炴ц〃鏄庤鐗囧唴瀛樻槸BSP鑷繁浣跨敤鐨勶紝緋葷粺涓嶅繀鍏沖績鍏剁敤閫旓紱RAMIMAGE璇存槑瀹冩槸涓鐗囧瓨鏀綩S IMAGE鐨勫唴瀛橈紱鑰孯AM鍒欒〃紺轟簺鐗囧唴瀛樹負RAM錛岀郴緇熷彲浠ュ湪鍏朵腑鍒嗛厤絀洪棿錛岃繍琛岀▼搴忋?br />浣嗗瓨鏀綬OM鐨勮繖鐗囧唴瀛樼殑鍚嶇О錛屽嵆NK涓鑸笉瑕佹敼鍔ㄣ傚洜涓築IB鏂囦歡涓畾涔夊皢涓涓枃浠跺姞鍏ュ埌鍝釜ROM鐗囷紙WINCE鏀寔灝哛OM銆IMAGE瀛樻斁鍦ㄤ笉榪炵畫鐨勫嚑涓唴瀛樼墖涓級涓椂浼氱敤鍒拌繖涓悕縐幫紝濡備笅鐜拌繖琛孊IB鏂囦歡欏瑰氨瀹氫箟灝唗ouch.dll鏀懼湪鍚嶇О涓篘K榪欑墖ROM涓紝
touch.dll $(_FLATRELEASEDIR)\touch.dll NK SH
鍥犺岋紝濡傛灉灝哊K鏀逛負鍏跺畠鍚嶇О錛屽垯緋葷粺涓墍鏈夌殑BIB鏂囦歡涓殑榪欎釜NK涓查兘闇瑕佹敼鍔ㄣ?br />娉ㄦ剰錛氫繚璇佸悇鐗囧唴瀛樹笉瑕侀噸鍙狅紱鑰屼笖涓棿涓嶈鐣欑┖媧烇紝浠ヨ妭綰﹀唴瀛橈紱涓ょ璁懼濡傛灉涓嶈兘鍚屾椂琚姞杞斤紝灝卞簲璇ュ彧涓哄叾淇濈暀涓鐗囦粠鑰岃妭綰﹀唴瀛橈紝渚嬪錛屾湰渚嬩腑鐨凜S8950鏄負緗戝崱椹卞姩紼嬪簭淇濈暀鐨勶紝EDBG鏄負緗戝崱浣滆皟璇曪紙KITL錛夌敤鏃朵繚鐣欑殑錛岃岀郴緇熻璁℃垚榪欎袱涓▼搴忎笉浼氬悓鏃跺姞杞斤紙CS8950鍦ㄥ惎鍔ㄦ椂鍒ゆ柇濡傛灉EDBG鍦ㄨ繍琛屽氨浼氳嚜鍔ㄩ鍑猴級錛岃繖鏍蜂負榪欎袱涓┍鍔ㄧ▼搴忓悇淇濈暀涓鐗囧唴瀛樺疄鍦ㄦ氮璐硅屼笖涔熸病鏈夊繀瑕併?br />RAM鐗囧繀欏誨湪鐗╃悊涓婃槸榪炵畫鐨勶紝濡傛灉緋葷粺鐨勭墿鐞嗗唴瀛樿鍒嗘垚浜嗗嚑鐗囷紝鍒欏湪RAM鐗囧彧鑳藉0鏄庝竴鐗囷紝鍏跺畠鐨勫唴瀛樺湪鍚姩闃舵鐢監EMGetExtensionDRAM鎶ュ憡緇欑郴緇燂紝濡傛灉鏈夊浜庝竴涓殑鍐呭瓨鐗囷紝搴旇鐢∣EMEnumExtensionDRAM鎶ュ憡銆侼K鐗囧垯娌℃湁姝ら檺鍒訛紝鍙槸NK璺ㄨ秺涓や釜浠ヤ笂鐗╃悊鍐呭瓨鐗囨椂錛岀郴緇熷惎鍔ㄦ椂浼氭樉紺鴻繖涓狾S鍖呰法瓚婁簡澶氫釜鐗╃悊鍐呭瓨鐗囷紝璁や負鏄釜閿欒錛屼絾騫朵笉褰卞搷緋葷粺鐨勬墽琛屼笌紼沖畾鎬э紝鍥犱負緋葷粺鍚姩涔嬫椂渚夸細鎵撳紑MMU鑰屼嬌鐢ㄨ櫄鎷熷湴鍧錛屼粠鑰岀湅鍒拌繛緇殑鍐呭瓨絀洪棿銆傚綋鐒訛紝濡傛灉鍐呮牳鑷繁閮借鏀懼湪浜嗕袱涓唴瀛樼墖涓婏紝閭g郴緇熷簲璇ュ氨鏃犳硶鍚姩浜嗐傝屽叾瀹冧繚鐣欒搗鏉ョ殑鍐呭瓨鐗囨槸涓鑸槸緇欓┍鍔ㄧ▼搴廌MA鐢紝搴旇淇濊瘉瀹冧滑鍦ㄧ墿鐞嗕笂鐨勮繛緇э紝鍥犱負DMA鏄洿鎺ョ敤鐗╃悊鍦板潃鐨勩?br />CONFIG孌典腑浠ヤ笅鍑犱釜闇瑕佹牸澶栨敞鎰忥細
ROMSTART錛屽畠瀹氫箟ROM鐨勮搗濮嬩綅緗紝搴旇鍜孨K鐗囩殑璧峰浣嶇疆鐩稿悓銆?br />ROMSIZE錛屽畾涔塕OM鐨勫ぇ灝忥紝搴旇鍜孨K鐗囩殑澶у皬鐩稿悓銆?br />濡傛灉涓嶉渶瑕丯K銆侭IN鏂囦歡錛屽垯鍙互涓嶈榪欎袱涓箋?br />ROMWIDTH錛屽畠鍙槸瀹氫箟ROMIMAG鐢熸垚ROM鍖呮椂濡備綍緇勭粐鏂囦歡錛岃岄潪鍏跺瓧闈㈠惈涔夛細ROM鐨勫搴︼紝鎵浠ヤ竴鑸兘搴旇涓?2
COMPRESSION錛屼竴鑸畾涔変負ON錛屼互鎵撳紑鍘嬬緝鍔熻兘錛屼粠鑰屽噺灝廈IN鏂囦歡鐨勫昂瀵搞?br />AUTOSIZE錛屼竴鑸簲璇ヨ涓篛N錛屼互浣跨郴緇熷皢瀹氫箟緇橰OM浣嗘病鏈夌敤鎺夌殑鍐呭瓨褰撳仛RAM浣跨敤錛岃屾彁楂楻AM鐨勪嬌鐢ㄧ巼銆傛敞鎰忥紝濡傛灉ROM鏄疐LASH錛屽垯涓嶈兘璁句負ON錛屽洜涓篎LASH涓嶈兘褰撲綔RAM浣跨敤銆?br />ROMOFFSET錛屽畠瀹氫箟OS璧峰浣嶇疆錛堝嵆ROMSTART錛夌殑鐗╃悊鍦板潃鍜岃櫄鎷熷湴鍧鐨勫樊鍊鹼紝鏈変簺BSP涓茍娌℃湁浣跨敤榪欎釜瀹氫箟銆?br />OEMAddressTable鍙婂叾瀹?br />OEMAddressTable鐢ㄦ潵鍒濆鍖栫郴緇熶腑鍚勭璁懼鐨勮櫄鎷熷湴鍧涓庣墿鐞嗗湴鍧鐨勫鏄犲叧緋匯傚湪鎴戜嬌鐢ㄧ殑BSP涓紝瀹冩槸榪欐牱瀹氫箟騫跺垵濮嬪寲鐨勶細
typedef struct
{
ULONG ulVirtualAddress;
ULONG ulPhysicalAddress;
ULONG ulSizeInMegs;
} AddressTableStruct;
#define MEG(A) (((A - 1)>>20) + 1)
const AddressTableStruct OEMAddressTable[] =
{
{ SDRAM_VIRTUAL_MEMORY, //铏氭嫙鍦板潃
PHYSICAL_ADDR_SDRAM_MAIN, //鐗╃悊鍦板潃
MEG(SDRAM_MAIN_BLOCK_SIZE) //榪欐絀洪棿鐨勫ぇ灝忥紝浠璁?br />},
鈥︹︹︹︹︹︹︹︹?br />{
0,
0,
0
}
}錛?br />濡備緥瀛愭墍紺猴紝OEMAddressTable涓轟竴涓粨鏋勬暟緇勶紝姣忛」鐨勭涓涓垚鍛樹負铏氭嫙鍦板潃錛岀浜屼釜鎴愬憳涓哄搴旂殑鐗╃悊鍦板潃錛屾渶鍚庝竴涓垚鍛樹負璇ユ絀洪棿鐨勫ぇ灝忋傝繖涓暟緇勭殑鏈鍚庝竴欏瑰繀欏誨叏閮ㄤ負0錛屼互紺烘暣涓暟緇勭殑緇撴潫銆傚唴鏍稿惎鍔ㄦ椂浼氳鍙栬繖涓暟緇勭殑鍐呭浠ュ垵濮嬪寲MMU欏佃〃錛屽惎鐢∕MU錛屼粠灝斾嬌紼嬪簭鍙互鐢ㄨ櫄鎷熷湴鍧鏉ヨ闂澶囥傚綋鐒訛紝OEMAddressTable涓墍鐢ㄥ埌鐨勬瘡涓墿鐞嗗湴鍧鍙婅櫄鎷熷湴鍧閮介渶瑕佸湪澶存枃浠朵腑瀹氫箟錛屾瘡涓狟SP涓畾涔夎繖浜涘肩殑鏂囦歡涓嶅敖鐩稿悓錛屾墍浠ワ紝鍦ㄦ涓嶈兘璇存槑鍏蜂綋鍦ㄥ摢涓枃浠訛紝璇昏呮湅鍙嬪彲浠ュ弬鑰冨叿浣揃SP鐨勬枃妗e強浠g爜銆?br />
涓嶈繛緇唴瀛樼殑澶勭悊
濡傛灉鍐呭瓨鍦ㄧ墿鐞嗕笂鏄繛緇殑錛屽垯OEMAddressTable涓彧闇瑕佷竴欏瑰氨鍙互瀹屾垚瀵瑰唴瀛樼殑鍦板潃鏄犲皠銆備絾濡傛灉BSP榪愯鍦⊿DRAM鐗╃悊涓婁笉榪炵畫鐨勭郴緇熶笂鏃訛紝OEMAddressTable涓渶瑕佹洿澶氱殑欏規潵灝哠DRAM鏄犲皠鍒拌繛緇殑铏氭嫙鍦板潃涓婏紝褰撶劧涔熷彲浠ュ皢瀹冧滑鏄犲皠鍒頒笉榪炵畫鐨勮櫄鎷熷湴鍧涓婏紝浣嗕技涔庢病鏈夌悊鐢遍偅涔堝仛銆傝屼笖錛屽綋鍏剁墿鐞嗗湴鍧涓嶈繛緇椂緋葷粺闇瑕佸仛鏇村鐨勫伐浣溿備緥濡傦紝鎴戞湁榪欐牱涓涓郴緇燂細32M SDRAM錛?6M FLASH錛孲DRAM鍦ㄧ墿鐞嗕笂涓嶈繛緇紝琚垎鎴愪簡4涓?M鐨勫唴瀛樺潡錛屾垜鐨凷DRAM鐨勪嬌鐢ㄦ儏鍐靛涓嬪浘鎵紺猴細
CONFIG銆侭IB鏂囦歡鐨凪EMORY孌靛涓嬫墍紺猴細
MEMORY
RESERVED 80000000 00008000 RESERVED
DRV_GLB 80008000 00001000 RESERVED
CS8900 80010000 00030000 RESERVED
EDBG 80040000 00080000 RESERVED
NK 800C0000 00940000 RAMIMAGE
RAM 81800000 00800000 RAM
鍦ㄨ繖32M鐨勭┖闂翠腑錛孊SP淇濈暀浜嗗墠0x80000瀛楄妭錛屾帴涓嬫潵鏄疦K錛屽畠鍗犵敤浜?x940000瀛楄妭錛岃屼笖瀹冭法瓚婁簡涓や釜鍐呭瓨鐗?榪欎簺鍜屽叾瀹傿SP鐨勮緗兘娌℃湁澶氬ぇ宸埆,鎺ヤ笅鏉ョ湅RAM鐗?瀹冨彧鍗犵敤浜嗘渶鍚庣殑8M絀洪棿,鍓嶉潰璇磋繃錛屽湪榪欑鐗╃悊鍐呭瓨涓嶈繛緇殑緋葷粺涓紝RAM鐗囦笉鑳借法瓚婁袱涓墿鐞嗗唴瀛樺潡錛屾墍浠ュ畠琚璁℃垚鍙崰鐢ㄨ緋葷粺涓殑鏈鍚庝竴涓墿鐞嗗唴瀛樼墖錛岃屽叾瀹冧袱鐗囧垯鐢監EMEnumExtensionDRAM鍦ㄨ繍琛屾椂鍒繪姤鍛婄粰緋葷粺錛岃鍑芥暟鐨勫唴瀹瑰涓?
pMemSections[0].dwFlags=0;
pMemSections[0].dwStart=(SDRAM_VIRTUAL_MEMORY + 0x1000000);
pMemSections[0].dwLen=0x800000;
pMemSections[1].dwFlags=0;
pMemSections[1].dwStart=(SDRAM_VIRTUAL_MEMORY + 0x0A00000);
pMemSections[1].dwLen=0x600000;
return 2;
榪欐牱,緋葷粺鎵鏈夌殑鍐呭瓨閮借嬋媧?緋葷粺鍙敤鍐呭瓨灝卞彉鎴愪簡8+8+6=24M錛屽彲浠ュ皢RAM瀹氫箟涓鴻繖涓夌墖涓殑浠繪剰涓鐗囷紝鑰屽湪OEMEnumExtensionDRAM涓姤鍛婂叾瀹冧袱鐗囥備絾鎶奟AM鏀懼湪鏈鍚庝竴鐗囩墿鐞嗗唴瀛樹笂鏈変竴涓緢澶х殑濂藉錛屽嵆濡傛灉NK鍙樺ぇ錛屼緥濡傜紪璇戜竴涓狣EBUG鐗堢殑緋葷粺鏃訛紝榪欐椂錛屽彧闇瑕佸皢OEMEnumExtensionDRAM涓殑鍐呭娉ㄩ噴鎺夛紝CONFIG.BIB鏂囦歡涓嶇敤鍋氫換浣曟敼鍔紝緋葷粺灝卞彲榪愯錛屽彧鏄湪MAKEIMG鏃朵細鏈変竴涓鍛婅緋葷粺鍖呭お澶э紝鍙兘鏃犳硶榪愯錛屼絾瀹為檯涓嶄細褰卞搷緋葷粺鐨勬墽琛屼笌紼沖畾鎬э紝鍥犱負NK涔嬪悗鐨勯偅孌靛唴瀛樺茍娌℃湁琚嬌鐢紝姝eソ琚定澶х殑緋葷粺鍗犵敤錛岃繖鍦ㄨ皟璇曟椂鏋佸叾鏂逛究銆?br />鑰屽鏋滅郴緇熺墿鐞嗗唴瀛樻槸榪炵畫鐨勶紝閭e皢鍙樺緱綆鍗曠殑澶氾紝榪樹互涓婇潰鐨勮緗負渚嬶紝濡傛灉榪?2M鐨凷DRAM鏄墿鐞嗕笂榪炵畫鐨勶紝鍐呭瓨鐨勪嬌鐢ㄦ儏鍐靛氨鍙互琛ㄧず濡備笅鍥撅細
鎵鏈夎呯郴緇熷彲鐢ㄥ唴瀛橀兘鍙互瀹氫箟鍦≧AM鐗囦腑銆?br />瀵圭‖浠剁煡璇嗕簡瑙d笉澶氱殑鏈嬪弸璇鋒敞鎰忥細SDRAM鏄惁鍦ㄧ墿鐞嗕笂榪炵畫錛屼笌鎴戜滑鐨勬澘涓婃湁鍑犵墖SDRAM娌℃湁鍏崇郴錛屽簲璇ュ悜紜歡宸ョ▼甯堜簡瑙DRAM鐨勫湴鍧鍒嗗竷鎯呭喌銆?/p>
]]>
騫蟲椂澶у鎺ヨЕ鏈澶氱殑鍙兘鏄疿86騫沖彴錛屽湪榪欑緋葷粺涓婂啓紼嬪簭鍑犱箮涓嶉渶瑕佽冭檻澶闂錛屼絾ARM涓婂氨涓嶄竴鏍蜂簡錛屾渶甯歌涔熸渶瀹規槗琚拷鐣ョ殑闂鍙兘灝辨槸瀛楄妭鐨勫榻愶紝鍗充嬌鍍忔垜榪欐牱鏈夊叚涓冨勾紼嬪簭寮鍙戠粡楠岀殑鎵嶆墜涔熸椂甯擱毦浜庢彁闃詫紝鏈榪戝氨鏈変竴涓狟UG錛岃姳浜嗕竴澶╂椂闂存渶緇堝彂鐜版槸瀵歸綈寮曞彂鐨勶紝鍦ㄦ涓庡ぇ瀹跺垎浜紝浣嗘効澶у鑳藉娉ㄦ剰鍒般?br />
銆銆鎴戝湪EBOOT涓鍙栧瓨鍦℉ARD銆DISK涓婄殑nk.bin鏂囦歡錛屼粠鑰屼粠HARD銆DISK涓奓OAD銆WINCE緋葷粺錛屽湪榪欎釜榪囩▼涓繪槸鏈塩heck sum閿欒錛屼絾浠巈thernet涓嬭澆鏃朵笉浼氭湁閿欙紝鎵浠ラ棶棰樺簲璇ヨ繕鏄湪鎴戝姞鐨勮繖閮ㄥ垎浠g爜涓婏紝鑰屼笖鍚屾牱鐨勪唬鐮佸湪PC涓婅兘姝e父榪愯銆傜粡榪囨鏌ヤ唬鐮佺殑閫昏緫鍏崇郴鏄紜殑銆傛帴鐫鎴戝湪鍑洪敊鏃跺皢閭d簺鏁版嵁鍏ㄩ儴鐢ㄨ皟璇曚俊鎭墦鍑烘潵錛屽彂鐜頒粠鏂囦歡寮濮嬬畻璧風4096涓瓧鑺傝涓㈡帀浜嗭紝鑰屽叾瀹冪殑瀛楄妭閮芥槸瀵圭殑銆傚垵姝ュ垽鏂槸瀵歸綈寮曞彂鐨勯棶棰橈紝鎵浠ュ幓鏌ユ瘡涓涓狟UFFER錛屾渶緇堝彂鐜版槸鍦ㄨ鍙栫‖鐩樻暟鎹椂BUFFERR騫舵病鏈夋寜鍙屽瓧鑺傚榻愶紝鑰岀‖鐩樹互16BIT璇誨彇鏁版嵁錛岃屽紩鍙戜簡閿欒銆?br />
瀹為檯涓婏紝榪欑被闂鍦ˋRM緋葷粺涓婂緢甯歌錛岃浜洪槻涓嶈儨闃詫紝浠ヤ笅鏄垜鐨勪竴浜涗緥瀛愩?br />
1錛岃В鏋愭暟鎹祦鏃跺簲璇ユ椂鍒繪敞鎰忋傚鏋滈渶瑕佹妸涓涓暟鎹祦錛圔UFFER錛夎漿鍖栨垚緇撴瀯榪涜鍙栧鹼紝灝卞簲璇ユ妸榪欎釜緇撴瀯瀹氫箟涓烘寜瀛楄妭瀛樺彇.鑰冭檻濡備笅緇撴瀯錛?br />
struct a{
char a;
short b;
long c;
};
濡傛灉鏌愪釜鏁版嵁嫻佷腑鍖呭惈榪欐牱鐨勭粨鏋勶紝鑰屼笖鎴戜滑瑕佺洿鎺ュ皢鏁版嵁嫻佺殑鎸囬拡杞寲鎴愯緇撴瀯鐨勬寚閽堬紝鐒跺悗鐩存帴鍙栫粨鏋勬垚鍛樼殑鍊鹼紝鎴戜滑灝卞簲璇ュ皢榪欎釜緇撴瀯瀹氫箟鎴愭寜瀛楄妭璁塊棶錛屽嵆灝嗗叾澶瑰湪璇彞
#pragma pack(push,1)
...
#pragma pack(pop)
涔嬩腑銆傚鏋滄垜浠笉榪欐牱鍋氾紝緙栬瘧鍣ㄤ細灝嗘垚鍛榖鐨勫湴鍧瀵歸綈鍒皊hort鎸囬拡鐨勫湴鍧錛屽嵆鍦╝涔嬪悗鍔犱笂涓涓猚har鍗?浣嶇殑鎴愬憳錛屽皢C瀵歸綈鍒癓ONG錛屽嵆鍦˙涔嬪悗鍐嶅姞涓涓猚har鎴愬憳銆傚姝や竴鏉ワ紝鎴愬憳B鍜屾垚鍛楥灝卞緱涓嶅埌姝g‘鐨勫間簡銆?br />
濡傛灉鎴戜滑瀹氫箟涓涓櫘閫氱殑緇撴瀯鐢ㄦ潵瀛樻斁涓浜涙暟鎹紝鍒欎笉鐢ㄥ畾涔夋垚鎸夊瓧鑺傚瓨鍙栵紝緙栬瘧鍣ㄤ細鍔犱笂涓浜涘崰浣嶆垚鍛橈紝浣嗗茍涓嶄細褰卞搷紼嬪簭鐨勮繍琛屻備粠榪欎釜鎰忎箟涓婅錛屽湪ARM涓紝灝嗙粨鏋勬垚鍛樺畾涔夋垚CHAR鍜孲HORT鏉ヨ妭綰﹀唴瀛樻槸娌℃湁鎰忎箟鐨勩?br />
涓涓吀鍨嬬殑渚嬪瓙灝辨枃浠剁郴緇熺殑椹卞姩紼嬪簭錛屾枃浠舵槸浠ヤ竴浜涘凡緇忓畾涔夊ソ鐨勭粨鏋勫瓨鏀懼湪瀛樺偍浠嬭川涓婄殑錛屽畠浠璇誨彇鍒頒竴涓狟UFFER涓紝鑰屽叿浣撳彇鏌愪釜鏂囦歡銆佺洰褰曠粨鏋勬椂錛屾垜浠細灝嗗湴鍧杞寲鎴愮粨鏋勮岃鍙栧叾涓殑鍊箋?br />
2錛岃闂璁炬椂銆?br />渚嬪錛岀鐩橀┍鍔ㄩ氬父浠?6BIT鐨勬柟寮忓瓨鍙栨暟鎹紝鍗蟲瘡嬈″瓨鍙栦袱涓瓧鑺傦紝榪欐牱灝辮姹備紶緇欏畠鐨凚UFFER鏄弻瀛楄妭瀵歸綈鐨勶紝椹卞姩紼嬪簭搴旇鑷充笂灞備紶鏉ョ殑鎸囬拡鍋氬嚭姝g‘鐨勫鐞嗕互淇濊瘉鏁版嵁鐨勬紜с?br />
3.鏈夋椂錛屾垜浠病鏈夊皢鏁版嵁嫻佹寚閽堣漿鍖栦負緇撴瀯鎸囬拡鍙栧鹼紝浣嗗鏋滄垜浠鍙栫殑鏄弻瀛楄妭鎴栬呮槸鍥涘瓧鑺傜殑鏁版嵁錛屽悓鏍烽渶瑕佹敞鎰忓榻愮殑闂錛屼緥濡傦紝濡傛灉浠庝竴涓狟UFFER鐨勫亸縐?0澶勮鍙栦竴涓洓瀛楄妭鍊鹼紝鍒欏疄闄呭緱鍒扮殑鍊兼槸鍋忕Щ8澶勭殑
鍦板潃涓婄殑DWORD鍊箋?img src ="http://m.shnenglu.com/milkyway/aggbug/17844.html" width = "1" height = "1" />
]]>
涓涓父瑙佺殑鍔炴硶灝辨槸鎵ц鑿滃崟鍛戒護錛欱uild->Open Release Directory鍘繪墦寮涓涓懡浠よ紿楀彛錛岀劧鍚庡湪榪欎釜紿楀彛涓跡錛ゅ埌鎯沖埌緙栬瘧鐨勭洰褰曪紝鎵цBuild.濡傛灉瑕侀噸鏂扮紪璇戝氨榪愯Build -c,
鐒跺悗鎵懼埌鐢熸垚鐨勶激錛棘鏂囦歡錛屽皢鍏舵嫹鍒癛elease 鐩綍涓嬶紝鍐嶆墽琛宮akeimg灝辮浜嗭紟
RELEASETYPE
鎸囧畾鍙戝竷鐨勭被鍨?瀹為檯涓婂氨鏄紪璇戝悗鐨勬枃浠剁殑瀛樻斁浣嶇疆鍙夐」涓?
SDK|DDK|PLATFORM|LOCAL|CUSTOM 鍏朵綑閫夐」絳夋晥OAK
DLLENTRY|EXEENTRY|NODLLENTRY
鎸囧畾鍏ュ彛鐐?
_TGTCPUFAMILY聽
鎸囧畾澶勭悊鍣ㄦ墍灞炲鏃忓彲閫墄86|MIPS|SH|ARM
LINT_TYPE
鍙塧ll | lob | ind
TARGETEXEFILES
鎺у埗杈撳嚭鏂囦歡 鍙塏OLINK---涓嶉摼鎺?
聽
TARGETTYPE
杈撳嚭鏂囦歡鐨勭被鍨?鍙塂YNLINK|PROGRAM|LIBRARY
WINCEDEBUG
鏂囦歡鍙戝竷綾誨瀷 鍙塺etail|debug 絀?debug
CDEBUG_DEFINES
璋冭瘯緙栬瘧閫夐」 WINCE_LMEM_DEBUG|DISABLE_OPTIMIZER|WINCESHIP|WINCE_OVERRIDE_CFLAGS
TARGET_PDB_NAME
PDB鏂囦歡鍚?
WINCEPROFILE
鍙?|1
TGTCPUISANAME
澶勭悊鍣ㄥ悕縐?
緙栬瘧鍣?
x86
cxx cl386 -nologo
asm ml -nologo
-machine:iX86
SH3
cxx clsh -nologo
asm shasm
-machine:sh3
SH4
cxx clsh -nologo
asm shasm
-machine:sh4
MIPSII
cxx clmips -nologo
asm mipsasm
-machine:mips /-machine:-machine:mipsfpu
ARMV4聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 :
cxx聽clarm -nologo
asm armasm -coff
-machine:arm
ARMV4T
ARMV4I
clthumb -nologo
asm armasm -coff
-machine:thumb
聽聽聽 // Initialize default clients
聽聽聽 NewClient (KITL_SVC_DBGMSG, KITL_SVCNAME_DBGMSG, FALSE);
聽聽聽 NewClient (KITL_SVC_PPSH,聽聽 KITL_SVCNAME_PPSH,聽聽 FALSE);
聽聽聽 NewClient (KITL_SVC_KDBG,聽聽 KITL_SVCNAME_KDBG,聽聽 FALSE);
聽聽聽 return fStartKitl? StartKitl (TRUE) : TRUE;
}
榪欐浠g爜涓昏瀹屾垚涓や釜鍔ㄤ綔錛?
1.瑁呰澆鍑芥暟鎸囬拡錛屼負鍚庣畫浠g爜鐨勬墽琛岃杞藉叆鍙g偣銆?
2.娉ㄥ唽kitl瀹㈡埛绔紝榪欎簺瀹㈡埛绔疄鐜頒紶杈撳眰浠ュ悗灝辨槸鎴戜滑鎵闇瑕佺殑璋冭瘯鐣岄潰銆?
杈撳叆鍙傛暟鍐沖畾鏄惁绔嬪嵆鍚姩KITL鏈嶅姟錛屽鏋渇alse鐨勮瘽灝變粎浠呰繘琛屽垵濮嬪寲絳夊緟鍚庣畫鍔ㄤ綔浣跨敤startKitl鏉ュ惎鍔╧itl.
鎴戜滑鍐嶆潵鐪嬬湅NewClient鐨勫師鍨?
static PKITL_CLIENT NewClient (UCHAR uId, LPCSTR pszSvcName, BOOL fAlloc)
{
聽聽聽 DEBUGCHK(IS_VALID_ID(uId));
聽聽聽 DEBUGCHK (!KITLClients[uId]);
聽聽聽 if (!fAlloc) {
聽聽聽聽聽聽聽 DEBUGCHK(IS_DFLT_SVC(uId));
聽聽聽聽聽聽聽 KITLClients[uId] = &DfltClnts[uId];
聽聽聽 } else if (!(KITLClients[uId] = (PKITL_CLIENT) AllocMem (HEAP_KITLCLIENT))) {
聽聽聽聽聽聽聽 return NULL;
聽聽聽 }
聽聽聽 memset (KITLClients[uId], 0, sizeof(KITL_CLIENT));
聽聽聽 KITLClients[uId]->ServiceId = uId;
聽聽聽 strcpy (KITLClients[uId]->ServiceName, pszSvcName);
聽聽聽 return KITLClients[uId];
}
榪欎釜琚О涓篘ewClient鐨勫嚱鏁版墍瀹屾垚鐨勫姛鑳藉崄鍒嗙殑綆鍗曪紝鍏堟鏌ユ墍闇瑕佸垱寤虹殑緇撴瀯鏄惁鏄郴緇熼粯璁ゆ湇鍔℃墍闇瑕佺殑錛屽鏋滄槸鐨勮瘽灝辯洿鎺ュ皢璇ョ粨鏋勭殑鎸囬拡鎸囧悜鍏ㄥ眬緇撴瀯DfltClnts騫跺垵濮嬪寲緇撴瀯錛屽鏋滀笉鏄氨鐢寵鐩稿簲鐨勭┖闂村畬鎴愯緇撴瀯鐨勫垵濮嬪寲銆傞粯璁ょ殑鏈嶅姟鏈?KITL_SVCNAME_DBGMSG錛?KITL_SVCNAME_PPSH錛?KITL_SVCNAME_KDBG鍒嗗埆瀵瑰簲Debug淇℃伅鐨勫彂甯冮氶亾(Debug message)錛屾枃鏈帶鍒跺彴鐣岄潰(PPshell)錛屽拰鍐呮牳璋冭瘯鐣岄潰(kernel debug),鍦ㄨ繖閲屽ぇ瀹跺彲鑳戒細闂細涓轟粈涔堜笉緇熶竴浣跨敤鍥哄畾鐨勫叏灞緇撴瀯鏉ュ瓨鏀捐繖浜涙湇鍔$殑淇℃伅鍛紵鍘熷洜寰堢畝鍗曪紝鍥犱負榪欎簺"client"鍦╓indowSCE涓嬫槸鍙互娉ㄥ唽鎵╁厖鍜屾敞閿鐨勶紝榪欐牱鐢ˋllocMem鎵鍒嗛厤鐨勫唴瀛樼┖闂村湪涓嶅啀闇瑕佽繖浜涙湇鍔$殑鏃跺欏彲浠ラ噴鏀炬帀錛屽氨鍙互閬垮厤涓嶅繀瑕佺殑嫻垂銆傚彟澶朘ITLClients鏄繖鏍峰畾涔夌殑PKITL_CLIENT KITLClients[MAX_KITL_CLIENTS];鎵浠itl鎵鑳芥敞鍐岀殑client榪炲悓3涓粯璁ょ殑鏈嶅姟涓鍏辨渶澶氬彲浠ユ湁MAX_KITL_CLIENTS--128涓?
涓嬮潰緇х畫娌跨潃紼嬪簭嫻佸線涓嬬湅鍚э紝kitlInit瀹屾垚鏈鍩烘湰鐨勫垵濮嬪寲鍔ㄤ綔鍗沖彲鍚姩kitl鏈嶅姟浜嗐傚啀鐪嬩竴涓嬭繖涓嚱鏁扮殑鍘熷瀷銆?
static BOOL StartKitl (BOOL fInit)
{
聽聽聽 // KITL already started?
聽聽聽 if (!fInit && (KITLGlobalState & KITL_ST_DESKTOP_CONNECTED)) {
聽聽聽聽聽聽聽 return TRUE;
聽聽聽 }
聽聽聽 /*
聽聽聽聽 * When this function is called, the kernel hasn't yet been initialized,
聽聽聽聽 * so can't make any system calls.聽 Once the system has come up far
聽聽聽聽 * enough to handle system calls, KITLInitializeInterrupt() is called to complete
聽聽聽聽 * initialization.聽 This is indicated by the KITL_ST_MULTITHREADED flag in KITLGlobalState.
聽聽聽聽 */
聽聽聽 // Detect/initialize ethernet hardware, and return address information
聽聽聽 if (!OEMKitlInit (&Kitl))
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 // verify that the Kitl structure is initialized.
聽聽聽 if (!Kitl.pfnDecode || !Kitl.pfnEncode || !Kitl.pfnEnableInt || !Kitl.pfnRecv || !Kitl.pfnSend
聽聽聽聽聽聽聽 || !Kitl.dwPhysBuffer || !Kitl.dwPhysBufLen || !Kitl.WindowSize || !Kitl.pfnGetDevCfg || !Kitl.pfnSetHostCfg) {
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 // Validate that address is not in free RAM area - the HAL should put it in a reserved
聽聽聽 // section of memory conditional on some environment var.
聽聽聽 if ((pTOC->ulRAMStart < Kitl.dwPhysBuffer + Kitl.dwPhysBufLen)
聽聽聽聽聽聽聽 && (pTOC->ulRAMEnd > Kitl.dwPhysBuffer)) {
聽聽聽聽聽聽聽 KITLOutputDebugString("\r\n!Debug Ethernet packet buffers in free RAM area - must set IMGEBOOT=1\r\n");
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 if (Kitl.dwPhysBufLen < (DWORD) 3 * KITL_BUFFER_POOL_SIZE) {
聽聽聽聽聽聽聽 KITLOutputDebugString("\r\n!Debug Ethernet buffer size too small, must be at least 0x%x bytes (3 * WindowSize * 2 * KITL_MTU)\r\n",
聽聽聽聽聽聽聽聽聽聽聽 3 * KITL_BUFFER_POOL_SIZE);
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 KITLGlobalState |= KITL_ST_KITLSTARTED; // indicate (to kdstub) that KITL has started
聽聽聽 // If the initialized flag is already set, we are being called from the power on routine,
聽聽聽 // so reinit the HW, but not any state.
聽聽聽 if (!(KITLGlobalState & KITL_ST_ADAPTER_INITIALIZED)) {
聽聽聽聽聽聽聽 // perform the initial handshake with the desktop
聽聽聽聽聽聽聽 if (!KITLConnectToDesktop ()) {
聽聽聽聽聽聽聽聽聽聽聽 KITLOutputDebugString ("\r\n!Unable to establish KITL connection with desktop!\r\n");
聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽
聽聽聽聽聽聽聽 // Set up kernel function pointers
聽聽聽聽聽聽聽 pKITLInitializeInterrupt = KITLInitializeInterrupt;
聽聽聽聽聽聽聽 pKITLSend = KITLSend;
聽聽聽聽聽聽聽 pKITLRecv = KITLRecv;
聽聽聽聽聽聽聽 KITLGlobalState |= KITL_ST_ADAPTER_INITIALIZED;
聽聽聽聽聽聽聽 if (Kitl.dwBootFlags & KITL_FL_DBGMSG)
聽聽聽聽聽聽聽聽聽聽聽 SetKernelCommDev (KERNEL_SVC_DBGMSG, KERNEL_COMM_ETHER);
聽聽聽聽聽聽聽 if (Kitl.dwBootFlags & KITL_FL_PPSH)
聽聽聽聽聽聽聽聽聽聽聽 SetKernelCommDev (KERNEL_SVC_PPSH, KERNEL_COMM_ETHER);
聽聽聽聽聽聽聽 if (Kitl.dwBootFlags & KITL_FL_KDBG)
聽聽聽聽聽聽聽聽聽聽聽 SetKernelCommDev (KERNEL_SVC_KDBG, KERNEL_COMM_ETHER);
聽聽聽聽聽聽聽 // only perform cleanboot if it's connected at boot. Cleanboot flag is
聽聽聽聽聽聽聽 // ignored if it's started dynamically.
聽聽聽聽聽聽聽 if (fInit && (Kitl.dwBootFlags & KITL_FL_CLEANBOOT)) {
聽聽聽聽聽聽聽聽聽聽聽 extern ROMHDR *const volatile pTOC;聽聽聽聽 // Gets replaced by RomLoader with real address
聽聽聽聽聽聽聽聽聽聽聽 // just clear the magic nOEMKitlInitumber (see SC_SetCleanRebootFlag)
聽聽聽聽聽聽聽聽聽聽聽 // NOTE: We can NOT call SC_SetCleanRebootFlag here since logPtr isn't
聽聽聽聽聽聽聽聽聽聽聽 // initialized yet.
聽聽聽聽聽聽聽聽聽聽聽 ((fslog_t *)((pTOC->ulRAMFree + MemForPT) | 0x20000000))->magic1 = 0;
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 // if OEM calls KitlInit (FALSE), KITLInitializeInterrupt will
聽聽聽聽聽聽聽 // not be called in SystemStartupFuc. We need to initialize
聽聽聽聽聽聽聽 // interrupt here (when RegisterClient is called)
聽聽聽聽聽聽聽 if (fKITLcsInitialized && !InSysCall ()) {
聽聽聽聽聽聽聽聽聽聽聽 KITLInitializeInterrupt ();
聽聽聽聽聽聽聽 }
聽聽聽 }
聽聽聽 LOG (KITLGlobalState);
聽聽聽 return TRUE;
}
鍚姩浠g爜棣栧厛鍒ゆ柇鏄惁宸茬粡鍚姩kitl鏈嶅姟錛屼箣鍚庤皟鐢∣EMKitlInit錛岃鍑芥暟騫朵笉鍦╬rivate鐩綍涓嬪疄鐜幫紝閫氬父windowsCE闇瑕佺敤鎴峰畾鍒剁殑浠g爜閮芥槸榪欑緇撴瀯---MS鎻愪緵鐨勪唬鐮佹帴鍙o紝鐢ㄦ埛鑷繁瀹屾垚鐩稿簲鐨凮EM閮ㄥ垎錛岄氬父榪欎簺浠g爜閮芥槸涓庡叿浣撶殑紜歡騫沖彴鐩稿叧鐨勪唬鐮併俴itl鐨凮EM浠g爜鍦℉AL涓疄鐜幫紝閫氬父鍦╬latform\kernel\hal\.涓嬶紝榪欓儴鍒嗙殑浠g爜鎴戜滑鍏堣煩榪囷紝鐪嬪畬startkitl鐨勫叏璨屽啀鍥炶繃澶撮愪釜璇存槑銆侽EMkitlInit涓簁itl鍒濆鍖栫‖浠朵紶杈撲粙璐紝鍚屾椂鍒嗛厤鍒濆鍖栦竴浜沰itl鎵闇瑕佺殑鍏ㄥ眬緇撴瀯銆傞殢鍚巗tartkitl緇х畫媯鏌EMkitlInit鎵鍒嗛厤鍜屽垵濮嬪寲鐨凨ITL緇撴瀯鍜屽唴瀛樺尯鍩熸槸鍚︽湁鏁堝悗璁劇疆kitl鐨勫叏灞鏍囩ずKITL_ST_KITLSTARTED錛涗箣鍚庤緗粓绔湇鍔$▼搴忎互鍙婃帴鏀跺拰鍙戦佺▼搴忕殑鍏ュ彛鐐瑰悗璁劇疆鍏ㄥ眬鏍囩ずKITL_ST_ADAPTER_INITIALIZED銆傜幇鍦ㄤ紶杈撲粙璐ㄥ凡緇忓叏閮ㄥ氨緇紝閫氳繃SetKernelCommDev璁劇疆kernel閫氳繃ethernet浼犻佽皟璇曚俊鎭紝璋冭瘯杈撳叆錛屼互鍙奀ESH鎺у埗鍙般傚啀鍚庤皟鐢↘ITLInitializeInterrupt瀹屾垚涓柇鐨勫垵濮嬪寲kitl鍚姩鐨勮繃紼嬪氨緇撴潫浜嗐?
聽聽 绱ф帴鐫鎴戜滑鏉ョ湅鐪嬶紝OEMkitlInit閮介』瑕佹垜浠共浠涔堛備笅闈㈢敤SMDK2440鐨刱itl涓哄疄渚嬫潵榪涜鍒嗘瀽錛?
BOOL OEMKitlInit (PKITLTRANSPORT pKitl)
{
聽聽聽 KITLOutputDebugString ("+OEMKitlInit\n");
聽聽聽 RETAILMSG(1, (_T("+OEMKitlInit\r\n")));
聽聽聽 // try to find a transport available
聽聽聽 if (!InitEther (pKitl)
聽聽聽聽聽聽聽 && !InitParallelSerial (pKitl)) {
聽聽聽聽聽聽聽 KITLOutputDebugString ("Unable to initialize KITL Transports!\n");
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 gpKitl = pKitl;
聽聽聽 KITLOutputDebugString ("-OEMKitlInit\n");
聽聽聽 RETAILMSG(1, (_T("-OEMKitlInit\r\n")));
聽聽聽 return TRUE;
}
浜嬪疄涓婂伐浣滃緢綆鍗曪紝璋冪敤InitEther (pKitl) 鍜?!InitParallelSerial (pKitl)鍒濆鍖栫綉鍗$洿鎺ユ妸鍒濆鍖栫殑KITL鍏ㄥ眬緇撴瀯榪斿洖灝辨槸鎵鏈夌殑宸ヤ綔銆傝繖鍎跨殑InitParallelSerial鏄竴涓猟ummy姘歌繙榪斿洖false,涔熷氨鏄榪欓噷娌℃湁瀵箂erial¶llel transport榪涜鏀寔銆傜湡姝g殑宸ヤ綔閲忛泦涓湪InitEther涔嬪悗銆備簨瀹炰笂InitEther 鍜?InitParallelSerial鍙浠繪剰鐨勫疄鐜頒竴涓氨鍙互杈懼埌寤虹珛浼犺緭鐣岄潰鐨勭洰鐨?涓嬮潰錛屾垜浠戶緇湅鍚庨潰鐨勪唬鐮併?
BOOL InitEther(PKITLTRANSPORT pKitl)
{
聽聽聽 EDBG_ADAPTER adp;
聽聽聽 DWORD dwDHCPLeaseTime;
聽聽聽 DWORD dwSubnetMask;
聽聽聽 KITLOutputDebugString ("+InitEther\n");
聽聽聽 memset (&adp, 0, sizeof(adp));
聽聽聽 memset (pKitl, 0, sizeof (KITLTRANSPORT));
聽聽聽 // use existing code for ether initialization
聽聽聽 if (!OEMEthInit (&adp))
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 // we are going to completely ignore the info in bootargs and the adaptor info
聽聽聽 // returned from OEMEthInit, except MAC address. Just to prove that KITL will connect standalone
聽聽聽 // get the MAC address
聽聽聽 MyAddr.wMAC[0] = adp.Addr.wMAC[0];
聽聽聽 MyAddr.wMAC[1] = adp.Addr.wMAC[1];
聽聽聽 MyAddr.wMAC[2] = adp.Addr.wMAC[2];
聽聽聽 //MyAddr = adp.Addr;
聽聽聽
聽聽聽 CreateDeviceName(&MyAddr, pKitl->szName);
聽聽聽 KITLOutputDebugString ("Using device name: %s\n", pKitl->szName);
聽聽聽 // If we haven't been given an IP address from our loader (or if we're not using static IP), get an IP address
聽聽聽 // from a DHCP server.
聽聽聽 if (adp.Addr.dwIP)
聽聽聽 {
聽聽聽聽聽聽聽 // Static IP or we got the IP from our bootloader...
聽聽聽聽聽聽聽 MyAddr.dwIP聽聽聽聽 = adp.Addr.dwIP;
聽聽聽聽聽聽聽 dwSubnetMask聽聽聽 = 0;聽聽聽 // Don't care about subnet mask...
聽聽聽聽聽聽聽 dwDHCPLeaseTime = adp.DHCPLeaseTime;
聽聽聽 }
聽聽聽 else
聽聽聽 {
聽聽聽聽聽聽聽 // Get a DHCP address...
聽聽聽聽聽聽聽 if (!EbootGetDHCPAddr (&MyAddr, &dwSubnetMask, &dwDHCPLeaseTime))
聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽
聽聽聽 MyAddr.wPort = htons (EDBG_SVC_PORT);
聽聽聽 KITLOutputDebugString ("Device %s, IP %s, Port %d\n", pKitl->szName, inet_ntoa (MyAddr.dwIP), htons (MyAddr.wPort));
聽聽聽 // initialize KITL Ethernet transport layer
聽聽聽 if (!KitlEtherInit (&MyAddr, dwDHCPLeaseTime)) {
聽聽聽聽聽聽聽 KITLOutputDebugString ("Unable to initialize KITL Ether transport\n");
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽
聽聽聽 // fill in the blanks in KITLTRANSPORT structure.
聽聽聽 pKitl->FrmHdrSize = KitlEtherGetFrameHdrSize ();
聽聽聽 pKitl->Interrupt = (UCHAR) adp.SysIntrVal;
聽聽聽 pKitl->dwPhysBuffer = EDBG_PHYSICAL_MEMORY_START;
聽聽聽 pKitl->dwPhysBufLen = 0x20000;聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // 128K of buffer available
聽聽聽 pKitl->dwBootFlags = 0;
聽聽聽 pKitl->WindowSize = EDBG_WINDOW_SIZE;
聽聽聽 pKitl->pfnDecode = KitlEtherDecodeUDP;
聽聽聽 pKitl->pfnEncode = KitlEtherEncodeUDP;
聽聽聽 pKitl->pfnSend = EthSend;
聽聽聽 pKitl->pfnRecv = OEMEthGetFrame;
聽聽聽 pKitl->pfnEnableInt = KitlEthEnableInts;
聽聽聽 pKitl->pfnSetHostCfg = SetHostCfg;
聽聽聽 pKitl->pfnGetDevCfg = GetDevCfg;
聽聽聽 KITLOutputDebugString ("-InitEther\n");
聽聽聽 return TRUE;
}
榪欎釜鍑芥暟瀹屾垚鐨勫伐浣滀富瑕佹槸璋冪敤OEMEthInit鍒濆鍖栫綉鍗$殑鏈嶅姟紼嬪簭鍙婅幏寰楃浉搴旂殑IP鍜孧AC錛屽鏋淚P鏃犳晥鍒欑敤DHCP鍔ㄦ佽幏寰桰P.閫氳繃MAC鍊間駭鐢熶竴涓爣紺猴紝榪欎釜鏍囩ず鐢ㄦ潵緇橮B鐨処DE浣跨敤銆傚垰鎵嶇殑鎴戜滑鍦╧itlInit涓湅鍒伴櫎浜嗘鏌EMkitlInit鐨勮繑鍥炲間箣澶栬繕媯鏌ヤ簡KITL緇撴瀯錛岃緇撴瀯鐨勮繖浜涚壒寰佸兼鏄湪榪欏効璁劇疆鐨勩傚湪榪欏効鍙互鐪嬪埌pKitl->pfnDecode pKitl->pfnEncode pKitl->pfnSetHostCfg pKitl->pfnGetDevCfg 浠ュ強kitl鎵鐢ㄧ殑涓柇鍙瘋繖浜涢兘鏄疧EM浠g爜錛屼篃灝辨槸鐢ㄤ簬浼犺緭鐨勭紪鐮佸拰瑙g爜褰㈠紡浠ュ強閰嶇疆鍑芥暟閮芥槸鍙互鑷繁瀹氫箟鐨勶紝榪欐牱涓鏉ヤ篃灝辨棤鎵璋撲嬌鐢ㄤ粈涔堜紶杈撲粙璐ㄤ綔涓篕ITK
鐨則ransport浜嗭紝榪欏氨涓轟嬌鐢?394鎴栬呮槸USB榪欎竴綾葷殑浼犺緭閾捐礬涔熻兘鍏呭綋浼犺緭鐣岄潰浣滀簡鍑嗗銆?OEMEthInit鍑芥暟鏄敤浜庡垵濮嬪寲浼犺緭浠嬭川--浠ュお緗戝崱銆傝繖閮ㄥ垎浠g爜鐩存帴鏄‖浠舵帶鍒朵唬鐮侊紝鎴戜滑鏉ョ畝鍗曠殑鐪嬩竴涓嬨?
BOOL
OEMEthInit(EDBG_ADAPTER *pAdapter)
{
聽PBYTE pBaseIOAddress;
聽// Driver globals from the bootloader.
聽//
聽if (pDriverGlobals->eth.EbootMagicNum == EBOOT_MAGIC_NUM)
聽{
聽聽memcpy(pAdapter, &pDriverGlobals->eth.TargetAddr, sizeof(EDBG_ADAPTER));
聽聽switch(pDriverGlobals->misc.EbootDevice)
聽聽{
聽聽case(DOWNLOAD_DEVICE_PCMCIA):聽// NE2000 CF card.
聽聽聽pBaseIOAddress聽 = (PBYTE)PCMCIA_Init();
聽聽聽if (pBaseIOAddress)
聽聽聽{
聽聽聽聽// Initialize the built-in Ethenet controller.
聽聽聽聽//
聽聽聽聽if (!NE2000Init((PBYTE)pBaseIOAddress, 1, pAdapter->Addr.wMAC))
聽聽聽聽{
聽聽聽聽聽EdbgOutputDebugString("ERROR: OEMEthInit: Failed to initialize Ethernet controller.\r\n");
聽聽聽聽聽return(FALSE);
聽聽聽聽}
聽聽聽}
聽聽聽pfnEDbgInit聽聽聽聽聽聽聽聽聽聽 聽= NE2000Init;
聽聽聽pfnEDbgEnableInts聽聽聽聽 聽= NE2000EnableInts;
聽聽聽pfnEDbgDisableInts聽聽聽 聽= NE2000DisableInts;
聽聽聽pfnEDbgGetPendingInts 聽= NE2000GetPendingInts;
聽聽聽pfnEDbgGetFrame聽聽聽聽聽聽 聽= NE2000GetFrame;
聽聽聽pfnEDbgSendFrame聽聽聽聽聽 聽= NE2000SendFrame;
聽聽聽pfnEDbgReadEEPROM聽聽聽聽 聽= NE2000ReadEEPROM;
聽聽聽pfnEDbgWriteEEPROM聽聽聽 聽= NE2000WriteEEPROM;
聽聽聽pfnEDbgSetOptions聽聽聽聽 聽= NE2000SetOptions;
聽聽#ifdef IMGSHAREETH
聽聽聽pfnCurrentPacketFilter聽= Ne2000CurrentPacketFilter;
聽聽聽pfnMulticastList聽聽= NE2000MulticastList;
聽聽#endif聽// IMGSHAREETH.
聽聽聽break;
聽聽case(DOWNLOAD_DEVICE_CS8900):聽// CS8900A.
聽聽聽// Initialize the CS8900.
聽聽聽//
聽聽聽if (!CS8900DBG_Init((PBYTE)CS8900DBG_IOBASE, CS8900DBG_MEMBASE, pAdapter->Addr.wMAC))
聽聽聽{
聽聽聽聽EdbgOutputDebugString("ERROR: OEMEthInit: CS8900 initialization failed.\r\n");
聽聽聽聽return(FALSE);
聽聽聽}
聽聽聽pfnEDbgInit聽聽= CS8900DBG_Init;
聽聽聽pfnEDbgEnableInts聽聽聽聽 聽= CS8900DBG_EnableInts;
聽聽聽pfnEDbgDisableInts聽聽聽 聽= CS8900DBG_DisableInts;
聽聽聽pfnEDbgGetFrame聽聽= CS8900DBG_GetFrame;
聽聽聽pfnEDbgSendFrame聽= CS8900DBG_SendFrame;
聽聽聽pfnEDbgGetPendingInts 聽= CS8900DBG_GetPendingInts;
聽聽#ifdef IMGSHAREETH
聽聽聽pfnCurrentPacketFilter聽= CS8900DBG_CurrentPacketFilter;
聽聽聽pfnMulticastList聽= CS8900DBG_MulticastList;
聽聽#endif聽// IMGSHAREETH.
聽聽聽break;
聽聽default:
聽聽聽EdbgOutputDebugString("ERROR: OEMInit: Unknown download NIC (0x%x).\r\n", pDriverGlobals->misc.EbootDevice);
聽聽聽return(FALSE);
聽
聽}}
聽else
聽{
聽聽// TODO - retrieve CS8900 MAC address from flash...
聽聽// TODO - intialize the CS8900 from scratch...
聽}
聽EdbgOutputDebugString("::: OEMEthInit() IP Address : %s\r\n", inet_ntoa(pAdapter->Addr.dwIP));
聽EdbgOutputDebugString("::: OEMEthInit() Netmask聽聽聽 : %s\r\n", inet_ntoa(pDriverGlobals->eth.SubnetMask));
聽if (pDriverGlobals->misc.EbootDevice == DOWNLOAD_DEVICE_PCMCIA)
聽聽pAdapter->SysIntrVal聽聽聽 = SYSINTR_PCMCIA_LEVEL;
聽else
聽聽pAdapter->SysIntrVal聽聽聽 = SYSINTR_ETHER;
聽pAdapter->DHCPLeaseTime = DEFAULT_DHCP_LEASE;
聽pAdapter->EdbgFlags聽聽聽聽 = pDriverGlobals->eth.EdbgFlags;
聽聽
#ifdef IMGSHAREETH
聽聽聽 VBridgeInit();
聽聽聽 VBridgeKSetLocalMacAddress((char *)pAdapter->Addr.wMAC);
#endif聽// IMGSHAREETH.
聽return(TRUE);
}
聽 聽
榪欎釜鍑芥暟鐪嬭搗鏉ュ緢澶嶆潅鍏跺疄鐪熸鐨勫伐浣滃茍涓嶅錛岄鍏堝垽鏂槸涓嶆槸鐢眅boot鍚姩鐨勶紝濡傛灉宸茬粡eboot涓凡緇忓畬鎴愪簡瀵逛互澶綉鍗$殑鍒濆鍖栧姩浣滃氨鐩存帴浣跨敤緗戝崱騫惰杞?鎸傛帴緗戝崱鎵闇鐨勫嚱鏁板拰緗戝崱淇℃伅錛屽惁鍒欏氨闇瑕佽嚜宸辮緗綉鍗$殑MAC鍦板潃鍜屽垵濮嬪寲緗戝崱(浜嬪疄涓婁互涓婂嚱鏁板茍娌℃湁瀵硅繖閮ㄥ垎浠g爜榪涜瀹炵幇錛岃繖灝辨槸寰堝浣跨敤2410/2440鐨勭敤鎴峰湪涓嶄嬌鐢╡boot鍚姩鐨勬儏鍐典笅鎬繪槸涓嶈兘浣跨敤kitl鐨勫師鍥?-鎵句笉鍒癳boot鍦―riverGlobal涓暀涓嬬殑magic NUMBER)銆傝繖鍎夸箣鎵浠ユ湁NE2000鍜孋s8900鐨勫尯鍒嗘槸鍥犱負SMDK2440鍙互浣跨敤PCMICA鎸傛帴Ne2000鍏煎鐨凬IC鎴栨澘杞紺S8900錛屽悗闈㈣緗腑鏂爣紺烘湁涓や釜鍒嗘敮涔熸槸榪欎釜鍘熷洜銆?
IMGSHAREETH鐨勯儴鍒嗘槸Vbridge鐨勯儴鍒?涓轟粈涔堣浣跨敤榪欎釜鍙玽bridge鐨勪笢瑗垮憿錛熸垜浠湅鐪嬩笅闈㈢殑鍋囪銆?
涓轟簡寤虹珛kitl鍗犵敤浜嗕竴涓綉鍗¤祫婧愶紝鑰岃璧勬簮濡傛灉鍦╳indowsCE涓嬪鐢?璇ヨ澶囧悓鏃惰涓や釜椹卞姩浣跨敤1.kitl 2.windowsCE NIC driver)鐨勮瘽浼氫笉浼氬鑷撮棶棰樺憿錛熺湅鐪嬩笅闈㈢殑涓や釜鍑芥暟銆?
聽聽聽 VBridgeInit();
聽聽聽 VBridgeKSetLocalMacAddress((char *)pAdapter->Addr.wMAC);
聽聽聽 璇ュ嚱鏁板湪鍐呮牳璋冭瘯浼犺緭閫氶亾鍜宼cp/ip&windsock涔嬮棿寤虹珛涓涓櫄鎷熺殑緗戞ˉv-bridge錛屽湪澶栭儴鐪嬫潵vbridge灝卞儚鍦╩ac灞備竴鏍鳳紝vbridge涓鏂歸潰鍜岀‖浠墮氳寤虹珛浼犺緭鐨勭墿鐞嗙晫闈紝鍙︿竴鏂歸潰鍜岃皟璇曟墍闇鐨凟DBG鍜寁mini.dll鎻愪緵鐩稿悓鐨勯昏緫鐣岄潰錛屽湪鏇撮珮鐨勫眰闈mini.dll灝卞儚涓涓笓闂ㄧ殑緗戝崱涓鏍鋒敮鎸丯DIS浠ヨ嚦浜巘cp/ip鍗忚鏍堛傝繖鏍鋒垜浠氨鍙互涓鏂歸潰浣跨敤緗戝崱鍋氳皟璇曞彟澶栦竴鏂歸潰浠嶇劧鑳借windowsCE浣跨敤緗戝崱閫氳錛屽浜巜indowCE鑰岃█鎵浣跨敤鐨勭綉鍗′笉鍦ㄦ槸涓庡簳灞傚搴旂殑緗戠粶璁懼錛岃屾槸閫氳繃vbridge铏氭嫙鍑烘潵鐨勭綉緇滆澶囷紝鎵浠ュ湪鐩存帴浣跨敤SMDK24XX鐨刡sp緙栬瘧鍑烘潵鐨勭郴緇熺綉鍗℃樉紺轟負vmini灝辨槸榪欎釜鍘熷洜銆傝繖涓椂鍊欑綉鍗¢┍鍔ㄦ庝箞閰嶇疆鍛紵絳旀寰堢畝鍗曪紝灝辨槸涓嶈緗戝崱椹卞姩錛屽洜涓烘垜浠凡緇忎粠vbridge涓娊璞?铏氭嫙---鐢ㄤ竴涓綉鍗?鍑轟竴涓綉鍗′簡錛屽師鏉ョ殑緗戝崱椹卞姩涔熷氨涓嶅湪闇瑕佷簡銆?
聽聽聽
浠庝笂闈㈢殑OemKitlInit鍒癐nitEther閮芥槸OEM浠g爜錛岀洰鐨勫湪浜庝嬌Kitl涓庣浉搴旂殑transport鐨勭墿鐞嗕粙璐ㄨ仈緋昏搗鏉ワ紝涔熷氨鏄瀯寤簁itl鐨勭‖浠舵娊璞″眰錛屽湪涓涓猭itl鍒濆鍖栦唬鐮佷腑涓彧鏈夎繖閮ㄥ垎宸ヤ綔(OEM浠g爜)鏄繀瑕佺殑錛屽叾浣欑殑浠g爜鐩存帴浣跨敤MS緙栬瘧濂界殑lib灝卞彲浠ヤ簡銆傚敖綆″姝ゆ垜浠繕鏄戶緇湅涓嬮潰鐨勪唬鐮侊紝铏界劧榪欏鎴戜滑鏉ヨ涓嶆槸蹇呴』鐨勪笉榪囧涓涓▼搴忚鏈夊叏闈㈢殑璁よ瘑錛屾鏋朵笂鐨勯噸瑕佹ā鍧楅兘鏄渶瑕佷簡瑙e拰璁よ瘑鐨勩?
鐪嬪畬浜嗚繖涓緋誨垪鐨凮EM浠g爜錛岀戶緇湅鐪婼tartKitl閲岄潰鎴戜滑娌℃湁鐪嬪畬鐨勯儴鍒嗗湪璁劇疆鍚姩鏍囩ず浣嶄箣鍓嶅仛浜?涓鏌ュ垎鍒槸媯鏌uffer鐨勪綅緗槸鍚﹀湪緙栬瘧緋葷粺鐨勬椂鍊欓鐣欎笅鏉ヤ互鍙婃槸鍚︽湁瓚沖鐨勯暱搴﹀彲鐢ㄣ傝繖涓唴瀛樺尯鍩熶笉鏄姩鎬佸垎閰嶇殑錛岃屾槸鍦╞sp鐨勫唴瀛橀厤緗枃浠朵腑鎸囧畾騫朵繚鐣欎笅鏉ョ殑(瑙乥sp file鐩綍涓嬬殑config.bib)銆傚啀涓嬫潵榪涜涓涓狵ITLConnectToDesktop鐨勫姩浣滐紝榪欎釜鐪嬪悕瀛楀氨鐭ラ亾浣滅敤浜嗐傚氨鏄拰PC榪炴帴銆傚悓鏍風湅鐪嬩唬鐮侊細
static BOOL KITLConnectToDesktop (void)
{
聽聽聽 // we'll use the PpfsFmtBuf for send buffer since ppfs can't be started yet at this stage
聽聽聽 //
聽聽聽 PKITL_HDR pHdr = (PKITL_HDR) (PpfsFmtBuf + Kitl.FrmHdrSize);
聽聽聽 PKITL_DEV_TRANSCFG pCfg = (PKITL_DEV_TRANSCFG) KITLDATA(pHdr);
聽聽聽 USHORT cbData = sizeof (PpfsFmtBuf) - Kitl.FrmHdrSize - sizeof (KITL_HDR) - sizeof (KITL_DEV_TRANSCFG);
聽聽聽 if (!Kitl.pfnGetDevCfg ((LPBYTE) (pCfg+1), &cbData))
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 memset (pHdr, 0, sizeof (KITL_HDR));
聽聽聽 pHdr->Id = KITL_ID;
聽聽聽 pHdr->Service = KITL_SVC_ADMIN;
聽聽聽 pHdr->Cmd = KITL_CMD_TRAN_CONFIG;
聽聽聽 cbData += sizeof (KITL_DEV_TRANSCFG);
聽聽聽 pCfg->wLen = cbData;
聽聽聽 pCfg->wCpuId = KITL_CPUID;
聽聽聽 memcpy (pCfg->szDevName, Kitl.szName, KITL_MAX_DEV_NAMELEN);
聽聽聽 cbData += sizeof (KITL_HDR);
聽聽聽 return KitlSendFrame (PpfsFmtBuf, cbData)
聽聽聽聽聽聽聽 && KITLPollResponse (FALSE, ChkCnxDsktp, TranCnxDsktp, (LPVOID) cbData);
}
緇撴瀯PKITL_HDR灝辨槸kilt鐨勪紶杈撳ご鏍煎紡錛岃孭KITL_DEV_TRANSCFG淇℃伅鍒欐槸浼犺緭璁懼鐨勮緗傞鍏堥氳繃璋冪敤Kitl.pfnGetDevCfg寰楀埌浼犺緭璁懼鐨勪俊鎭紝Kitl.pfnGetDevCfg鏄嚱鏁版寚閽堬紝鍦ㄥ浠ュお緗戝崱鍒濆鍖栫殑鏃跺欐寚鍚慜EM浠g爜涓殑GetDevCfg鍑芥暟銆傞氳繃榪欎釜鍑芥暟寰楀埌璁懼淇℃伅(smdk2410鐨刡sp涓繖鍎胯繑鍥炵殑灝辨槸IP鍦板潃)銆傜劧鍚庡啀緇х畫璁劇疆浼犺緭澶寸殑鏍囩ず錛岀被鍨嬶紝鍛戒護絳夌瓑淇℃伅錛岀劧鍚庡氨鏄彂閫佹暟鎹簡錛屽叿浣撶殑鍔ㄤ綔灝辨槸璋冪敤KitlSendFrame銆?To be continue...)
BOOL KitlSendFrame (LPBYTE pbFrame, WORD cbData)
{
聽聽聽 if (!Kitl.pfnEncode (pbFrame, cbData)) {
聽聽聽聽聽聽聽 KITLOutputDebugString ("!KitlSendFrame: transport failed to encode the data frame\r\n");
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 return KitlSendRawData (pbFrame, (USHORT) (cbData + Kitl.FrmHdrSize + Kitl.FrmTlrSize));
}
榪欎釜鍑芥暟棣栧厛璋冪敤KitlEtherEncodeUDP瀵規暟鎹撫榪涜緙栫爜涓篣DP鍗忚闇瑕佺殑鏍煎紡銆傜劧鍚庤皟鐢?KitlSendRawData灝嗘暟鎹佸嚭鑷砅C.
BOOL KitlSendRawData (LPBYTE pbData, WORD wLength)
{
聽聽聽 BOOL fRet;
聽聽聽 if (!(KITLGlobalState & KITL_ST_MULTITHREADED) || InSysCall())
聽聽聽聽聽聽聽 fRet = Kitl.pfnSend (pbData, wLength);
聽聽聽 else if (IsDesktopDbgrExist ())
聽聽聽聽聽聽聽 fRet = KCall((PKFN) Kitl.pfnSend, pbData, wLength);
聽聽聽 else {
聽聽聽聽聽聽聽 EnterCriticalSection (&KITLKCallcs);
聽聽聽聽聽聽聽 fRet = Kitl.pfnSend (pbData, wLength);
聽聽聽聽聽聽聽 LeaveCriticalSection (&KITLKCallcs);
聽聽聽 }
聽聽聽 return fRet;
}
棣栧厛鍒ゅ畾緋葷粺娌℃湁鍦ㄨ皟搴︿腑涓斿綋鍓嶄唬鐮佸湪涓嶅彲鍓ュず鐘舵佺姸鎬佽繍琛岋紝閫氳繃EthSend璋冪敤OEMEthSendFrame灝嗘暟鎹佸嚭灝卞畬鎴愪簡宸ヤ綔銆傚彟澶栦袱涓垎鏀笌鎴戜滑鍒嗘瀽鐨勭▼搴忔祦娌℃湁鍏崇郴鍏堟斁涓涓嬨?
BOOL
OEMEthSendFrame(
聽聽聽 BYTE *pData,聽聽聽聽 // IN - Data buffer
聽聽聽 DWORD dwLength)聽 // IN - Length of buffer
{
聽聽聽 int retries = 0;
聽聽聽 while (retries++ < 4) {
聽聽聽聽聽聽聽 if (!pfnEDbgSendFrame(pData, dwLength))
聽聽{
#ifdef IMGSHAREETH
聽聽聽ProcessVMiniSend();
#endif //IMGSHAREETH
聽聽聽聽聽聽聽聽聽聽聽 return TRUE;
聽聽}
聽聽聽聽聽聽聽 else
聽聽聽聽聽聽聽聽聽聽聽 EdbgOutputDebugString("!OEMEthSendFrame failure, retry %u\n",retries);
聽聽聽 }
聽聽聽 return FALSE;
}
鍦ㄥ彂閫佹暟鎹撫鐨勮繃紼嬩腑涓撻棬鏈夊鐞唙Mini鍙戦佺殑榪囩▼銆傜敱浜巏itl鏈韓灝變笉鏄緢綆鍗曟垜浠互鍚庡悗闈㈠啀鐢ㄤ笓闂ㄧ殑鏂囩珷璇存槑vbridge鐨勫伐浣滆繃紼嬨傚畬鎴愪簡鍙戦侊紝鎴戜滑緇х畫涓嬮潰鐨勮繃紼嬨?
BOOL KITLPollResponse (BOOL fUseSysCalls, PFN_CHECK pfnCheck, PFN_TRANSMIT pfnTransmit, LPVOID pData)
{
聽聽聽 DWORD dwLoopCnt = 0, dwLoopMax = MIN_POLL_ITER;
聽聽聽 DWORD dwStartTime = CurMSec;
聽聽聽 int聽聽 nTimeMax = MIN_POLL_TIME;聽 // start with 1 sec
聽聽聽 BOOL聽 fUseIter = FALSE, fUseTick = FALSE;
聽聽聽 while (!pfnCheck (pData)) {
聽聽聽聽聽聽聽 //
聽聽聽聽聽聽聽 // if we've already connected with desktop, use the desktop
聽聽聽聽聽聽聽 // "Retransmit" package to determine if we need to retransmit
聽聽聽聽聽聽聽 //
聽聽聽聽聽聽聽 if (!(KITLGlobalState & KITL_ST_DESKTOP_CONNECTED)) {
聽聽聽聽聽聽聽聽聽聽聽 if (fUseTick) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if ((int) (CurMSec - dwStartTime) > nTimeMax) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // retransmit
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (!pfnTransmit (pData, fUseSysCalls))
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 dwStartTime = CurMSec;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (nTimeMax < MAX_POLL_TIME)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 nTimeMax <<= 1;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 } else if (fUseIter || (dwStartTime == CurMSec)) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // if time isn't moving for a while, we'll
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // use iteration.
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (dwLoopCnt ++ > dwLoopMax) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (!pfnTransmit (pData, fUseSysCalls))
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (dwLoopMax < MAX_POLL_ITER)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 dwLoopMax <<= 1;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 dwLoopCnt = 0;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 fUseIter = TRUE;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 } else {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // time is moving, just use tick from here
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 fUseTick = TRUE;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 if (!KITLPollData(fUseSysCalls, pfnTransmit, pData)) {
聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽 }
聽聽聽 }
聽聽聽 return TRUE;
}
static BOOL TranCnxDsktp (LPVOID pParam, BOOL fUseSysCalls)
{
聽聽聽 return KitlSendFrame (PpfsFmtBuf, (WORD) (DWORD) pParam);
}
榪欎釜鍑芥暟鐨勪富浣撴槸涓涓驚鐜紝緇堟鐨勬潯浠舵槸!pfnCheck (pData)錛岃繖涓嚱鏁版槸鐢卞墠闈紶閫掕繘鏉ョ殑錛岃繑鍥炲間負KITLGlobalState & KITL_ST_DESKTOP_CONNECTED錛屼篃灝辨槸璇村湪寰楀埌妗岄潰榪炴帴涔嬪墠鏄笉浼氳繑鍥炵殑涔熷氨鏄鍚姩kitl浠ュ悗涓嶄笌妗岄潰璁$畻鏈鴻繛鎺indowsCE鐨勬槸鏃犳硶鍚姩鐨勩傜敱浜庝粠dwStartTime瀹氫箟鍒癲wStartTime == CurMSec鐨勫垽瀹氫粎浠呴渶瑕佸緢灝戠殑鏃墮棿灝卞彲浠ュ畬鎴愯繖孌墊椂闂村唴CurMSec鏄笉浼氳鏀瑰啓鐨勫氨鍙互閫氳繃寰幆榪涜瓚呮椂媯鏌?
騫墮氳繃TranCnxDsktp閲嶆柊鍙戦佹暟鎹紝鐩村埌KITLPollData璁劇疆KITLGlobalState銆?
static BOOL KITLPollData(BOOL fUseSysCalls, PFN_TRANSMIT pfnTransmit, LPVOID pData)
{
聽聽聽 LPBYTE pRecvBuf = PollRecvBuf;
聽聽聽
聽聽聽 if (fUseSysCalls && (KITLGlobalState & KITL_ST_MULTITHREADED)
聽聽聽聽聽聽聽 && !(pRecvBuf = _alloca(KITL_MTU))) {
聽聽聽聽聽聽聽 KITLOutputDebugString("!KITLPollData: STACK OVERFLOW!\r\n");
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 HandleRecvInterrupt(pRecvBuf, fUseSysCalls, pfnTransmit, pData);
聽聽聽 return TRUE;
}
鐢變簬鎴戜滑涓婇潰浼犳潵鐨刦UseSysCalls鍙傛暟涓篺alse鎵浠ュ墠涓孌墊鏌ユ搷浣滃茍涓嶈繘琛屻傜洿鎺ヨ皟鐢?HandleRecvInterrupt銆?
void HandleRecvInterrupt(UCHAR *pRecvBuf, BOOL fUseSysCalls, PFN_TRANSMIT pfnTransmit, LPVOID pData)
{
聽聽聽 WORD wLen = KITL_MTU;
聽聽聽 BOOL fFrameRecvd;
聽聽聽 // Receive data into buffer
聽聽聽 do {
聽聽聽聽聽聽聽 if (!fUseSysCalls)
聽聽聽聽聽聽聽聽聽聽聽 fFrameRecvd = Kitl.pfnRecv (pRecvBuf, &wLen);
聽聽聽聽聽聽聽 else if (IsDesktopDbgrExist ())
聽聽聽聽聽聽聽聽聽聽聽 fFrameRecvd = KCall((PKFN) Kitl.pfnRecv, pRecvBuf, &wLen);
聽聽聽聽聽聽聽 else {
聽聽聽聽聽聽聽聽聽聽聽 EnterCriticalSection (&KITLKCallcs);
聽聽聽聽聽聽聽聽聽聽聽 fFrameRecvd = Kitl.pfnRecv (pRecvBuf, &wLen);
聽聽聽聽聽聽聽聽聽聽聽 LeaveCriticalSection (&KITLKCallcs);
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 if (fFrameRecvd) {
聽聽聽聽聽聽聽聽聽聽聽 ProcessRecvFrame (pRecvBuf,wLen,fUseSysCalls, pfnTransmit, pData);
聽聽聽聽聽聽聽聽聽聽聽 wLen = KITL_MTU;
聽聽聽聽聽聽聽 }
聽聽聽 } while (fFrameRecvd);
}
閫氳繃Kitl.pfnRecv璋冪敤pfnEDbgGetFrame鎸囧悜鐨凜S8900DBG_GetFrame璇誨彇褰撳墠鐨勬暟鎹撫閫佷氦ProcessRecvFrame澶勭悊銆傛敞鎰忥紝榪欏効鐨刾fnEDbgGetFrame騫朵笉鏄氳繃DMA鎴栬呮槸緗戝崱浼犳潵鐨勪腑鏂惎鍔ㄧ殑鑰屾槸浣跨敤鏌ヨ鐨勬柟娉曡繘琛岀殑錛岃繖灝辨槸涓轟粈涔堣繖鍎垮茍娌℃湁鍚姩涓柇浠嶇劧鑳藉浣跨敤浠ュお緗戝崱榪涜鏁版嵁浼犺緭鏁版嵁鐨勫師鍥犮傞殢鍚庯紝鎴戜滑灝嗚綆楁満绔佹潵鐨勬暟鎹佷氦ProcessRecvFrame澶勭悊銆?
static BOOL ProcessRecvFrame(UCHAR *pFrame, WORD wMsgLen, BOOL fUseSysCalls, PFN_TRANSMIT pfnTransmit, LPVOID pData)
{
聽聽聽 KITL_HDR *pMsg;
聽聽聽 KITL_CLIENT *pClient = NULL;
聽聽聽 BOOL fRet = TRUE;
聽聽聽 UCHAR RxBufOffset;
聽聽聽 WORD聽 wDataLen;
聽聽聽 UCHAR ClientIdx;
聽聽聽 // let the transport layer decode the frame
聽聽聽 if (!(pMsg = (KITL_HDR *) Kitl.pfnDecode (pFrame, &wMsgLen))) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_RECV, ("ProcessRecvFrame: Received Unhandled frame\n"));
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 // is it a valid KITL message?
聽聽聽 if (pMsg->Id != KITL_ID) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("KITL: Got unrecognized Id: %X\r\n",pMsg->Id));
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽
聽聽聽 // Validate length
聽聽聽 if (wMsgLen < KITL_DATA_OFFSET) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("KITL: Invalid length %u\n",wMsgLen));
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 if (KITLDebugZone & ZONE_FRAMEDUMP)
聽聽聽聽聽聽聽 KITLDecodeFrame("<<KITLRecv",pMsg, wMsgLen);
聽聽聽
聽聽聽 // Check for administrative messages
聽聽聽 if (pMsg->Service == KITL_SVC_ADMIN)
聽聽聽聽聽聽聽 return ProcessAdminMsg(pMsg, wMsgLen, fUseSysCalls, pfnTransmit, pData);
聽聽聽 // Service Id is index into KITLClients array
聽聽聽 ClientIdx = pMsg->Service;
聽聽聽 if (ClientIdx >= MAX_KITL_CLIENTS) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!ProcessKITLMsg: Invalid ServiceId: %u\n",pMsg->Service));
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 pClient = KITLClients[ClientIdx];
聽聽聽
聽聽聽 // Until we complete registering, only handle administrative messages
聽聽聽 if (!pClient || !(pClient->State & KITL_CLIENT_REGISTERED)) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!ProcessKITLMsg: Client %u not registered\n",ClientIdx));
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 if (pMsg->Service != pClient->ServiceId) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!ProcessKITLMsg: Mismatch in service Id for Client %u (Got %u, expect %u)\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->Service,pClient->ServiceId));
聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 if (pClient->State & KITL_USE_SYSCALLS) {
聽聽聽聽聽聽聽 if (fUseSysCalls)聽
聽聽聽聽聽聽聽聽聽聽聽 EnterCriticalSection(&pClient->ClientCS);
聽聽聽聽聽聽聽 else if (pClient->ClientCS.OwnerThread) {
聽聽聽聽聽聽聽聽聽聽聽 // We can't get the client CS, and it is owned - just toss frame
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!KITL(%u) tossing msg %u (Can't get CS)\n",ClientIdx, pMsg->SeqNum));
聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽 }
聽聽聽 }
聽聽聽 // we've being in sync with the desktop
聽聽聽 pClient->State |= KITL_SYNCED;
聽聽聽
聽聽聽 // Put flags and seq # to LEDs
聽聽聽 KITL_DEBUGLED(LED_PEM_SEQ, ((DWORD) pMsg->Flags << 24) | pMsg->SeqNum);
聽聽聽
聽聽聽 // OK, valid message, see if it's an ACK
聽聽聽 if (pMsg->Flags & KITL_FL_ACK) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_RECV,("KITL(%u): Received ack for msg %u, Tx window: %u,%u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->SeqNum, pClient->AckExpected,pClient->TxSeqNum));
聽聽聽聽聽聽聽 // ACKs acknowledge all data up to the ACK sequence #
聽聽聽聽聽聽聽 while (SEQ_BETWEEN(pClient->AckExpected, pMsg->SeqNum, pClient->TxSeqNum)) {聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽 if ((pClient->State & KITL_USE_SYSCALLS) &&
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ((pClient->CfgFlags & KITL_CFGFL_STOP_AND_WAIT) ||
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 (SEQ_DELTA(pClient->AckExpected, pClient->TxSeqNum) >= pClient->WindowSize-1) ||
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 !(KITLGlobalState & KITL_ST_INT_ENABLED))) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (fUseSysCalls)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SetClientEvent(pClient,pClient->evTxFull);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 else {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // Can't process message at this time...
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!KITL(%u): Tossing ACK %u (Can't set event)\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx, pMsg->SeqNum));
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 // Stop retransmission timer.
聽聽聽聽聽聽聽聽聽聽聽 TimerStop(pClient, (UCHAR)(pClient->AckExpected % pClient->WindowSize),fUseSysCalls);
聽聽聽聽聽聽聽聽聽聽聽 SEQ_INC(pClient->AckExpected);
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 goto ProcessKITLMsg_exit;
聽聽聽 }
聽聽聽 // Handle NACKs - retransmit requested frame if it is in our Tx window
聽聽聽 if (pMsg->Flags & KITL_FL_NACK) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("KITL(%u): Received NACK for msg %u, Tx window: %u,%u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->SeqNum, pClient->AckExpected,pClient->TxSeqNum));
聽聽聽聽聽聽聽 if (SEQ_BETWEEN(pClient->AckExpected, pMsg->SeqNum, pClient->TxSeqNum)) {
聽聽聽聽聽聽聽聽聽聽聽 UCHAR Index = pMsg->SeqNum % pClient->WindowSize;
聽聽聽聽聽聽聽聽聽聽聽 if (pClient->TxFrameLen[Index]) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // Restart retransmission timer (note we can't start timers if syscalls
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // are disabled, but this shouldn't screw us up, we'll just potentially
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // retransmit an extra frame if the timer fires before we get the ACK)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (fUseSysCalls)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 TimerStop(pClient,Index,fUseSysCalls);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 RetransmitFrame(pClient, Index, fUseSysCalls);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (fUseSysCalls)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 TimerStart(pClient,Index,KITL_RETRANSMIT_INTERVAL_MS,fUseSysCalls);
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 else
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!KITL(%u): NACK in window, but TxFrameLen empty!\n",ClientIdx));
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 else
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!KITL(%u): Received NACK outside of TX window: Seq: %u, Window: %u,%u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->SeqNum,pClient->AckExpected,pClient->TxSeqNum));
聽聽聽聽聽聽聽 goto ProcessKITLMsg_exit;
聽聽聽 }
聽聽聽
聽聽聽 // Data frame.聽 Place in appropriate slot in Rx buffer pool. Note that we defer acking
聽聽聽 // received frames until they are read from the buffer, in KITLRecv.
聽聽聽 RxBufOffset = pMsg->SeqNum % pClient->WindowSize;
聽聽聽 if (! SEQ_BETWEEN(pClient->RxSeqNum, pMsg->SeqNum, pClient->RxWinEnd)) {
聽聽聽聽聽聽聽 UCHAR uLastACK = (UCHAR) (pClient->RxWinEnd - pClient->WindowSize - 1);
聽聽聽聽聽聽聽 KITL_DEBUGMSG (ZONE_WARNING, ("KITL(%u): Received msg outside window: Seq:%u, Win:%u,%u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->SeqNum,pClient->RxSeqNum,pClient->RxWinEnd));
聽聽聽聽聽聽聽 // Special case to handle lost ACKs - if an ack is dropped, our Rx window will have
聽聽聽聽聽聽聽 // advanced beyond the seq # of the retransmitted frame.聽 Since ACKs ack all messages
聽聽聽聽聽聽聽 // up to the ack #, we only need to check the last frame.
聽聽聽聽聽聽聽 if (pMsg->SeqNum == uLastACK) {
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("KITL(%u): Lost ACK (seq: %u, win: %u,%u)\n",ClientIdx,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 pMsg->SeqNum,uLastACK,pClient->RxWinEnd));
聽聽聽聽聽聽聽聽聽聽聽 SendAckNack (TRUE, pClient, uLastACK);
聽聽聽聽聽聽聽 }
聽聽聽 } else if (pClient->RxFrameLen[RxBufOffset] != 0) {
聽聽聽聽聽聽聽 // If all our buffers are full, toss frame (will be acked when data is read in KITLRecv)
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("KITL(%u): Received duplicate (Seq:%u), slot %u already full. Win: %u,%u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->SeqNum,RxBufOffset,pClient->RxSeqNum,pClient->RxWinEnd));
聽聽聽 } else {
聽聽聽聽聽聽聽 DWORD OldProcPerms;
聽聽聽聽聽聽聽 // If we're in non-preemptible mode, can't set the receive event, so just toss message
聽聽聽聽聽聽聽 // and wait for retry.
聽聽聽聽聽聽聽 if (!fUseSysCalls && (pClient->State & KITL_USE_SYSCALLS)) {
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("KITL(%u): Tossing frame %u (Can't signal Rx event)\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->SeqNum));
聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_RECV,("KITL(%u): Received frame Seq: %u, len: %u, putting in slot %u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx, pMsg->SeqNum, wMsgLen, RxBufOffset));
聽聽聽聽聽聽聽 // If frames were dropped, send NACK (only allow one outstanding NACK)
聽聽聽聽聽聽聽 if (pMsg->SeqNum != pClient->RxSeqNum) {
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!KITL(%u): Dropped frame (seq: %u, win: %u,%u)\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ClientIdx,pMsg->SeqNum,pClient->RxSeqNum, pClient->RxWinEnd));
聽聽聽聽聽聽聽聽聽聽聽 if (!(pClient->State & KITL_NACK_SENT)) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SendAckNack(FALSE, pClient, pClient->RxSeqNum);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 pClient->State |= KITL_NACK_SENT;聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 else
聽聽聽聽聽聽聽聽聽聽聽 pClient->State &= ~KITL_NACK_SENT;
聽聽聽聽聽聽聽
聽聽聽聽聽聽聽 // Copy data to receive buffer, unblock anyone waiting, and close receive window
聽聽聽聽聽聽聽 wDataLen = wMsgLen - (WORD)KITL_DATA_OFFSET;
聽聽聽聽聽聽聽 if (wDataLen == 0)
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!KITL: Received data message with 0 length!\n"));
聽聽聽聽聽聽聽 if (pClient->ProcPerms) {
聽聽聽聽聽聽聽聽聽聽聽 // acquire permission of pClient and add it to current thread
聽聽聽聽聽聽聽聽聽聽聽 ACCESSKEY aKey = GETCURKEY() | pClient->ProcPerms;
聽聽聽聽聽聽聽聽聽聽聽 SWITCHKEY (OldProcPerms, aKey);
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 memcpy(pClient->pRxBufferPool + RxBufOffset*KITL_MTU,KITLDATA(pMsg), wDataLen);
聽聽聽聽聽聽聽 if (pClient->ProcPerms) {
聽聽聽聽聽聽聽聽聽聽聽 SETCURKEY (OldProcPerms);聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 pClient->RxFrameLen[RxBufOffset] = wDataLen;
聽聽聽聽聽聽聽 if (pClient->State & KITL_USE_SYSCALLS)
聽聽聽聽聽聽聽聽聽聽聽 // If we get here, we know that fUseSysCalls is TRUE
聽聽聽聽聽聽聽聽聽聽聽 SetClientEvent(pClient,pClient->evRecv);
聽聽聽聽聽聽聽
聽聽聽聽聽聽聽 // Close receive window
聽聽聽聽聽聽聽 while (pClient->RxFrameLen[pClient->RxSeqNum % pClient->WindowSize] &&
聽聽聽聽聽聽聽聽聽聽聽聽聽聽 (SEQ_DELTA(pClient->RxSeqNum, pClient->RxWinEnd) >= 1)) {
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_RECV,("Rx win: %u,%u, usesyscalls: %u\n",pClient->RxSeqNum, pClient->RxWinEnd, fUseSysCalls));
聽聽聽聽聽聽聽聽聽聽聽 SEQ_INC(pClient->RxSeqNum);
聽聽聽聽聽聽聽 }
聽聽聽 }
聽聽聽
ProcessKITLMsg_exit:
聽聽聽 if (fUseSysCalls && (pClient->State & KITL_USE_SYSCALLS))
聽聽聽聽聽聽聽 LeaveCriticalSection(&pClient->ClientCS);
聽聽聽
聽聽聽 return fRet;
}
ProcessRecvFramed鏄竴涓繎200琛岀殑鍑芥暟錛屾牱瀛愬緢鍚撲漢銆傚畠鏄暟鎹撫鐨勮В鏋愬拰澶勭悊妯″潡鐨勪富浣撱傛垜浠粠涓婂埌涓嬬湅鐪嬮兘騫蹭簡浜涗粈涔堛傚厛璋冪敤KitlEtherDecodeUDP灝嗘潵鑷富鏈虹殑鏁版嵁甯цВ鐮佷負KITL_HDR緇撴瀯錛岀劧鍚庢晥楠岄瓟娉曟暟KITL_ID錛岀‘璁よ甯х殑淇℃伅鐨勬湁鏁堟т互鍙婃暟鎹暱搴︽槸鍚︽湁鏁堬紝濡傛灉ZONE_FRAMEDUMP鏍囩鏄墦寮鐨勫垯闇瑕佸垯瑙f瀽Frame鐨勫唴瀹瑰茍璁板綍涓嬫潵(杈撳嚭鍒拌皟璇曠晫闈紝鍒濆鍖栨祦紼嬪茍涓嶅寘鍚淇℃伅)錛岀劧鍚庡垽瀹氳鏁版嵁甯ф弿榪扮殑淇℃伅鏄惁灞炰簬綆$悊鍛戒護(榪炴帴妗岄潰錛屾柊寤篶lient絳夌瓑),濡傛灉鏄垯璋冪敤ProcessAdminMsg榪涜澶勭悊銆?
static BOOL ProcessAdminMsg(KITL_HDR *pHdr, WORD wMsgLen, BOOL fUseSysCalls, PFN_TRANSMIT pfnTransmit, LPVOID pData)
{
聽聽聽 KITL_CLIENT *pClient = NULL;聽聽聽
聽聽聽
聽聽聽 switch (pHdr->Cmd)
聽聽聽 {
聽聽聽聽聽聽聽 case KITL_CMD_SVC_CONFIG:
聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽聽聽聽聽 KITL_SVC_CONFIG_DATA *pCfg = (KITL_SVC_CONFIG_DATA *) KITLDATA (pHdr);
聽聽聽聽聽聽聽聽聽聽聽 int i, iStart;
聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽 if (wMsgLen != (KITL_DATA_OFFSET + sizeof(KITL_SVC_CONFIG_DATA))) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!ProcessAdminMsg: Invalid legnth for CONFIG msg: %u\n",wMsgLen));
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 // Find client struct
聽聽聽聽聽聽聽聽聽聽聽 if ((i = ChkDfltSvc (pCfg->ServiceName)) < 0)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 i = HASH(pCfg->ServiceName[0]);
聽聽聽聽聽聽聽聽聽聽聽 iStart = i;
聽聽聽聽聽聽聽聽聽聽聽 while (KITLClients[i]) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // For multi instanced services, skip clients that are already registered
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (!strcmp(KITLClients[i]->ServiceName,pCfg->ServiceName) &&
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 (!(KITLClients[i]->State & KITL_CLIENT_REGISTERED) || !(KITLClients[i]->CfgFlags & KITL_CFGFL_MULTIINST))) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 pClient = KITLClients[i];
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (i < NUM_DFLT_KITL_SERVICES)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // no dups for default services
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (MAX_KITL_CLIENTS == ++ i)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 i = NUM_DFLT_KITL_SERVICES;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (iStart == i)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 break;聽 // couldn't find a client
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 if (!pClient || !(pClient->State & (KITL_CLIENT_REGISTERING|KITL_CLIENT_REGISTERED))) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!Received config for unrecognized service %s\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 pCfg->ServiceName));
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return TRUE;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 if (fUseSysCalls)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 EnterCriticalSection(&pClient->ClientCS);
聽聽聽聽聽聽聽聽聽聽聽 // Send config to peer, unless this was a response to our cmd
聽聽聽聽聽聽聽聽聽聽聽 if (!(pHdr->Flags & KITL_FL_ADMIN_RESP)) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // ack this config message
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SendConfig(pClient,TRUE);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // Stop any pending transfers, reset sequence #s, etc
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // WARNING - can cause lost transmit data if the other side doesn't get
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // our config, and retries the config command.
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (pClient->State & KITL_SYNCED) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ResetClientState(pClient);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 //
聽聽聽聽聽聽聽聽聽聽聽 // we got the response from desktop, connecting the client
聽聽聽聽聽聽聽聽聽聽聽 //
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_INIT, ("ProcessAdminMsg: Receive Config message for service %s\n", pClient->ServiceName));
聽聽聽聽聽聽聽聽聽聽聽 pClient->State &= ~(KITL_WAIT_CFG|KITL_CLIENT_REGISTERING);
聽聽聽聽聽聽聽聽聽聽聽 pClient->State |= KITL_CLIENT_REGISTERED;
聽聽聽聽聽聽聽聽聽聽聽 // Set our event in case anyone is waiting for config info
聽聽聽聽聽聽聽聽聽聽聽 if (fUseSysCalls)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SetClientEvent(pClient,pClient->evCfg);
聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽 if (fUseSysCalls)聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 LeaveCriticalSection(&pClient->ClientCS);
聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 case KITL_CMD_RESET:
聽聽聽聽聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITL_RESET_DATA *pResetData =聽 (KITL_RESET_DATA *) KITLDATA (pHdr);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITLOutputDebugString("KITL: Got RESET command\n");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // Set for clean boot if requested
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (pResetData->Flags & KITL_RESET_CLEAN)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SC_SetCleanRebootFlag();
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // This function never returns
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KernelIoctl(IOCTL_HAL_REBOOT, NULL,0,NULL,0,NULL);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITLOutputDebugString("KITL: IOCTL_HAL_REBOOT not supported on this platform\n");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 case KITL_CMD_DEBUGBREAK:
聽聽聽聽聽聽聽聽聽聽聽 if (fUseSysCalls && IsDesktopDbgrExist ())
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 DebugBreak ();
聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽 case KITL_CMD_TRAN_CONFIG:
聽聽聽聽聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 int i;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 PKITL_HOST_TRANSCFG pCfg = (PKITL_HOST_TRANSCFG) KITLDATA(pHdr);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 wMsgLen -= KITL_DATA_OFFSET;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (pCfg->dwLen != wMsgLen) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITLOutputDebugString ("!Host config message size mismatch %d, %d\r\n", pCfg->dwLen, wMsgLen);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 wMsgLen -= sizeof (KITL_HOST_TRANSCFG);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (!Kitl.pfnSetHostCfg ((LPBYTE) (pCfg+1), wMsgLen))
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Kitl.dwBootFlags = pCfg->dwFlags;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if (pCfg->dwKeySig == HOST_TRANSCFG_KEYSIG) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 for (i = 0; i < HOST_TRANSCFG_NUM_REGKEYS; i++) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 g_dwKeys[i] = pCfg->dwKeys[i];
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG (ZONE_INIT, (" KeyIndex %d = %d \n", i, g_dwKeys[i]));
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 }聽聽聽
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 KITLGlobalState |= KITL_ST_DESKTOP_CONNECTED;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽 // in case we're polling (pfnTransmit && pData only set to non-null if we're polling)
聽聽聽聽聽聽聽 // we'll use desktop as our timer (desktop sends a retransmit packet to us every 2 seconds).
聽聽聽聽聽聽聽 case KITL_CMD_RETRASMIT:
聽聽聽聽聽聽聽聽聽聽聽 if (pfnTransmit && pData) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 // KITLOutputDebugString ("Retrasmitting packets....\n");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 pfnTransmit (pData, fUseSysCalls);
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 break;
聽聽聽聽聽聽聽 default:
聽聽聽聽聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_WARNING,("!ProcessAdminMsg: Unhandled command 0x%X\n",pHdr->Cmd));
聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽 }
聽聽聽 return TRUE;
}
鎴戜滑鐩存帴鐪婯ITL_CMD_TRAN_CONFIG鍒嗘敮錛岀洰鍓嶆垜浠殑涓昏宸ヤ綔浠嶇劧鏄厤緗繛鎺ャ傞鍏堝緱鍒癙KITL_HOST_TRANSCFG緇撴瀯鎸囬拡錛屽茍閫丼etHostCfg璁劇疆涓繪満淇℃伅涔嬪悗錛岃鍏ヤ粠涓繪満閫佸嚭鐨?涓猭ey鍊煎悗璁劇疆浠ュ強kitl鍚姩閫夐」鍜孠ITL_ST_DESKTOP_CONNECTED鏍囩ず浣嶃傜粫浜嗚繖涔堝ぇ涓鍦堜篃灝卞共浜嗕釜鍒濆鍖栬繛鎺ョ殑宸ヤ綔錛岀幇鍦ㄦ垜浠戶緇洖鍒皊tartKitl銆傞鍏堝厛鏄緗笁涓嚱鏁版寚閽堜緵鍚庨潰紼嬪簭璋冪敤錛屽茍璁劇疆鏍囩ず浣岾ITL_ST_ADAPTER_INITIALIZED;鐒跺悗閫氳繃SetKernelCommDev浠庡畾浣岾ERNEL_SVC_DBGMSG,KERNEL_SVC_PPSH錛孠ERNEL_SVC_KDBG鐨則ransport錛屾敞鎰忥細榪欎釜鍑芥暟騫朵笉鏄痥itl鐨勫嚱鏁幫紝鑰屾槸windowsCE kernel鐨勭郴緇熷嚱鏁板湪WINCE420\PRIVATE\WINCEOS\COREOS\NK\KERNELkwin32.c涓?浣滅敤鏄粠瀹氫綅緋葷粺璋冭瘯淇℃伅鐨勫彂甯冮氶亾錛屾湁鍏磋叮鍙互鑷繁鐪嬬湅銆備箣鍚嶴tartKitl鐨勮繃紼嬪氨緇撴潫浜嗭紝榪欎釜鏃跺欎綘鑲畾鎯抽棶閭itl鐨勪腑鏂垵濮嬪寲鍑芥暟鏄粈涔堟椂鍊欐墠榪愯鍛紵娌℃湁涓柇鐨勬敮鎸乲itl鏄浣曢氳鍜屽伐浣滅殑鍛紝浜嬪疄涓奒ITLInitializeInterrupt灝辮礋璐h繖閮ㄥ垎鐨勫伐浣滐紝浣嗘槸鐢變簬緋葷粺鍐呮牳榪樻病鏈夊畬鎴愬垵濮嬪寲鐨勫姩浣滐紝鎵浠ヨ繖涓椂鍊欒搗鍔╧itl鐨勪腑鏂槸浼氬獎鍝峩ernel鐨勫伐浣溿傚洜姝ゅ湪鍚庨潰鐢盨ystemStartupFunc()璋冪敤KITLInitializeInterrupt鏉ュ畬鎴愬垵濮嬪寲鐨勫姩浣溿?
BOOL
KITLInitializeInterrupt()
{
聽聽聽 int i;
聽聽聽 if (!(KITLGlobalState & KITL_ST_ADAPTER_INITIALIZED))
聽聽聽聽聽聽聽 return FALSE;
聽聽聽
聽聽聽 // Check if we are coming up for the first time, or resuming interrupts (e.g. when coming
聽聽聽 // back from OEMPowerOff)
聽聽聽 if (KITLGlobalState & KITL_ST_MULTITHREADED) {
聽聽聽聽聽聽聽 // Just enable interrupt and return
聽聽聽聽聽聽聽 EnableInts();
聽聽聽聽聽聽聽 return TRUE;
聽聽聽 }
聽聽聽
聽聽聽 KITLOutputDebugString("KITL: Leaving polling mode...\n");
聽聽聽 InitializeCriticalSection(&KITLODScs);
聽聽聽 InitializeCriticalSection(&KITLKCallcs);
聽聽聽 KITLGlobalState |= KITL_ST_MULTITHREADED;
聽聽聽
聽聽聽 KITL_DEBUGMSG(ZONE_INIT,("KITL Checking client registrations\n"));
聽聽聽 // Some clients may have registered already, finish initialization now that
聽聽聽 // the system is up. KDBG continues to run in polling mode.
聽聽聽 for (i=0; i< MAX_KITL_CLIENTS; i++) {
聽聽聽聽聽聽聽 if (KITLClients[i] && (i != KITL_SVC_KDBG)
聽聽聽聽聽聽聽聽聽聽聽 && (KITLClients[i]->State & (KITL_CLIENT_REGISTERED|KITL_CLIENT_REGISTERING))) {
聽聽聽聽聽聽聽聽聽聽聽 if (!RegisterClientPart2((UCHAR)i))
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽 }
聽聽聽 }
聽聽聽 // Start interrupt thread. If we have clients registered, also turn on receive interrupts
聽聽聽 // from the ethernet controller, otherwise leave them disabled.
聽聽聽 if ((UCHAR) KITL_SYSINTR_NOINTR != Kitl.Interrupt) {
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_INIT,("KITL Creating IST\n"));
聽聽聽聽聽聽聽 if ((hIntrThread = CreateKernelThread((LPTHREAD_START_ROUTINE)KITLInterruptThread,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 NULL, (WORD)g_dwKITLThreadPriority, 0)) == NULL) {
聽聽聽聽聽聽聽聽聽聽聽 KITLOutputDebugString("Error creating interrupt thread\n");
聽聽聽聽聽聽聽聽聽聽聽 return FALSE;
聽聽聽聽聽聽聽 }
聽聽聽 }
聽聽聽 return TRUE;
}
鐢變簬灝嗕細鏈塈ST涓簁itl涓撻棬鏈嶅姟錛屾墍浠ヤ篃灝遍渶瑕佷復鐣屽尯鏉ュ畬鎴愮嚎紼嬬殑鎿嶄綔錛岃繖鍎垮垱寤轟簡KITLODScs\KITLKCallcs涓や釜涓寸晫鍖恒備箣鍚庢爣璁?KITL_ST_MULTITHREADED銆傛鏌ユ敞鍐屼簡鐨勬湇鍔★紝瀹屾垚鍚庡氨鍒涘緩IST.
kitl鐨勫垵濮嬪寲錛屽惎鍔ㄧ殑澶ц嚧榪囩▼灝辨槸濡傛錛宻tart-->娉ㄥ唽鏈嶅姟-銆夊垵濮嬪寲transport->鍒涘緩IST
鏈鍚庢垜浠潵鐪嬬湅IST閲岄潰鎴戜滑閮藉共浜涗粈涔?
static DWORD KITLInterruptThread (DWORD Dummy)
{
聽聽聽 HANDLE hIntEvent;
聽聽聽 DWORD dwRet;
聽聽聽 KITL_DEBUGMSG(ZONE_INIT,("KITL Interrupt thread started (hTh: 0x%X, pTh: 0x%X), using SYSINTR %u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 hCurThread,pCurThread, Kitl.Interrupt));
聽聽聽 pCurThread->bDbgCnt = 1;聽聽 // no entry messages
聽聽聽
聽聽聽 if ((hIntEvent = CreateEvent(0,FALSE,FALSE,EDBG_INTERRUPT_EVENT)) == NULL) {
聽聽聽聽聽聽聽 KITLOutputDebugString("KITL CreateEvent failed!\n");
聽聽聽聽聽聽聽 return 0;
聽聽聽 }
聽聽聽 if (!SC_InterruptInitialize(Kitl.Interrupt, hIntEvent, NULL,0)) {
聽聽聽聽聽聽聽 CloseHandle(hIntEvent);
聽聽聽聽聽聽聽 KITLOutputDebugString("KITL InterruptInitialize failed\n");
聽聽聽聽聽聽聽 return 0;
聽聽聽 }
聽聽聽 // always enable interrupt as long as OEM told us so
聽聽聽 EnableInts();
聽聽聽
聽聽聽 KITLGlobalState |= KITL_ST_IST_STARTED;
聽聽聽
聽聽聽 while ((dwRet = SC_WaitForMultiple (1,&hIntEvent,0,INFINITE)) == WAIT_OBJECT_0) {
聽聽聽聽聽聽聽 KITL_DEBUGLED(LED_IST_ENTRY,0);
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_INTR,("KITL Interrupt event\n"));
聽聽聽聽聽聽聽 // no need to check pending, just call HandleRecvInterrupts because it'll
聽聽聽聽聽聽聽 // just return if there is no interrupt pending
聽聽聽聽聽聽聽 HandleRecvInterrupt(ISTRecvBuf,TRUE, NULL, NULL);
聽聽聽聽聽聽聽 SC_InterruptDone(Kitl.Interrupt);
聽聽聽聽聽聽聽
聽聽聽聽聽聽聽 KITL_DEBUGMSG(ZONE_INTR,("Processed Interrupt event\n"));
聽聽聽 }
聽聽聽 KITLOutputDebugString("!KITL Interrupt thread got error in WaitForMultipleObjects: dwRet:%u, GLE:%u\n",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 dwRet,GetLastError());
聽聽聽 return 0;
}
棣栧厛鏄垱寤鴻IST鎵灞炵殑浜嬩歡錛屽茍灝嗚浜嬩歡涓庢墍灞炵殑涓柇鑱旂郴璧鋒潵錛屽啀鍚庤嚜鐒舵槸鍚姩涓柇浜嗐傝瀹欿ITL_ST_IST_STARTED鏍囪鍚庣殑浠g爜灝辨槸IST鐨勫疄闄呭唴瀹癸紝褰撲腑鏂彂鐢燂紝浜や粯HandleRecvInterrupt澶勭悊錛岃繑鍥炰腑鏂傚拰澶氭暟IST涓鏍瘋璋冪敤姘歌繙涓嶄細榪斿洖錛岄櫎闈炵粨鏉熻綰跨▼錛屾墍浠ュ悗闈㈢殑璋冭瘯淇℃伅杈撳嚭鐨勬槸閿欒銆?
void HandleRecvInterrupt(UCHAR *pRecvBuf, BOOL fUseSysCalls, PFN_TRANSMIT pfnTransmit, LPVOID pData)
{
聽聽聽 WORD wLen = KITL_MTU;
聽聽聽 BOOL fFrameRecvd;
聽聽聽 // Receive data into buffer
聽聽聽 do {
聽聽聽聽聽聽聽 if (!fUseSysCalls)
聽聽聽聽聽聽聽聽聽聽聽 fFrameRecvd = Kitl.pfnRecv (pRecvBuf, &wLen);
聽聽聽聽聽聽聽 else if (IsDesktopDbgrExist ())
聽聽聽聽聽聽聽聽聽聽聽 fFrameRecvd = KCall((PKFN) Kitl.pfnRecv, pRecvBuf, &wLen);
聽聽聽聽聽聽聽 else {
聽聽聽聽聽聽聽聽聽聽聽 EnterCriticalSection (&KITLKCallcs);
聽聽聽聽聽聽聽聽聽聽聽 fFrameRecvd = Kitl.pfnRecv (pRecvBuf, &wLen);
聽聽聽聽聽聽聽聽聽聽聽 LeaveCriticalSection (&KITLKCallcs);
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 if (fFrameRecvd) {
聽聽聽聽聽聽聽聽聽聽聽 ProcessRecvFrame (pRecvBuf,wLen,fUseSysCalls, pfnTransmit, pData);
聽聽聽聽聽聽聽聽聽聽聽 wLen = KITL_MTU;
聽聽聽聽聽聽聽 }
聽聽聽 } while (fFrameRecvd);
}
HandleRecvInterrupt鏄腑鏂鐞嗙▼搴忕殑瀹炰綋錛屽皢transport閫佹潵鐨勬暟鎹~鍏ョ紦鍐插尯寰呭鐞嗐備笂闈㈡墍鎻愬埌鐨勪腑鏂湪OEM浠g爜涓寚瀹氾紝鍦⊿MDK2440bsp涓涓柇瀵瑰簲浠ュお緗戝崱涓柇銆?
浣滆咃細Walzer
鏃ユ湡錛?005.3.19
鎽樿錛欿ITL鏄疨LATFORM BUILDER涓殑涓涓寒鐐癸紝鎻愪緵浜嗗拰鏈湴璋冭瘯綾諱技鐨勬柇鐐廣佸彉閲忚窡韙佸唴瀛樻煡鐪嬬瓑鎵嬫錛屽鏋滄病鏈塊ITL錛屽祵鍏ュ紡璋冭瘯搴旇鍙兘鐢ㄤ覆鍙f墦鍗版秷鎭潵鐪嬩簡錛屽伐浣滄晥鐜囧ぇ澶т笅闄嶃傛湰鏂囦互瀹炵幇鏈綆鍗曠殑SERIAL KITL涓虹洰鐨勶紝灝卞叾瀹炵幇浠g爜榪涜璺熻釜璋冭瘯錛岃繖浜涗唬鐮佽法瓚婁簡WINCE鐨凱LATFORM銆丳UBLIC銆丳RIVATE涓夊ぇ涓昏鐩綍錛屾湁浜涚儲鐞愶紝涓嶈繃鍙鑳借皟閫氾紝涓鍒囧伐浣滃拰寮礬閮芥槸鍊煎緱鐨勩傛垜鎶婅皟璇曠粡楠屽拰涓漢鐞嗚В鍐欎笅鏉ワ紝甯屾湜鑳藉府鍔╁埆浜哄皯璧板集璺傚鏋滄枃绔犱腑鏈夌悊瑙eけ褰撶殑鍦版柟錛岃涓嶅悵璧愭暀銆?br />
姝f枃錛?br />
涓.void OEMInit()聽 [platform\project\src\kernel\oal\init.c]
聽聽聽 棣栧厛浠嶰EMInit()鍑芥暟鐪嬭搗銆傘傚湪渚濇鍒濆鍖朆ranch-Target Buffer銆並ERNEL鍑芥暟銆佸垵濮嬪寲涓柇銆乀IMER涔嬪悗錛屽氨杞埌KITL浜嗐傝皟鐢ㄤ簡榪欎釜鍑芥暟OALKitlStart()銆傛鏃舵湁涓紪璇戠殑鍒嗘敮錛屽鏋滄槸RELEASE鐗堟湰錛岄偅涔堝湪kernel\kern\stubs.c閲岄潰鐨凮ALKitlStart()鍑芥暟鏄釜STUB錛屽彧鏄痳eturn TRUE錛?濡傛灉鏄疍EBUG鐗堟湰錛岄偅灝辮繘鍒発ernel\oal\kitl.c閲岄潰鐨凮ALKitlStart().
浜?BOOL OALKitlStart()聽 [platform\myproject\src\kernel\oal]
聽聽聽 鍦∣ALKitlStart()閲岄潰錛岄鍏堣瘯鍥句粠0xA00FF00澶勮鍙朾ootloader閲岄潰鐣欎笅鐨刱itl鍙傞噺錛屽鏋滆涓嶅埌涓滆タ鍒欎嬌鐢ㄨ鍑芥暟閲岀殑榛樿閰嶇疆銆傜敱浜庡師鏉ョ敤浜唀thernet鍚屾椂浣滀負download鍜宬itl閫斿緞錛屾墍浠ュ湪InitSpecifiedEthDevice鍑芥暟閲岀粰pKitlArgs緇撴瀯浣撹祴鍊間簡銆傜幇鍦ㄦ兂鎶婁袱鑰呭垝鍒嗘竻妤氾紝棣栧厛灝辨妸璇誨彇bootloader閲岄潰鐨刱itl鍙傞噺涓鍙ュ共鎺夛紝寮鴻揩浣跨敤鎴戜滑鍦ㄤ笅闈㈢殑榛樿閰嶇疆銆備富瑕佸氨鏄~鍏呬笁涓弬閲?/p>
1.棣栧厛鏄繖涓粨鏋勪綋
OAL_KITL_ARGS pKITLArgs
{
聽UINT32 flags;聽 //璁懼ソENABLED鏍囧織錛屾寜闇瑕佽POLL鏍囧織錛屼絾娉ㄦ剰涓瀹氫笉瑕佽PASSIVE鏍囧織
聽DEVICE_LOCATION聽 devLoc;
聽{
聽聽DWORD聽 IfcType;聽聽//涓嶈ether榪樻槸serial錛岄兘鏄痠nternal type =0;
聽聽DWORD聽 BusNumber;聽// =0
聽聽DWORD聽 LogicalLoc;聽//鐗╃悊鍦板潃
聽聽PVOID聽聽聽聽 PhysicalLoc;聽//鐣欏仛鍚庨潰=OALPAtoVA(LogicalLoc, FALSE). 鐪熻楝? 鎰熻搴旇鍜屼笂闈㈢殑LogicalLoc浣滅敤璋冭繃鏉ョ湅鐫姣旇緝欏哄惂?
聽聽DWORD聽 Pin;聽聽//Ethernet鎵嶇敤鐨勪笢涓?br />聽}
聽union
聽{
聽聽struct
聽聽{
聽聽聽UINT32聽 baudRate;聽//涓嶇敤瑙i噴浜?br />聽聽聽UINT32聽 dataBits;
聽聽聽UINT32聽 stopBits;
聽聽聽UINT32聽 parity;
聽聽}
聽聽struct
聽聽{
聽聽聽UINT16聽 mac[3];聽//榪欎釜涔熶笉鐢ㄨВ閲婁簡
聽聽聽UINT32聽 ipAddress;
聽聽聽UINT32聽 ipMask;
聽聽聽UINT32聽 ipRoute
聽聽}
聽}
}
2. pszDeviceID.聽 鎰熻榪欏悕瀛楀氨鏄搗浜嗗ソ鐜? 璧嬫垚Walzer搴旇姣旇緝鎷?涓嶈繃榪樻槸淇濈暀鍘熸潵璧嬬殑AMOISOFT濂戒簡, 鍏嶅緱琚墦.
3. 鍏ㄥ眬鍙橀噺OAL_KITL_DEVICE g_kitlDevices. 榪欎釜涓滀笢鍦╧itl.c寮澶村寘鍚殑kitl_cfg.h涓璧嬪?聽 鏈涓昏灝辨槸淇敼g_kitlDevices.pDriver.聽 榪欎釜pDrvier鎸囧悜涓涓嚱鏁版寚閽堝垪琛ㄧ殑緇撴瀯浣擄紝璇ュ垪琛ㄥ畾涔変簡鐢ㄥ仛kitl妯″潡鐨勫垵濮嬪寲銆佽鍐欍佷腑鏂佹祦鎺у埗絳夊嚱鏁般?g_kitlDevices鏈韓鏄釜浜岀淮鏁扮粍, 鍙互瀹氫箟璁稿璁懼鐢ㄥ仛kitl鏃舵彁渚涚殑鍙傛暟璁劇疆, 鍚庨潰浼氱敤涓涓猣or鏉ュ驚鐜垽鏂璸KITLArgs鐨勫弬鏁板拰g_kilDevices閲岄潰鍝釜涓緇存暟緇勬垚鍛樼浉鍖歸厤.
榪欎笁涓弬閲忓~鍏呭ソ浠ュ悗錛屽氨鍙互榪涘埌OALKitlInit(pszDeviceID, pKITLArgs, g_kitlDevices)閲岄潰浜?
涓?BOOL OALKitlInit( deviceId, pArgs, pDevice)聽聽聽 [platform\common\src\common\kitl\kitl.c]
聽聽聽 榪欎釜鍑芥暟鍏堟妸杈撳叆鐨勫弬閲忓叏閮ㄧ敤OALMSG鎵撳嵃鍑烘潵錛岃繖涓笉綆°?br />聽聽聽 閲嶈鐨勬槸寮曞叆浜唃_kitlState鍏ㄥ眬鍙橀噺錛屽紑澶翠竴鍙?br />聽聽聽 g_kitlState.pDevice = OALKitlFindDevice(&pArgs->devLoc, pDevice) 榪欎釜灝辨槸涓婇潰鎵璇寸殑浠巊_kitlDevices閲屽彲鐢ㄨ澶囧垪琛ㄩ噷寰幆鍒ゆ柇錛屾壘鍒伴夌敤鐨勮澶囩殑鍖歸厤鍑芥暟鎸囬拡銆?br />聽聽聽 鎺ョ潃鎶婅緭鍏ュ弬閲廳evicdId鍜屽墠闈㈠~鍏呭ソ鐨凮AL_KITL_ARGS緇撴瀯COPY鍒癵_kitlState閲岄潰
聽聽聽 鐒跺悗灝卞彲浠ヨ皟鐢↘ItlInit(TRUE)浜嗭紝濡傛灉鍓嶉潰鍦‵LAG閲岄潰璁句簡PASSSIVE鏍囧織錛岀幇鍦ㄥ氨鏄疜itlInit(FALSE)浜嗭紝鍢垮樋鐖藉埌浜嗗惂銆?/p>
鍥?BOOL KitlInit(BOOL fStartKitl)聽聽聽 [private\winceos\coreos\nk\kitl\ethdbg.c]
聽聽聽 澶尌鐞愪簡錛屾垜瑕佺敤涓插彛錛屽畠灞呯劧鍙玡thdbg.c錛屼笉緇欓潰瀛愩備笉榪囨槸private閲岄潰鐨勪笢涓滐紝鍙繙瑙傝屼笉鍙旱鐜╃剦~~
聽聽聽 榪欎釜鍑芥暟騫蹭簡涓変歡浜嬶細
1. 瑁呰澆浜嗕笁涓叏灞鐨勫嚱鏁版寚閽?br />2. 鐢∟ewClient娉ㄥ唽浜嗕笁涓狵ITL瀹㈡埛绔細
聽聽聽 KITL_SVCNAME_DBGMSG聽聽 //debug message, Debug淇℃伅鍙戝竷閫氶亾
聽聽聽 KITL_SVCNAME_PPSH聽 //PPshell, 鏂囨湰鎺у埗鍙扮晫闈?
聽聽聽 KITL_SVCNAME_KDBG //kernel debug, 鍐呮牳璋冭瘯鐣岄潰
3.鐢眆StartKitl鏉ュ喅瀹氭槸鍚﹀惎鍔⊿tartKitl()鍑芥暟. (榪欓噷欏轟究鎻愪竴涓嬶紝鎸夌収鍖堢墮鍒╁懡鍚嶆硶, BOOL鍙橀噺鍓嶉潰鍔犱釜b, 浣哅S鐨勫仛娉曟垜瑙夊緱寰堝悎鐞? BOOL鍙橀噺灝辨槸涓狥LAG鍢? 鍓嶉潰鍔犱釜f, 鎶婂皬b鐣欑潃緇橞YTE綾誨瀷鐢?)
浜?static BOOL StartKitl(BOOL fInit)聽聽聽 [private\winceos\coreos\nk\kitl\ethdbg.c]
聽聽聽 榪欏張鏄痯rviate閲岄潰鐨勪笢涓溿傛渶鐥涜嫤鐨勫湴鏂瑰紑濮嬩簡銆傝繖鍑芥暟鍙婂叾瀛愬嚱鏁板皢絎竴嬈¤皟鐢∣EM鑷繁鍐欑殑KITL妯″潡鍒濆鍖栥佽鍐欑▼搴忋傛槸楠″瓙鏄┈錛屾媺鍑烘潵婧滄簻灝辯煡閬撳暒~
聽聽聽 鎸夐『搴忕湅涓嬫潵錛岄鍏堝垽鏂緭鍏ュ弬閲忔槸鍚﹁鍚姩KITL錛屽茍涓斿鏋淜ITLGlobalState閲岄潰琚墦涓奒ITL_ST_DESKTOP_CONNECTED鏍囪鐨勮瘽錛岄偅涓嬮潰鐨勬楠ゅ氨鍏ㄥ厤浜嗐傚綋鐒舵垜浠槸絎竴嬈¤繍琛屽埌榪欓噷錛岃嫢榪欎箞灝辮煩鍑虹殑璇濓紝淇哄氨椹姞鐖典簡銆?/p>
聽聽聽 絎竴姝?
聽聽聽 騫茬殑絎竴浠舵浜嬪氨鏄皟鐢∣EMKitlInit(&Kitl). 榪欎釜鍚庨潰璇﹁堪. 緇х畫鎶婅繖涓嚱鏁扮湅瀹?
聽聽聽 OEMKitlInit鍒濆鍖朘ITL鐨勭‖浠舵娊璞″眰鍚庡茍鎶婄浉鍏蟲寚閽堟暟鎹~鍏呯粰鍏ㄥ眬鍙橀噺KITLTRANSPORT Kitl (鏈夋病鏈夋悶閿欙紝涓轟粈涔堜笉鍙玤_kitl), 榪欎簺宸ヤ綔鍋氬畬灝辮繑鍥炰簡
聽聽聽聽 StartKitl鏀惰揣鍚庢妸Kitl緇撴瀯鏁翠釜媯鏌ヤ竴閬?淇濊瘉娌¢敊鍚? 椹笂涔板崟, 鎶婂叏灞鍙橀噺KITLGlobalState鎵撲笂涓狵ITL_ST_KITLSTARTED鏍囪. 榪欐墠綆桲ITL鍚姩鐨勭涓姝K浜?
聽聽聽 絎簩姝?
聽聽聽 鎺ヤ笅鏉ュ氨鏄疜ITLConnectToDesktop(), 榪涜繖涓嚱鏁板悗灝辨槸絎竴嬈′嬌鐢ㄤ簡鍓嶉潰KITL浼犺緭浠嬭川紜歡鎶借薄灞傞噷鐨勮鍐欏嚱鏁頒簡, 榪欐椂鍊欏氨闇瑕佽皟璇曚簡. 榪欎釜ConnectToDesktop澶ц嚧灝辨槸鍏圫end浜嗕竴涓猭ITL.....鐨刦rame榪囧幓,鐒跺悗polling絳夊緟PC绔殑response, 閭h竟鍐嶅彂涓猭ITL.....鐨刦rame榪囨潵, 鎼炲緱璺熷湴涓嬪厷鎵撴殫鍙蜂技鐨? 鍏跺疄涔熸病浠涔堢巹涔庣殑錛屽氨鏄櫘閫氱殑鏁版嵁鍖呭墠闈㈠姞涓狵TIL涓撶敤鐨凥EADER鑰屽凡. 榪欎釜CONNECT鎴愬姛鍚?KITLGlobalState閲岄潰灝卞姞涓狵ITL_ST_DESKTOP_CONNECTED鏍囪浜?
聽聽聽 絎笁姝?
聽聽聽 set up kernel function pointers, 涔熸病浠涔?灝變笁涓嚱鏁版寚閽? 璧嬪畬鍚庡氨KITL_ST_ADAPTER_INITIALIZED浜? 鍏跺疄榪欎釜KITLGolbalSate鐨勬誨叡鏈?涓爣蹇?鍒嗗埆鏄?br />KITL_STARTED,聽 (OK)
DESKTOP_CONNECTED,聽聽 (OK)
TIMER_INIT, (?)
INT_ENABLED,聽 (POLLING)
IST_STARTED,聽 (POLLING)
MULTITHREADED,聽聽 (?)
ADAPTER_INITIALIZED. (OK)
鍚庨潰鎷彿閲屾墦涓奜K鏄埌榪欓噷宸茬粡瀹屾垚鐨勶紝 鎵撻棶鍙風殑鎴戣繕涓嶅お娓呮浠涔堜綔鐢? INT鍜孖ST涓ら」,鎴戜滑鐢ㄧ殑POLLING鎵浠ヨ偗瀹氭槸涓嶉渶瑕佷簡.
聽聽聽 絎洓姝?
聽聽聽 璋冪敤SetKernelCommDev璁劇疆kernel閫氳繃浣曠浠嬭川浼犻丏BGMSG, PPSH鍜孠DBG.
聽聽聽 OHYEAH, 鎴戠殑SERIAL KITL灝卞き鎶樺湪榪欓噷. 榪涘埌SerKernelCommDev(service, CommDevice)鍑芥暟閲岀湅, 瀹冨彧璁ommDevice=KERNEL_COMM_ETHER鐨勬儏鍐碉紝鑰屽睆钄戒簡涓嶦THER騫跺垪鐨凷ERIAL鍜孭ARALLER,鐩存帴return FALSE, 涓嬮潰鐨勪簨鎯呴兘涓嶇敤騫蹭簡. 鑰屽湪MS鎻愪緵鐨刉inCE Documantation閲岄潰錛岃繖涓猄etKernelCommDev鍑芥暟鐨勮鏄庝笂鍐欑潃"This function is obsolete and should not be used". 鑻ユ兂鏀瑰槢,榪欎釜鏄湪private閲岄潰鐨勮繕鍔ㄥ畠涓嶅緱. NND, 鎰熻琚玀S raped浜?
聽聽聽聽 濡傛灉浣跨敤ETHER鍦ㄨ繖閲屾垚鍔熺殑璇? 涓嬮潰榪樻湁涓や釜鍑芥暟NKForceCleanBoot()鍜孠ITLInitializeInterrupt()璧拌繃鍘? 榪橩ITL鍒濆鍖栧氨鍏ㄩ儴緇撴潫浜? 鎴戜及璁ITLGolbalSate閲岄潰鐨処NIT_ENABLED鍜孖ST_STARTED灝辨槸鍦ㄨ繖涓嚱鏁拌繃紼嬩腑琚爣璁頒笂鐨?
聽聽聽聽
聽聽聽
鍏?BOOL OEMKitlInit(PKITLTRANSPORT pKitl)聽聽聽 [platform\common\src\common\kitl\kitl.c]
聽聽聽 鍓嶉潰鎻愬埌StartKItl璧鋒潵鍚庯紝棣栬鐨勫氨鏄皟鐢∣EMKitlInit. 榪欎釜鍑芥暟鍦╓inCE4.2鍜?.0閲屽樊鍒緢澶? 4.2閲岀殑鍋氭硶鏄犅犅?if (!InitEther (pKitl) && !InitParallelSerial (pKitl)), 鎶奅THER, SERIAL, PARALLEL閮藉垵濮嬪寲浜嗕竴閬?紕拌繍姘旂湅鍝釜鐢ㄥ緱涓婏紝鑰?.0閲屾槸榪涙潵鍚庡氨涓涓緢鏄庢樉鐨勫垎鏀墽鎯?鐢眊_kitlState.pDevice->type鏉ュ喅瀹氭槸璋冪敤OALKitlEthInit榪樻槸OALKitlSerialInit. 鍏稿瀷鐨勭鏃忔瑙? 灞呯劧娌℃湁OALKitlParallelinit. 榪樺ソ鎴戜滑鐢ㄧ殑鏄疭ERIAL.
聽聽聽 榪欓噷鏈変釜閫夋嫨緙栬瘧鐨勫湴鏂?灝辨槸#ifdef KITL_ETHER鍜?ifdef KITL_SERIAL, 鍏蜂綋瀹氫箟鐨勫湴鏂規槸璇ョ洰褰曚笅鐨剆ources鏂囦歡閲岄潰涓琛?CDEFINES=$(CDEFINES) -DKITL_SERIAL -DKITL_ETHER, 鐚ョ悙鍟婃壘浜嗗崐澶? 鍏跺疄鎴戣寰楁棦鐒舵湁if緇撴瀯鏉ラ変簡錛岄偅涔堥夋嫨緙栬瘧涔熸槸鍙湁鍙棤鐨勪簡.
聽聽聽 濂斤紝涓嬮潰灝辮繘鍒癘ALKItlSerialInit()閲岄潰.
涓?BOOL OALKitlSerialInit(LPSTR deviceId, OAL_KITL_DEVICE *pDevice, OAL_KITL_ARGS *pArgs, KITLTRANSPORT *pKitl)
聽聽聽 [platform\common\src\common\kitl\kitlserial.c]
聽聽聽 鎴戣嚜宸卞線榪欎釜kitlserial.c鏂囦歡閲屽啓浜嗗叚涓嚱鏁?
聽聽聽 BOOL KitlSerialInit(KITL_SERIAL_INTFO *pSerInfo)
聽聽聽 UINT16 KitlSerialWriteData(UINT8 *pch, UINT16 length)
聽聽聽 UINT16 KitlSerialReadData(UINT8 *pch, UINT16 length)
聽聽聽 void KitlSerialFlowControl聽 //stub, 鎴戞墍鐢ㄧ殑FFUART鍙湁TXD鍜孯XD涓ゆ牴綰? RTS絳夐兘娌℃湁, 鎵浠lowControl鑷劧涔熷簲璇ユ槸STUB浜?br />聽聽聽 void KitlSerialEnableInt(void)聽聽 //stub, use polling
聽聽聽 void KitlSerialDisableInt(void)聽 //stub, use polling
聽聽聽 鍚﹀垯鍓嶉潰鐨刧_kitlDevices閲岄潰娌℃湁鐩稿簲鐨勭‖浠舵娊璞″眰鏉ュ~鍏?
聽聽聽 涓婇潰鐨凷erialRecv, Encode, Decode絳夊氨鎰忔濋兘寰堟槑鏄句簡,涓嶇敤澶氳. OK鐜板湪宸茬粡璧板埌鏈搴曞眰浜? 鏂囩珷涔熷彲浠ョ粨鏉熶簡.
鍏佽褰曚竴涓嬭皟璇曠粡楠?br />聽聽聽 铏界劧榪欐槸鎴戠涓夋璋冧覆鍙d簡錛岀敱浜庢病鎬葷粨鍓嶉潰鐨勭粡楠岋紝榪樻槸鑰椾簡涓ゅぉ鎵嶅埌private閲岄潰澶姌鐨勫湴鏂廣傚疄闄呬笂搴旇涓澶╁氨鑳借蛋鍒頒簡銆傞棶棰樺嚭鍦?br />1. 絎竴澶╄皟璇曞櫒鏍規湰鐢ㄤ笉涓婃墜銆傝皟璇曞櫒杞歡銆丳B涓嶆柇姝葷繕錛岀粡甯擱噸鍚蔣浠剁敋鑷抽噸鍚數鑴戯紝絎竴澶╂湁3/4浠ヤ笂鐨勬椂闂磋楀湪榪欎簺闂涓? 涓嶆柇閲嶅惎銆?br />2. 鍦║ART鍒濆鍖栧嚱鏁扮殑鏈鍚庯紝灞呯劧蹇樿浜嗗湪interrupt controller register閲岄潰enable uart unit, 榪欎箞涔岄緳鐨勪簨銆?br />3. KitlSerialFlowControl鐨勯棶棰? 鍐欑殑鏃跺欑収鎼簡X86涓嬬殑鍑芥暟, 娌℃兂鏄庣櫧鍒板簳瑕丆ontrol浠涔? 璋冭瘯鏃舵鍦ㄨ繖閲屽悗,聽 涓寮濮嬫妸鎸囧悜榪欎釜鍑芥暟鐨勬寚閽堣緗垚NULL, 浣嗚繖鏍稰RIVATE閲岄潰鏈変簺瑕両F鍒ゆ柇鐨勫嚱鏁板氨榪涗笉鍘諱簡. 鍚庢潵鎹㈡垚STUB灝監K浜?
4. receive鍑芥暟閲岄潰, 鍦ㄦ敹姣忎釜BYTE涔嬪墠鍏堝幓鍒ゆ柇浜哃ine Status Register閲岄潰鐨凞ata Ready bit, 濡傛灉璇ヤ負闆? 鍒欒繑鍥炲け璐? 浣嗚繖閲屾槸鏈夐棶棰樼殑錛屽叿浣撲篃娌″お鎯蟲槑鐧? 鍙嶆鍦ㄨ皟璇昫ebug serial鐨勬椂鍊欏氨鎶婅繖涓垽鏂粠MS鎻愪緵鐨勬簮鐮侀噷澶村垹鍘諱簡錛岀幇鍦ㄥ仛KITL serial鏃跺張鎵嬬棐鍔犺繘鍘? 鏋滅劧榪樻槸涓嶈. 榪欏彲鑳芥槸MS鎴朓NTEL鐨勪竴澶凚UG, 浣嗘寜鐓NTEL CPU MANUL UPDATE閲岄潰緇欑殑璇繪祦紼? 涓寮濮嬪彧鍒ゆ柇LSR閲岄潰鐨凟RROR, 娌℃湁鍒ゆ柇DR浣嶅氨寮濮嬭絎竴涓狟YTE浜? 璇昏繃鍚庡啀鍒ゆ柇濡傛灉DR浣嶄負1,鍒欑戶緇涓嬩竴BYTE.
5. 鍦╮eceive鍑芥暟閲屽姞閫氳繃debugger鍔燽reak point, 緇撴灉receive buffer register閲岄潰鐨勬暟鎹debugger鎵弿鍘諱互鍚庯紝灝卞彉闆朵簡錛孋PU涓婂嵈浠涔堥兘鏀朵笉鍒? 榪欎簨鎯呰椾簡澶у崐涓笅鍗堬紝鏈鍚庤繕鏄疛effery鍙戠幇鐨勮繖涓棶棰?
鍙傝冩枃绔狅細
KITL瑙f瀽 by Nasiry聽 (http://nasiry.cnblogs.com/archive/2004/09/22/45473.html)
棣栧厛瑙i噴涓嬭繖涓や釜涓滀笢
The RAM on a Windows CE鈥揵ased device is divided into two areas: the object store and the program memory.
The object store resembles a permanent, virtual RAM disk. Data in the object store is retained when you suspend or perform a soft reset operation on the system. Devices typically have a backup power supply for the RAM to preserve data if the main power supply is interrupted temporarily. When operation resumes, the system looks for a previously created object store in RAM and uses it, if one is found. Devices that do not have battery-backed RAM can use the hive-based registry to preserve data during multiple boot processes.
The program memory consists of the remaining RAM. Program memory works like the RAM in personal computers 鈥?it stores the heaps and stacks for the applications that are running.
鎴戞壙璁ゆ垜寰堟噿錛屼笂闈竴孌佃瘽鐨刄RL鏄痬s-help://MS.WindowsCE.500/wcecoreos5/html/wce50conMemoryArchitecture.htm
鍏蜂綋鐨勮緗彲浠ュ湪緋葷粺鍚姩鍚庯紝Control Panel -> System -> Memory 閲岄潰鐪嬪埌銆傞粯璁ょ殑鏄妸鍐呭瓨浜斾簲寮錛屼竴鍗婄粰Storage Memory錛?涓鍗婄粰Program Memory鐢ㄣ傝繖鏍鋒樉鐒舵槸涓嶅悎綆楃殑銆備互64M鐨凴AM涓轟緥, 鍚姩鍚嶴torage Memory 32M, 鑰屽洜涓烘病鏈夌暀鍑虹晫闈㈣鐢ㄦ埛寰閲岄潰鎷蜂笢瑗? 浠諱綍鏃跺檌n use閮戒笉浼氳秴榪?0M; Program Memory涔熸槸32M, 浣嗗惎鍔ㄥ悗灝辯敤鎺?7M, 瀹為檯涓婂簲鐢ㄧ▼搴忓彲鐢ㄧ殑鍐呭瓨鍙湁5M, 涓鏃﹁揪鍒頒簡涓婇檺, 閭d箞姣忓墠榪涗竴姝ラ兘瑕佸緢鑹伴毦鍦板幓閲婃斁鍑犲崄K鍐呭瓨錛岀劧鍚庣敤鎺夛紝鍐嶅幓閲婃斁鍑犲崄K鍐呭瓨錛屽姝ゅ驚鐜紝姝ゆ椂搴旂敤紼嬪簭鐨勮繍琛岄熷害鐙傛參鏃犳瘮.
鍒掑垎鐨勬柟娉曚篃寰堢畝鍗? 鍙笉榪囧彲鑳芥病浜烘敞鎰忓埌鑰屽凡.
璇存槑鍦╩s-help://MS.WindowsCE.500/wceosdev5/html/wce50lrfFSRAMPERCENT.htm聽 鎳掑緱鐪嬭嫳鏂囩殑浜哄氨緇х畫寰涓嬬湅
鍏跺疄璇寸櫧浜嗗氨涓鍙ヨ瘽, 鍦˙SP鐨刢onfig.bib閲?CONFIG 鍖烘坊鍔犺繖涓彉閲?FSRAMPERCENT = 0xXXXXXX, 浣嗘敞鎰忎袱鐐癸紝
(1) 蹇呴』鍐欏湪config.bib鐨凜ONFIG鍖洪噷, 涓嶆槸plagform.bib涓嶆槸config.reg絳夊叾浠栨枃浠惰屾槸config.bib錛屼篃涓嶆槸config.bib鏂囦歡鐨勪換鎰忓湴鏂硅屼竴瀹氳鍦–ONFIG REGION閲?
(2) FSRAMPERCENT榪欎釜鍙橀噺涓瀹氬緱鍐欎負FSRAMPERCENT, 涓嶈兘鍐欐垚FSROMPERCENT涓嶈兘鍐欐垚ILOVEU, 鎴栬呴樋鐚樋鐙椾粈涔堢殑.
鍐欎笅榪欎袱鍙ョ殑鏃跺欐湰浜哄凡緇忔墦寮鏃犳晫鍏夌幆, 鍏嶇柅涓鍒囬浮铔嬪拰瑗跨孩鏌?
FSRAMPERCENT鏄竴涓?byte闀垮害鐨勫崄鍏繘鍒舵暟, 鎴戜滑鐢ㄤ唬鏁板亣璁?FSRAMPERCENT = 0xQXYZ, 鍏朵腑Q,X,Y,Z閮芥槸鍗佸叚榪涘埗鏁?/p>
閭d箞鏈緇堝垝鍒嗙粰Storage Memory鐨勫ぇ灝?=聽 ( Q + X + Y +聽 Z ) / 0x400 * TOTAL_RAM_SIZE
浠ユ枃涓殑渚嬪瓙鏉ョ畻, FSRAMPERCENT=0x10203040, 鍋囪TOTAL_RAM_SIZE=64M, 閭d箞StorageMemory= (0x10 + 0x20 + 0x30 + 0x40) / 0x400 * 64M = 10M.
浣滆咃細Walzer
鏃ユ湡錛?005.12.12
RAPI鍏ㄥ啓涓篟emote Application Interface, 灝辨槸PC绔皟鐢ㄨ繖緇凙PI, 閫氳繃ActiveSync鏉ユ搷浣淭ARGET绔疻indowsCE浣滀笟. 榪欎釜鍔熻兘浼拌浠ュ悗鍦╓INCE鎴朩IN MOBILE鐨勫簲鐢ㄤ笂浼氱敤鍒拌澶?/p>
鎴戜粖澶╀慨鏀逛簡鍚屼簨鐣欎笅鐨刄pdateboot.exe鐨勪唬鐮? 鏀硅繘钃濈墮璇誨啓鐨勬ā鍧? 榪欎釜鍦版柟鎴戜滑鐢ㄥ埌浜哛API, 鐪嬩竴涓嬩粬浠湪紼嬪簭涓垵濮嬪寲RAPI鐨勫仛娉?/p>
聽HRESULT hRapiResult;
聽hRapiResult = CeRapiInit();
聽if(hRapiResult != S_OK)
聽{
聽聽聽聽 m_ValueEdit.SetWindowText((LPCTSTR)"鍒濆鍖朢API澶辮觸");
聽聽聽聽 return;
聽}
鐪嬭搗鏉ユ槸騫蟲貳鏃犲, 瀹為檯涓婂崟姝ヤ竴涓嬪氨鍙互鍙戠幇榪愯鍒癈eRapiInit()鏃? 紼嬪簭灝盉LOCK鍦ㄨ繖閲屼簡錛屾媧昏蛋涓嶄笅鍘? 騫舵病鏈夎揪鍒奧爄f(hRapiResult != S_OK)鐨勯鏈熺洰鐨? 鎴戞煡浜嗕竴涓婥eRapiInit()鐨勮鏄?
A call to CeRapiInit does not return until the connection is made, an error occurs, or another thread calls CeRapiUninit.
涔熷氨鏄鍍忔垜鐜板湪騫舵病鏈夋妸鏉垮瓙鍜孭C鐩歌繛騫跺惎鍔ˋCTIVE SYNC鏃? 榪欎釜CeRapiInit()鏄偗瀹氳禆鐫涓嶈蛋浜? 紼嬪簭浼氭鍦ㄨ繖閲? (閯欒涓涓嬭皝鍐欑殑浠g爜錛岃繖涓潙濂藉ぇ鍟? 聽鍥犳鎯沖埌浜嗛噸鏂板垱绔嬩釜絳夊緟榪涚▼璋冪敤CeRapiUninit鏉ュ共鎺夊畠. 涓嶈繃榪欐牱鍋氭樉鐒朵笉鍘氶亾, 鍒涚珛榪涚▼闇瑕佸崰鐢ㄦ洿澶氱殑鍐呭瓨. 鎵浠ョ敤浜嗕笂鍙ヨ鏄庣殑涓嬪崐孌?
The CeRapiInitEx function does not block the calling thread. Instead, it uses an event to signal when initialization is complete.
寤虹珛涓簨浠? 鐢╓aitForSingleObject鏉ョ瓑浠? 瓚呮椂灝盉YEBYE浜? 璐$尞鑷繁鍐欑殑濡備笅浠g爜, 浠ュ悗RAPI INIT鍙互鍙傝?br />
multi-xip瀹為檯涓婂緢鏈夌敤錛屼絾鏄幇鍦ㄦ湁涓涓負闅劇殑浜嬫儏錛氬氨鏄疧S璧鋒潵涔嬪悗鏃犳硶鍐檉lash錛岃繖涓緢璁╀漢鑻︽伡銆傛墍浠ヨ繖涔熷鑷村崌綰х▼搴忔棤娉曡緗爣蹇椾綅銆傚彧鑳界敤GPIO鍙c?/p>
Multi-xip鐨勫疄鐜幫細
1) Bib鏂囦歡鐨勪慨鏀癸細
聽聽 MEMORY
聽聽聽 RSVD聽聽聽聽 80000000聽 000FF000聽 RESERVED
聽聽聽 ARGS聽聽聽聽 800FF000聽 00001000聽 RESERVED
聽聽聽 NK聽聽聽聽聽聽 9C600000聽 01000000聽聽 RAMIMAGE
聽聽聽 APP聽聽聽聽聽 9D600000聽 00500000聽聽 RAMIMAGE
聽聽聽 CHAIN聽聽聽 9DB00000聽 00002000聽聽 RESERVED
聽聽聽 RAM聽聽聽聽聽 80100000聽 01F00000聽 RAM
聽聽聽 pdwXIPLoc 00000000 9DB00000聽 FIXUPVAR
CONFIG
聽聽聽 AUTOSIZE=ON
聽聽聽 ROM_AUTOSIZE=OFF
聽聽聽 RAM_AUTOSIZE=OFF
聽聽聽 DLLADDR_AUTOSIZE=ON
聽聽聽 XIPSCHAIN=9DB00000
聽聽聽 ROMSTART=9C600000
聽聽聽 ROMWIDTH=32
聽聽聽 ROMSIZE=01600000
聽聽聽 KERNELFIXUPS=ON
2) 鍦∣EMInit鍔犱竴涓繛鎺ュ悇涓猙in鐨勫嚱鏁幫細
void InitRomChain()
{
聽// Added for MultiXIP stuff
聽static聽 ROMChain_t s_pNextRom[MAX_ROM] = {0};
聽DWORD聽 dwRomCount = 0;
聽聽聽 DWORD聽聽聽聽聽聽 dwChainCount = 0;
聽聽聽 DWORD *聽聽聽聽 pdwCurXIP;
聽聽聽 DWORD聽聽聽聽聽聽 dwNumXIPs;
聽聽聽 PXIPCHAIN_ENTRY pChainEntry = NULL;
聽聽聽 if(pdwXIPLoc == NOT_FIXEDUP){
聽聽聽聽聽聽聽 return;聽 // no chain or not fixed up properly
聽聽聽 }
聽聽聽 // set the top bit to mark it as a virtual address
聽聽聽 pdwCurXIP = (DWORD*)(((DWORD)pdwXIPLoc) | 0x80000000);
聽聽聽 // first DWORD is number of XIPs
聽聽聽 dwNumXIPs = (*pdwCurXIP);
聽聽 if(dwNumXIPs > MAX_ROM){
聽聽聽聽聽 OALMSG(TRUE, (L"ERROR: Number of XIPs exceeds MAX\r\n"));
聽聽聽聽聽 //lpWriteDebugStringFunc(TEXT("ERROR: Number of XIPs exceeds MAX\n"));
聽聽聽聽聽 return;
聽聽聽 }
聽聽聽 pChainEntry = (PXIPCHAIN_ENTRY)(pdwCurXIP + 1);
聽聽聽 while(dwChainCount < dwNumXIPs)
聽聽聽 {
聽聽聽聽聽聽聽 if ((pChainEntry->usFlags & ROMXIP_OK_TO_LOAD) &&聽 // flags indicates valid XIP
聽聽聽聽聽聽聽聽聽聽聽 *(LPDWORD)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽聽聽聽聽 s_pNextRom[dwRomCount].pTOC = *(ROMHDR **)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET + 4);
聽聽聽聽聽聽聽聽聽聽聽 s_pNextRom[dwRomCount].pNext = NULL;
聽聽聽聽聽聽聽聽聽聽聽 if (dwRomCount != 0)
聽聽聽聽聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 s_pNextRom[dwRomCount-1].pNext = &s_pNextRom[dwRomCount];
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 else
聽聽聽聽聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 OEMRomChain = s_pNextRom;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 dwRomCount++;
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 else
聽聽聽聽聽聽聽 {
聽聽聽聽聽聽聽聽聽聽聽 OALMSG(TRUE, (L"Invalid XIP found\r\n"));
聽聽聽聽聽聽聽聽聽聽聽 //lpWriteDebugStringFunc( _T("Invalid XIP found\n") );
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 ++pChainEntry;
聽 dwChainCount++;
聽}
}
聽 榪欐槸浠嶤EPC涓嫹璐濊繃鏉ョ殑銆?/p>
閫氳繃涓婇潰鐨勮緗紝romimage浼氱敓鎴?涓猙in錛宯k.bin錛宎pp.bin錛宑hain.bin錛岃繕鏈変竴涓獂ip.bin錛屾槸涓婇潰涓変釜bin鐨勯泦鍚堜綋銆傛垜浠琩ownload鏄download xip.bin錛岃繖鏍峰氨鍙互瀹炵幇multibin銆傞氳繃璋冭瘯鍙戠幇錛孖nitRomChain灝辨槸鍒╃敤chain.bin鏉ヨ繛鎺ュ悇涓猙in鐨勩?br />榪欐牱鎴戜滑涔熺悊瑙d簡bib鏂囦歡涓繖涓鍙ョ殑鍚箟錛?br />pdwXIPLoc 00000000 9DB00000聽 FIXUPVAR
涔熷氨鏄疐IXUPVAR鐨勫惈涔夈傛垜浠湅鍒板湪浠g爜涓垜浠悓鏍峰畾涔変簡pdwXIPLoc錛岃繖鏍穜omimage鏃訛紝灝卞皢9DB00000璧嬬粰pdwXIPLoc銆傝繖灝辨槸FIXUPVAR鐨勪綔鐢ㄣ傛濡俻TOC涔熸槸鐢眗omimage璧嬪間竴鏍楓?/p>
浣滆咃細Walzer
鏃ユ湡錛?005.9.29
浠ヨ繖嬈¤鍔犲叆PC涓婁簨鍏堝仛濂界殑bookmark.htm, 鏀懼埌鏉夸笂DiskOnChip/Documents and Settings/Walzer/ 鐩綍涓嬩負渚?
棣栧厛鎶奲ookmark.htm鎷瘋礉鍒癷e.bib鐨勫悓綰х洰褰昿ublic\ie\oak\files\涓嬶紝鐒跺悗鍦╞ib閲屽寘鍚?br />bookmark.htm聽聽聽 $(_FLATRELEASEDIR)\bookmark.htm聽聽聽聽聽聽聽聽聽聽聽聽 NK SH
鍗蟲妸璇ユ枃浠舵斁鍒癗K閲岋紝DOWNLOAD涓嬪幓鍚庢槸緋葷粺闅愯棌鏂囦歡銆傜敱浜庢垜浠敤浜哅ulti-Bin鐨勫仛娉曪紝鎵浠ヨ繕寰楀湪PLATFORM涓嬬殑xip.cfg閲屾寚瀹氭柊鍔犲叆鏂囦歡鏀懼埌鍝釜BIN閲岄潰.
榪欎釜鍦扮悆浜洪兘鐭ラ亾浜嗐傞噸鐐規槸涓嬮潰鐨勫浣曟妸鏂囦歡鍦―OWNLOAD鍚庢斁鍒版寚瀹氱洰褰曢噷銆?/p>
鎵懼埌ie.dat, 閲岄潰鐨勮娉曟牸寮忓弬鑰僲s-help://MS.WindowsCE.500/wceosdev5/html/wce50conFileSystemFile.htm
鎴戝湪閲岄潰鍔犱簡涓孌?br />Directory("\DiskOnChip"):-Directory("Documents and Settings")
Directory("\DiskOnChip\Documents and Settings"):-Directory("Walzer")
Directory("\DiskOnChip\Documents and Settings\Amoi"):-File("bookmark.htm","\Windows\bookmark.htm")
鍏堝緩绔嬩袱灞傚瓙鐩綍錛岀劧鍚庢妸ROM閲岄潰鐨刡ookmark.htm鎷瘋礉鍒扮洰褰曢噷銆傚煎緱涓鎻愮殑鏄涓夎鐨勬渶鍚庝竴涓弬閲忥紝\Windows\bookmark.htm 涓嬭澆鍚庣殑鏂囦歡閮藉湪ROM閲岄潰錛孿windows灝辨槸鎸嘡OM閲岀殑鏂囦歡銆?/p>
綾諱技鐨刣at鏂囦歡榪樺緢澶氾紝SYSGEN鐨勬椂鍊欏氨鍦≒BWorkspace鐨勭浉搴擱ELEASE鐩綍閲岃儨鍒╀細甯? 鍚堝茍涓篿nitobj.tmp, 榪欎釜鏂囦歡鍜屽悎騫跺墠闆舵暎鐨勯兘涓篈SCII鐮侊紝鐒跺悗瑕佽漿鎴怳NICODE鐢熸垚initobj.dat錛屾渶鍚庢垜浠彲浠ョ湅鍒癱e.bib閲屽寘鍚簡initobj.dat榪欎釜鏂囦歡錛屽茍鍏ユ渶緇堢敓鎴愮殑BIN鏂囦歡閲屻?/p>
聽聽聽
鍦ㄤ粈涔堟儏鍐典笅搴旇鐢?/span>
Visual Studio .NET
鑰屼笉鏄?/span>
eMbedded Visual C++
鏉ヤ負
Win CE
緋葷粺寮鍙戝簲鐢ㄧ▼搴忥紵
The type of application that you want to create will dictate the choice between native and managed code (.NET). When performance and control are the highest priorities, developers should turn to eMbedded Visual C++ or native code. When a consistent programming model and time-to-market are the primary considerations, the advantages offered by Visual Studio .NET are unparalleled.
.NET Compact Framework
搴旂敤紼嬪簭鐨勮繍琛屾ц兘鏄惁鍜?/span>
eMbedded Visual C++
搴旂敤紼嬪簭涓鏍鳳紵
In most cases, applications that you write with eMbedded Visual C++ will run faster than those that you write by using Microsoft Visual Basic .NET or Microsoft Visual C# .NET. However, for computationally-intensive portions of an application, you will see a substantial improvement of your Visual Basic .NET applications over their eMbedded Visual Basic .NET equivalents.
Running an application natively refers to running an application without recompiling it for a different environment. Windows CE .NET 4.2 and Windows CE 5.0 devices can run Pocket PC applications if both of the following are true:
鈥?/span>聽聽聽聽聽 The application is designed for the same CPU architecture
鈥?/span>聽聽聽聽聽 The application calls the same API set as the Pocket PC 2003 SDK. Windows CE .NET 4.2 and Windows CE 5.0 support the same SDK APIs from CESHELL and AYGSHELL.
For more information, visit the Windows CE Application Development page.
絎竴縐嶏紝灝辨槸image宸茬粡鍦–EPC鎴栬呯粓绔笂璺戣搗鏉ヤ簡錛岄偅涔堣繖涓椂鍊欒鎯蟲坊鍔犳枃浠跺彲浠ラ氳繃PB鎴栬匛VC鎻愪緵鐨剅emote file viewer錛岃繖涓瘮杈冪畝鍗曪紝鐪嬬潃鐣岄潰鎿嶄綔灝辮浜嗐?
絎簩縐嶏紝灝辨槸瀵瑰畾鍒剁殑image宸茬粡build榪囦簡錛岀幇鍦ㄦ兂寰閲岄潰娣誨姞鏂囦歡鐨勮瘽錛屽彲浠ュ湪浣犲搴斿鉤鍙扮殑release鏂囦歡澶歸噷闈㈢洿鎺ユ坊鍔犳枃浠訛紝鐒跺悗淇敼騫沖彴閰嶇疆鏂囦歡project.bib錛岀劧鍚庡啀make image錛屼篃鍙互灝嗘枃浠舵坊鍔犲埌image涓幓錛屽皢image鍚姩鍚庯紝浼氬嚭鐜板湪windows鏂囦歡澶逛笅闈?
姣斿浣犳兂灝唗est.txt娣誨姞鍒癷mage涓紝鍒欓鍏堥渶瑕佸皢姝ゆ枃浠舵嫹璐濆埌騫沖彴release鐩綍涓嬮潰
錛堝鉤鍙皉elease鐩綍涔熷氨鏄幆澧冨彉閲廮FLATRELEASEDIR鐨勫鹼紝_FLATRELEASEDIR鐨?= %_WINCEROOT%\PBWorkspaces\%_TGTPROJ%\RelDir\%_TGTPLAT%\%_TGTCPUFAMILY%_Release錛屼篃灝辨槸realease鐩綍錛岋紙_TGTPLAT涓哄鉤鍙板悕錛宊TGTCPUFAMILY涓篊PU鍚嶏級銆傛垜鏂板緩鐨勫鉤鍙頒負shellTest錛屽叾鍊間負E:\WINCE500\PBWorkspaces\ShellTest\RelDir\MyCEPC_x86_Release 錛?
鐒跺悗鎸夌収浠ヤ笅淇敼project.bib錛?
鍦ㄥ叾涓坊鍔犵被浼艱繖鏍蜂竴琛?
test.txt$(_FLATRELEASEDIR)\test.txt NK S
榪欏彞璇濈殑鎰忔濇槸璇村皢騫沖彴release鏂囦歡澶逛笅闈㈢殑test.txt鏂囦歡娣誨姞鍒癷mage涓紝鏂囦歡灞炴т負緋葷粺鏂囦歡錛屽叧浜巄ib鏂囦歡鐨勬牸寮忥紝璇鋒煡闃匴inCE鐨勫府鍔?/p>
淇敼濂絧roject.bib鍚庯紝淇濆瓨錛岀劧鍚庡湪pb鐨刡ulid鑿滃崟涓嬮夋嫨make image錛屾垚鍔熷悗涓嬭澆鍒扮粓绔垨CEPC錛屽氨鍙互鐪嬪埌娣誨姞鐨勬枃浠朵簡銆?/p>
絎笁縐嶏紝灝辨槸騫沖彴瀹氬埗閮芥病鍋氬ソ錛屾垨鑰呭仛濂戒簡闇瑕佷慨鏀癸紝閭d箞濡傛灉浣犵洿鎺ユ寜鐓х浜岀鏉ュ仛錛岀劧鍚庨夋嫨build鑿滃崟鐨剆ysgen and build鐨勮瘽錛屼綘浼氬彂鐜版牴鏈笉浼氳test.txt鎷瘋礉鍒癷mage涓紝榪欎釜涔熸槸鎴戠殑鎯ㄧ棝鏁欒錛岃姳浜嗗ソ浜涙椂闂存墠鐭ラ亾鍘熷洜銆?/p>
涓轟粈涔堝憿錛熶粠build image鏃剁殑output紿楀彛錛屾垜姣忔閮藉彲浠ョ湅鍒癱lean up欏圭洰release鐩綍鐨勮緭鍑猴紝鐪嬫潵鎴戠洿鎺ユ妸鏂囦歡澶嶅埗鍒皉elease鐩綍鏄笉琛岀殑錛屽洜涓哄湪sysgen and build鐨勮繃紼嬩腑姝ゆ枃浠跺す浼氳娓呯┖錛岃嚜鐒舵垜鐨則est.txt涔熻娓呮帀浜嗐傞偅璇ユ庝箞鍔炲憿錛?
榪欓噷緙哄皯涓涓楠わ紝閭e氨鏄鍦ㄥ鉤鍙拌緗腑錛屼綔涓浜涢厤緗紝浠庤岃Release鐩綍鍦ㄨ娓呯┖浠ュ悗鑳藉皢鐩爣鏂囦歡浠庢湰鍦扮‖鐩樺姩鎬佸鍒跺埌release鐩綍
淇敼閰嶇疆浠ヤ究鎷瘋礉鏂囦歡鍒癛elease鐩綍鐨勪富瑕佹楠ゅ涓嬶細
1 pb涓粠platform鑿滃崟閫塻etting
2 鍦ㄥ脊鍑哄璇濇涓瑿onfiguration涓欏圭‘淇濇紜紝涓鑸粯璁ゅ氨鏄紜殑銆?
3 Custom Build Actions閫夐」鍗′腑鐨凚uild step涓嬫媺妗嗭紝閫夋嫨Pre-Make Image (鏈夊洓涓夐」錛屽垎鍒負Pre-Sysgen錛孭ost-Sysgen錛孭re-Make Image錛孭ost-Make Image錛屾剰鎬濆鍏跺悕) 錛岀劧鍚嶯ew錛屽湪寮瑰嚭鐨凜ustom Build Action瀵硅瘽妗嗕腑杈撳叆綾諱技浠ヤ笅鐨勮鍙ワ細
copy <Path>\<File name> %_FLATRELEASEDIR%\<File name>
姣斿test.txt鏀懼湪鎴戠數鑴戜笂鐨別鐩樻牴鐩綍涓嬶紝閭d箞璇彞鏄繖鏍風殑錛?/p>
copy聽E:\test.txt聽%_FLATRELEASEDIR%\test.txt
鍔犱笂榪欎釜姝ラ鍚庯紝鍐嶆寜絎簩縐嶆柟娉曞氨鍙互杈懼埌鐩殑浜嗐?/p>
VirtualCopy can be a bit confusing to use.
http://msdn2.microsoft.com/en-us/library/aa908789.aspx
Let's look at the parameters. I've commented with -- after each of them.
lpvDest
[in] Pointer to the destination memory, which must be reserved.
-- This means that the destination range of VIRTUAL memory must already be reserved by a call to VirtualAlloc(). You must have allocated a range of virtual memory that you are going to map to some physical range.
lpvSrc
[in] Pointer to committed memory.
-- This is the range of *either* VIRTUAL *or* PHYSICAL memory that you want to map the range specified by the 'lpvDest' parameter to.
If you specify a VIRTUAL address and omit the PAGE_PHYSICAL flag from the fdwProtect parameter, then you are simply saying "Copy the mapping at the lpvSrc address to the lpvDest address". This just means that there will be two ranges of virtual memory that point to the same physical range.
If you specify a PHYSICAL address (shifted right 8 bits) and include the PAGE_PHYSICAL flag in the fdwProtect parameter, then you are saying "Map the range at the lpvDest address to this specific physical address". This sets your new range of virtual memory to point to a piece of physical memory.
cbSize
[in] Size, in bytes, of the region. The allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+cbSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.
-- pretty straight forward here.
fdwProtect
[in] Type of access protection. If the pages are being committed, any one of a number of flags can be specified, along with the PAGE_GUARD and PAGE_NOCACHE, protection modifier flags. The following table shows the flags that can be specified.
-- 'Reserving' a page means you're allocating a range of virtual memory but not pointing it at anything yet. 'Commiting' a page means you are actually taking up physical storage somewhere - be it in RAM or in physical addres space. For the purposes of our discussion here, you would normally map registers and i/o space with PAGE_NOCACHE. If you used a physical address (shifted right 8 bits) in the lpvSrc parameter, then you would also specify the PAGE_PHYSICAL flag.
quetion:
If I want to access some physical memory in my driver, can I do like these way?
Method (1) define static map relationship in OEMAddressTable and reserve difined virtual address in config.bib first, then use VirtualAlloc() and VirtualCopy() without the page_physical parameter.
or (2) directly use MmMapIoSpace() or VirtualAlloc+Copy() with the page_physical parameter
answer:
Yes, either of those would work I believe. #2 is the preferred/recommended method
Monday, March 26, 2007 12:07 PM by Kurt Kennett
Wow! Lots of interest in VirtualCopy! Ok, I'll try to be super-clear here.
VirtualCopy *copies* or *sets* a range of virtual addresses.
- You use it to *copy* an existing Virtual->Physical mapping (no matter where it is).
OR
- You use it to *set* a mapping to a range of physical addresses.
In *either* case, the virtual memory you want to create the new map in must already be allocated (via VirtualAlloc()).
OEMAddressTable is a static (unchanging, available at startup without doing any work or setup) table of virtual -> physical mappings. The kernel is the only thing that has default access to the resources mapped by this table. If you are operating outside the OAL (i.e. in any kind of driver or application), you must use VirtualCopy() to copy or create memory page mappings. As mentioned above, you can copy any existing mapping as long as you have access to it. This includes a static mapping done by the OEMAddressTable. Some people will map all resources in the OEMAddressTable (so the kernel has access to everything), then just copy those mappings in drivers when they need to. This is not a best practice because it makes driver code less portable -- it is better to read the physical address of a component from the registry, then use the value found there to map to it. If you do this your driver code does not have to change if it is moved to a different platform or extended to use multiple components in different physical locations.
A mapping does not have to exist in OEMAddressTable in order for you to access the physical resources mapped. You can create a new mapping unknown to the OEMAddressTable by using VirtualCopy with the PAGE_PHYSICAL flag.
MmMapIoSpace is a CEDDK function -- it simply does the appropriate calls to VirtualAlloc/VirtualCopy. You could write your own MmMapIoSpace if you wanted to. Some people have in the past - calling the function "VirtualMemCopyPhysical" or something like that. Some platforms need to modify the MmMapIoSpace to set Virtual mapping attributes when pages are mapped (hence the original purpose for this blog entry).
Using flags like PAGE_EXECUTE_READWRITE with VirtualCopy are a 'request'. If the platform/CPU does not have a differentiation between executable pages and non-executable pages, the EXECUTE property will not be able to be set. For example, the X86 CPUs can explicitly state that memory is executable, but can't be read or written to. The ARM processors have no notion of this - you can read it or read and write it.
In Windows CE 5.0 and earlier, virtual allocations below 2MB come out of the address space of the process calling it, while allocations above 2MB come out of the shared address space.
Sue