- 12月 02 週四 201011:04
DesireHD ROM移植HD2近況
- 10月 29 週五 201015:57
ActiveX開發:錯誤代碼:0x80070002
{
HRESULT hr; // HResult used by Safety Functions
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleUnregisterTypeLib(_tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);
// Remove entries from the registry.
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if (FAILED(hr)) return hr;
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
if (FAILED(hr)) return hr;
return NOERROR;
}
- 7月 27 週二 201006:11
Linux Driver基礎篇-編譯與掛載
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
- 7月 26 週一 201011:52
Linux Driver 字元型基礎篇
1. 引入標頭檔
在撰寫 driver 前必須先 include 一些標頭檔:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
2. 撰寫控制元件的函式
struct file_operations 即為定義各個 function pointer 的 structure。
static ssize_t drv_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
{
printk("device read\n");
return count;
}
static ssize_t drv_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
{
printk("device write\n");
return count;
}
static int drv_open(struct inode *inode, struct file *filp)
{
printk("device open\n");
return 0;
}
int drv_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
printk("device ioctl\n");
return 0;
}
static int drv_release(struct inode *inode, struct file *filp)
{
printk("device close\n");
return 0;
}
struct file_operations drv_fops =
{
read: drv_read,
write: drv_write,
ioctl: drv_ioctl,
open: drv_open,
release: drv_release,
};
3. 撰寫初始化、結束元件的函式
#define MAJOR_NUM 60
#define MODULE_NAME "DEMO"
static int demo_init(void) {
if (register_chrdev(MAJOR_NUM, "demo", &drv_fops) < 0) {
printk("<1>%s: can't get major %d\n", MODULE_NAME, MAJOR_NUM);
return (-EBUSY);
}
printk("<1>%s: started\n", MODULE_NAME);
return 0;
}
static void demo_exit(void) {
unregister_chrdev(MAJOR_NUM, "demo");
printk("<1>%s: removed\n", MODULE_NAME);
}
module_init(demo_init);
module_exit(demo_exit);
其中 MAJOR_NUM 即為 driver 所對應的 device 的 major number
- 7月 12 週一 201011:05
軀動程式開發
軀動程式本身是屬於「軟體硬介面」的程式設計技術,不管是學習WinCE或是Embedded Linux,最精彩的部份絕對是驅動程式莫屬。由於嵌入式系統整體來看,除了軟體開發外,也包含硬體的客制化,因此驅動程式在嵌入式系統技術領域中,佔了舉足輕重的地位。
學習驅動程式需要確實瞭解硬體的規格與微處理器架構,並且工程師還要能分得清楚哪些東西是介面(interfacing)也就是與硬體無關的程式(machine-independent);以及哪些是站在第一線做硬體控制的程式(machine-dependent)。各種軟體硬介面與滙流排也都要精通。
現在的嵌入式系統學習主軸
現今嵌入式系統的實作,幾乎都會加入嵌入式作業系統(embedded OS)的元素,有了作業系統,我們都可以為目標裝置「寫軟體」。總合來看,如果要學習所謂的嵌入式系統,從熱門的WinCE或Embedded Linux領域切入是相當不錯的選擇。
驅動程式是「寫軟體」與「做硬體」的 “connectivity”,因此現今資訊業界最熱門的嵌入式系統學習主軸為驅動程式的設計。
WinCE驅動程式
WinCE驅動程式的核心人物當然就是在WDM(Windows Driver Model)身上了。WDM是Windows 98/2000之後的驅動程式架構,WDM是一個嚴密的分層(layered)架構,架構層間以IRPs(I/O Request Packets)做通訊。
WDM驅動程式分為三種類型:bus driver、function driver與filter driver。Bus driver是device-independent的驅動程式,主要在驅動I/O bus,例如:PCI bus driver、USB bus driver;function driver是 “device” 的驅動程式,我們常講的「驅動程式設計」大部份都是講 function driver,function driver 主要在驅動各種裝置,因此大多是由裝置廠造商撰寫並提供給使用者安裝,function driver 的設計大多著墨在「讀/寫」外部裝置。Filter driver是非必要的驅動程式,主要在過瀘 I/O requests。
WDM驅動程式的設計是使用Windows DDK,學習資源豐富並且完整;相較於Linux驅動程式,WDM驅動程式的學習材料較系統化。
Linux驅動程式
Linux驅動程式採取嚴謹的分層式架構設計(layered architecture),利用分層的架構設計來徹底區分generic device driver(machine independent)與machine dependent driver。
Linux驅動程式採用分層架構的觀念設計,透過「註冊」與「回呼」的機制來清楚地區分每一層的關係。分層架構的實作必須在下層將自己註冊給上層,上層再回呼下層;上層的驅動程式必須提供註冊函數供下層呼叫,下層驅動程式所使用的註冊函數也將決定自己的上層架構。
與 user application 如何互動,是撰寫驅動程式時所要考慮的重要一環,因此在撰寫驅動程式時,要提供什麼「功能」給應用程式引用,就必須事先定義清楚。Linux的generic device driver層已經幫我們把這些功能定義清楚了。Linux驅動程式如何透過 I/O port 或 I/O memory來控制裝置,也就是與晶片組的溝通,方式是使用 Linux kernel 所提供的I/O函數來存取並控制實體硬體裝置。
Linux驅動程式的學習困難度較高,並且也沒有像是Windows DDK這樣的完整開發工具;但是若能掌握正確的學習步驟,要邁向高手之路並非遙不可及。
-- 作者/陳俊宏 (jollen)
原文刊載於 Run! PC 雜誌 8 月號
歡迎任意轉貼引用.但請務必註明出處
- 6月 16 週二 200909:52
LINQ to SQL
http://www.asp.net/learn/linq-videos/
Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
Part 4: Updating our Database
Part 5: Binding UI using the ASP:LinqDataSource Control
Part 6: Retrieving Data Using Stored Procedures
Part 7: Updating our Database using Stored Procedures
Part 8: Executing Custom SQL Expressions
Part 9 - Using a Custom LINQ Expression with the <asp:LinqDatasource> control
- 6月 05 週五 200914:33
RTX51 Tiny的任務切換
RTX51 TINY的任務切換共有 TASKSWITCHING 和SWITCHINGNOW兩個入口,前者供定時器Timer0的中斷服務程序,後者供系統函數os_delete和os_wait使用。相應地也有兩個不同的出口,分別是恢復保護現場和清除狀態標誌位。系統首先將當前任務置為「TIMEOUT」狀態,等待下一次時間片循環,然後找到下一個處於「READY」狀態的任務,通過堆棧管理,將自由堆棧空間分配給該任務,使其成為當前任務。清除使該任務進入「READY」或「TIMEOUT」狀態的相關位後,執行該任務。
- 10月 09 週四 200820:00
[WinCE]將FTPD帳號密碼
- 10月 08 週三 200817:39
啟動FTPD in WinCE
"IsEnabled"=dword:1
"UseAuthentication"=dword:1
"AllowAnonymous"=dword:1
"AllowAnonymousUpload"=dword:1
"DefaultDir"="\\temp"
- 10月 03 週五 200810:53
變更網路卡IP for WinCE
首先,要修改網卡IP就必須先知道網卡資訊在註冊表的位置與CreateFile時需要用的設備名稱。對於「設備名稱」,若系統只有單一網卡通常都會是"NDS0:",若是多張網卡就要找該網卡的Index了,沒錯,就是到BuiltIn區找驅動程式的設定,到下面位置取得下列兩參數:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\網卡名稱]
"Prefix"="NDS"
"InstanceIndex"=dword:1