目前分類:系統開發經驗與心得 (26)

瀏覽方式: 標題列表 簡短摘要

Desire版核心移植HD2已全,大部分作者都換跑道改移植DHD rom,因為有原始的zImage所以移植很快,以下是GPC做的版本,功能差不多都OK只有點小頓。


傑克鼠 發表在 痞客邦 留言(2) 人氣()

開發ActiveX時候,原本程式執行好好的,註冊OCX/反註冊OCX都很正常,當照著MSDN步驟進行安全碼加註後,每次返註冊OCX都會出現DllUnregisterServer函數出錯,錯誤代碼:0x80070002 可能不敢相信,但以下是MSDN程式碼:

STDAPI DllUnregisterServer(void)
{
   HRESULT hr; // HResult used by Safety Functions
   AFX_MANAGE_STATE(_afxModuleAddrThis);

傑克鼠 發表在 痞客邦 留言(0) 人氣()

先前介紹了一個簡單的字元範例,這個範例不需要任何硬體線路單純只使用printk函數輸出,一個標準的HELLO WORLD程式。那建立完範本該如何編譯? 如何掛載? 如何使用? 往後一一講解。

首先我的開發環境是使用ubuntu,核心版本是2.6.24,PC環境基本上用哪個版本的套件對以下步驟無多大影響,在這先以PC環境為主,往後在介紹ARM的cross compiler。而我們開發的是linux driver,因此編譯的時候linux核心src是不能缺少,所編譯的driver版本與核心版本必須是近似甚至相同的,反則會面臨雖然編譯程公卻無法掛載的命運,所幸PC環境上的套件都會有src,因此這部分無需擔心。

現在先將先開啟一新的資料夾,並將先前介紹的範本檔案建立存入該資料夾中。在開一個新檔案叫Makefile,對linux開發不熟的可能對此檔不清楚,這是make編譯程式的批次檔,方便開發使用,該檔案內容如下:

TARGET=demo
KDIR:=/lib/modules/$(shell uname -r)/build PWD:=$(shell pwd) obj-m:=$(TARGET).o default: make -C $(KDIR) M=$(PWD) modules clean: rm -rf *.o *.ko modules.* Modules.* *.mod.c

存檔即可,此批次檔TARGET設的參數將為該資料夾編譯後的檔名,在此設定為demo,編譯後產生demo.ko為我們所要掛載的driver module。之後在該資料夾下打入make即可編譯成功。

傑克鼠 發表在 痞客邦 留言(1) 人氣()

1. 引入標頭檔

在撰寫 driver 前必須先 include 一些標頭檔:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

傑克鼠 發表在 痞客邦 留言(0) 人氣()

軀動程式本身是屬於「軟體硬介面」的程式設計技術,不管是學習WinCE或是Embedded Linux,最精彩的部份絕對是驅動程式莫屬。由於嵌入式系統整體來看,除了軟體開發外,也包含硬體的客制化,因此驅動程式在嵌入式系統技術領域中,佔了舉足輕重的地位。

學習驅動程式需要確實瞭解硬體的規格與微處理器架構,並且工程師還要能分得清楚哪些東西是介面(interfacing)也就是與硬體無關的程式(machine-independent);以及哪些是站在第一線做硬體控制的程式(machine-dependent)。各種軟體硬介面與滙流排也都要精通。

 

現在的嵌入式系統學習主軸

現今嵌入式系統的實作,幾乎都會加入嵌入式作業系統(embedded OS)的元素,有了作業系統,我們都可以為目標裝置「寫軟體」。總合來看,如果要學習所謂的嵌入式系統,從熱門的WinCE或Embedded Linux領域切入是相當不錯的選擇。

驅動程式是「寫軟體」與「做硬體」的 “connectivity”,因此現今資訊業界最熱門的嵌入式系統學習主軸為驅動程式的設計。

傑克鼠 發表在 痞客邦 留言(0) 人氣()

說道.Net Framework 3.5最強的新功能,莫過於LINQ了,它簡化了更多資料處理的指令,讓設計者有更多的時間關注在系統核心,其中,最不可思議的莫過於LINQ to SQL這部份,方便的感動如同小弟當年乍見的Typed DataSet,LINQ to SQL更直覺的解決資料庫的操作,底下有幾部影片範例,無須多言,看完就能知道他的強大。


傑克鼠 發表在 痞客邦 留言(0) 人氣()

RTX51 Tiny是基於Timesharing的RTOS,與系統中斷不同,它以非搶佔式的任務切換。所以在一個任務被執行時不能對其進行中斷,除非該任務主動放棄CPU的資源,中斷才可以打斷當前的任務,中斷完成後把CPU的控制權再交還該被中斷的任務。任務切換有兩種情況,一種是當前任務主動讓出CPU資源;另一種情況是在當前任務的時間片已經用完的情況下,進行任務切換。CPU執行時間被分成若干個時間片,RTX51 TINY為每個任務分配一個時間片。時間片是通過對變量INT_CLOCK與TIMESHARING兩個參數的設置來確定的。系統內定INT_CLOCK為10000、TIMESHARING為5,如果晶振頻率為11.059 2 MHz,則最大的時間片為(1/11.0592Mhz)×10000×5=4.52ms。

RTX51 TINY的任務切換共有 TASKSWITCHING 和SWITCHINGNOW兩個入口,前者供定時器Timer0的中斷服務程序,後者供系統函數os_delete和os_wait使用。相應地也有兩個不同的出口,分別是恢復保護現場和清除狀態標誌位。系統首先將當前任務置為「TIMEOUT」狀態,等待下一次時間片循環,然後找到下一個處於「READY」狀態的任務,通過堆棧管理,將自由堆棧空間分配給該任務,使其成為當前任務。清除使該任務進入「READY」或「TIMEOUT」狀態的相關位後,執行該任務。


傑克鼠 發表在 痞客邦 留言(1) 人氣()

前篇簡單說明如何啟動WinCE上的FTPD功能,當然前提是必須在Platform Builder就已加入FTPD功能。但前所提的方式是以匿名方式存取WinCE FTPD,在獨立網域系統內這是最簡單便捷的方式,但若在開放網路環境下這方法就十分不保險,任何有心人士都能輕易找到這個匿名節點,所以至少要設專用的帳號密碼,以下說明如何讓WinCE FTPD具有登入特定帳號的功能。

Private Sub SetFTPD(byVal User as string, ByVal Password as string )

     NTLMSetUserInfo(User , Password )

     Dim strKeyName As String = "HKEY_LOCAL_MACHINE\Comm\FTPD"

     Microsoft.Win32.Registry.SetValue(strKeyName, "AllowAnonymousUpload", 0)

     Microsoft.Win32.Registry.SetValue(strKeyName, "AllowAnonymous", 0)

     Microsoft.Win32.Registry.SetValue(strKeyName, "UseAuthentication",1)

     Microsoft.Win32.Registry.SetValue(strKeyName, "IsEnabled", 1)

     Microsoft.Win32.Registry.SetValue(strKeyName, "DefaultDir", "\")

     Microsoft.Win32.Registry.SetValue(strKeyName, "UserList", User)

End Sub

首先在WinCE內創造一給FTPD專用的獨立帳號,在此WinCE是用NTLMSetUserInfo這個函數函數,其P/Inoke如下:

<DllImport("ntlmssp.dll")> _

Public Shared Function NTLMSetUserInfo(ByVal pszUser As String, ByVal pszPassword As String) As Boolean

End Function

之後再根據前篇文章的介紹,將Anonymous兩個權限關閉、認證和FTPD設定開啟狀態,並碼使用者清單(UserList)只設給該使用者即可。

傑克鼠 發表在 痞客邦 留言(0) 人氣()

WinCE內建有簡單的FTPD服務,內定是關閉的,可透過修改註冊表將之開啟:

[HKEY_LOCAL_MACHINE\Comm\FTPD]
    "IsEnabled"=dword:1
    "UseAuthentication"=dword:1
    "AllowAnonymous"=dword:1

傑克鼠 發表在 痞客邦 留言(0) 人氣()

想要用程式來變更WinCE的網路卡IP,微軟可能認為嵌入式系統的網卡IP在設備安裝後就不會更動,原因未知,但就是未提供方便API方便修改,因此想要更改IP就必須從修改Registry註冊表下手。

首先,要修改網卡IP就必須先知道網卡資訊在註冊表的位置與CreateFile時需要用的設備名稱。對於「設備名稱」,若系統只有單一網卡通常都會是"NDS0:",若是多張網卡就要找該網卡的Index了,沒錯,就是到BuiltIn區找驅動程式的設定,到下面位置取得下列兩參數:

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\網卡名稱]
   "Prefix"="NDS" 
   "InstanceIndex"=dword:1 

傑克鼠 發表在 痞客邦 留言(3) 人氣()

【簡介】嵌入式系統應用很廣泛,無論家庭生活至工業生產都能有其應用範圍,對於家用而言,系統正常工作並非必要,不穩至停板只要一個Reset紐就可以解決,但對於工業應用而言,任何不正常的控制命令都可能導致重大損失。因此以「正常工作」是首要條件,「WatchDog Timer」這無時無刻監視著系統的小狗便是一個直接有效的工具,當系統遲緩或停擺時,可立刻發現並執行必要的工作。

【觀念】從軟體開發者的角度而言,「WatchDog Timer」就是一個倒數裝置,當時間倒數至0就會執行一內定工作,一般是給予Reboot,所以,程式必須在倒數結束內必須給予Strobe,告知狗狗程式還正常運行,狗狗將會恢復倒數時間重新倒數,如此週而復始的監視系統。

【實現】當然WatchDog這樣簡單的程式邏輯用一個高優先的執行緒便可搞定,但對於「監視」這樣重要的工作我是比較喜歡硬體中斷,在硬體上能選擇有此功能最好。在此以硬體WatchDog Timer為範例。

控制命令相當簡單,只需用CreateFile與DeviceIOControl配合IOCTL code即可,開啟方式:

m_hWDT = CreateFile(_T"WDT1:", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

傑克鼠 發表在 痞客邦 留言(2) 人氣()

一般錯誤的發生通常是在程式執行下,很容易在Debug-Mode或用Try Catch抓出,但這個Exception發生的時機與一般不同,並非出現在某行指令執行,因此光只是在事件or方法中用Try Catch包死死就可以抓出皮漏,至少在我發生的時機,完全無法取得錯誤資訊,害我被這個可惡的Bug攪和了一整天,好不容易才找到原因。
稍為描述我遇到這個Exception,由於是在WinCE環境下發生,當下沒有抓圖軟體可以用,完整的錯誤如下:

Fatal Application Error
Application TD_Control.exe has performed an illegal operation and will be shut down.

傑克鼠 發表在 痞客邦 留言(2) 人氣()

當多個執行緒在共用變數的時候,首要小心遇到死結問題,基本發生原因為其一執行緒Lock住變數,導致其他執行緒無窮境的等待,想起來似乎不容易發生,確實當整個程式只共用一組變數,這種問題很容易避免,但若在同一時間內到兩個以上的變數,這種死結是很容易發生的,以下簡單的範例 。

範例:

下兩個執行緒的程式碼,其中含有兩個將共用的物件 Object_A 和 Object_B:

 

Thread 1

傑克鼠 發表在 痞客邦 留言(1) 人氣()

連接至WinCE偵錯方法:

WinCE設備的設定

  1. 到安裝VS.NET的電腦中的 C:\Program Files\Common Files\microsoft shared\CoreCon\1.0\Target\wce400 裡面,選擇你用的CPU,如x86,到該資料夾裡面,將相關檔案複製一份到WinCE裝置任意資料夾下。
  2. 開啟你的Windows CE裝置,用「檔案總管」到複製檔案的地方,先執行"ConmanClient2.exe",之後執行"CMAccept.exe",這兩個直行後都是沒有介面會跑出來的,所以確定有去執行它就可以了。

 

VS.NET的設定

  1. 到VS2005功能表 「工具」→「選項」後,展開「裝置工具」的節點,選擇裝置,在右邊烈表找到Windows CE裝置,之後選擇「屬性」,在傳輸部分是選擇「TCP連接傳輸」,點擊畫面右邊的一個「設定」按鈕,將「裝置IP位址」設定為「使用特定IP位址」,並在下方設定你的裝置IP。
  2. 在3分鐘之內,從開發電腦的VS.NET開始偵錯,會出現選項,選擇"Windows CE 裝置",過一下子你會看到VS.NET的StatusBar會顯示在部屬的物件,如.NET CF等等,完成之後就可以遠端偵錯了。

傑克鼠 發表在 痞客邦 留言(0) 人氣()

最近敝人在WinCE-based上開發的模組越來越龐大,另一方面是IO處理頻繁,執行一兩天就會因資源不足導致Shutdown。沒錯,資源對於WinCE而言一直都是相當棘手的問題,畢竟WinCE的記憶體和虛擬記憶體空間都不像桌上型電腦龐大,可以想怎麼用就怎麼用。因此,當我們針對WinCE模組設計時,除了程式資源分配盡量優化外,更重要的是需考慮其模組資源上的使用與釋放,如此的系統才能經的起長時間的考驗。以下是網路一篇文章,我覺得很淺顯易懂,在此就暫時引用一下這位高手的文獻,供大家參考:

 

(作者:史帝芬)


    .Net framework和Java VM一樣針對一般資源會自動回收,對於

傑克鼠 發表在 痞客邦 留言(0) 人氣()

這兩天為了替同事上課,整理一些基礎的組合語言資料,本來想說用google大神剪剪貼貼就搞定,但發現一件十分有趣的事,就是這lea與mov兩個指令,似乎都說是「近似」的指令,讓人非常傻眼,還很少人更正,是這種低級語言....不不低階語言已經乏人問津了還是忽視,反正我也在整理資料,順便寫一下,這兩個天壤之別的指令到底差在哪裡。

  • Lea傳遞變數位置
  • Mov傳遞變數數值

學過C++的,應該很容易了解吧~~就是指指標的 *X1 語 &X1。我也很納悶為什麼那麼多人會說兩者差不多,我想,可能為誤會的原因應該是組語「字串」傳遞所害的,舉例來講:

lpCaption="Caption"
lpText="Hello World!"

_asm

傑克鼠 發表在 痞客邦 留言(2) 人氣()

 

Sub WriteBit(ByRef Data As byte,ByVal BitIndex As Integer, ByVal NewBit As Boolean)

If NewBit = True Then
Data = Data And Math.Pow(2, BitIndex)
Else

傑克鼠 發表在 痞客邦 留言(3) 人氣()

WinCE.NET兩個重要函數之一Coredll.dll,為方便查詢將清單列於此: 

  1 SystemStarted  
  2 InitializeCriticalSection  
  3 DeleteCriticalSection  
  4 EnterCriticalSection  

傑克鼠 發表在 痞客邦 留言(0) 人氣()

WinCE系統若想要重新啟動,沒有.NET的Managed函數可用,須倚靠 Coredll.dll的KernelIoControl完成,以下是用Managed包裝後的重啟函數,使用方法很簡單,直接呼叫ResetSystem()即可:

Private Const FILE_DEVICE_HAL As Integer = &H101

Private Const METHOD_BUFFERED As Integer = 0
Private Const FILE_ANY_ACCESS As Integer = 0

傑克鼠 發表在 痞客邦 留言(0) 人氣()

多執行緒(MultiThread)是系統效能的強力工具,可以將原本低效率的程式以分工的方式提升數倍,對於核心開發的工作,如WinCE,多執行緒變成不可不熟悉的技術,例如處理IO,當大量資料進入系統的時候,總不能讓User看到系統發呆的難看景象吧~那誰要買我們的系統呢?

還好,微軟強大的軟體工程師幫你簡化的這方面的問題,對於多執行緒的開發,兩行指令就能處置,當然,除了「開線」外,其他還有很多必須知道的事,例如非同步執行緒的資料同步問題、各執行緒與UI之間的溝通等等,在此先稍微開場,如何開多線。

標準的執行緒開啟:

Dim mythread As New System.Threading.Thread(AddressOf myProccess)

mythread.Start()

Private Sub myProccess()

.....

End Sub

指令相當簡單,開啟一個新的執行緒去執行myProccess()副程式,當然你可以用mythread.Name為這個執行緒命名,其中執行緒也含有一些方法,如Abort,但在經驗來講WinCE中似乎並非每次都管用,所以我的建議myProccess副程式最好內寫好退出執行緒的路子,免的出現關閉程式還是沒辦法結束副執行緒的窘境。

第二個方法執行緒集區(ThreadPool),是用隨時會有大量執行緒需求,而每個執行緒執行時間短且都會釋放時,會選擇使用ThreadPool,以前想達程ThreadPool的要考慮的問題很多,NET已經簡化這些問題了,事實上當開啟一NET程式,CLR已經提供我們一顆CPU 25條的ThreadPool使用,其使用方式也很簡單:

Dim myCallback As New System.Threading.WaitCallback(AddressOf myProccess)

System.Threading.ThreadPool.QueueUserWorkItem( myCallback , Sendata)

Private Sub myProccess(Byval state as Object)

.....

End Sub

其中WaitCallback是執行緒集區執行緒執行的回呼方法,若要建立委派,您可以將回呼方法傳遞至 WaitCallback 建構函式,比較需要注意的是其副程式要含有傳入參數state,這是必要格式。之後只要使用ThreadPool.QueueUserWorkItem即可交給CLR管理我們的ThreadPool,程式非常簡潔就能提升效能,M$真的是太貼心了。


傑克鼠 發表在 痞客邦 留言(0) 人氣()

1 2