2012年12月31日 星期一

ARM

1.了解不同記憶体的動作:因為ARM的界面為乩憶体界面(ROM/SDRAM)
2.學習ARM的assembler:BootLoad
3.C
4.compiler/debug tool
5.硬体電路:基本電源、Reset、Clock and memory
6.例外事件及中斷:Booload中的重點。或是由BSP(board support package)提供使用。
7.控制界面:UART、PWM、RTC Timer、GPIO、WTD and SPI(I2C)

故可以將其分為
基礎篇(memory、ADS and AXD)
原理篇(硬/軟開機流程、ARM操作模式及暫存器、ARM assemble及ARM 例外處理)
實務篇(記憶体控制、系統配置、時脈電源管理、看門狗、開機程序、中斷控制器、輸出入埠、C的例外及中斷處理及UART 控制)

2012年11月30日 星期五

Vim as your IDE

0.安裝中文help

中文幫助手冊的安裝

http://vcd.gro.clinux.org    (中文)

解壓後其中有個doc文件夾, 將其中的內容全部复制到~/.vim/doc, 或者vim安裝目錄下的doc目錄中, 此時vim中的help信息已經是中文的了.
注意:
a. 如果無法顯示中文, 在~/.vimrc中增加下面這句試試:
   set helplang=cn
b. 幫助文件的文本是utf-8編碼的, 如果想用vim直接查看, 需要在~/.vimrc中設置:
   set encoding=utf-8

 

 

1.TeTrIs.vim : A tetris game in pure vim

為了練習vim的樂趣及操作.

image

To start the game, press <Leader>te.
(If you don't know what is <Leader>, you should press \te, and type :help Leader<Enter> to learn about what the heck leader is)
Controls:
h: left
l: right
j: down
i,k: rotate
<Space>: drop
<Esc> or q: quit

 

2.快速瀏覽和操作Buffer -- 插件: MiniBufExplorer

上面那個狹長的窗口就是MiniBufExplorer窗口, 其中列出了當前所有已經打開的buffer, 當你把光標置於這個窗口時, 有下面幾個快捷鍵可以用:

image

<Tab>
向前循環切換到每個buffer名上

<S-Tab>
向後循環切換到每個buffer名上

<Enter>
在打開光標所在的buffer

d
刪除光標所在的buffer

let g:miniBufExplMapWindowNavVim = 1

則可以用<C-h,j,k,l>切換到上下左右的窗口中去,就像:
C-w,h j k l    向"左,下,上,右"切換窗口.

 

4.Ctag+TagList

image

接下來將 Taglist 的 Plugin 放置到 C:\Program Files\Vim\vim71\plugin 內。
在 C:\Program Files\Vim\_vimrc 設定 ctags.exe 的路徑
let Tlist_Ctags_Cmd = 'C:\ctags.exe'
再加上 map ,設定 F12 為開啟/關閉 Tag List 的快捷鍵:
nnoremap <F12> :TlistToggle<CR>

使用

1.開啓專案,按F12來產生Ctag檔

2."Enter”在buffer中開啓;

  "o” 在視窗中開啓

  "x”放大 Ctag視窗

  "space”顯示出其定義(查看函式)

5.WinManager

文件瀏覽器和窗口管理器 -- 插件: WinManager

image

文件瀏覽器: netrw.vim

在該界面上你可以用下面的一些命令來進行常用的目錄和文件操作:

<F1>
顯示幫助

<cr>
如果光標下是目錄, 則進入該目錄; 如果光標下文件, 則打開該文件

-
返回上級目錄

c
切換vim 當前工作目錄正在瀏覽的目錄

d
創建目錄

D
刪除目錄或文件

i
切換顯示方式

R
文件或目錄重命名

s
選擇排序方式

x
定制瀏覽方式, 使用你指定的程序打開該文件

 

WinManager插件來將TagList窗口和netrw窗口整合

let g:winManagerWindowLayout='FileExplorer|TagList'
nmap wm :WMToggle<cr>

參考:

http://rritw.com/a/JAVAbiancheng/ANT/20120817/206260.html

http://haridas.in/vim-as-your-ide.html

TeTrls.vim

http://www.vim.org/scripts/script.php?script_id=172

Setting Up Ctags + Gvim in Windows:

http://c9s.blogspot.tw/2007/07/setting-up-ctags-gvim-in-windows.html

Graphical vi-vim Cheat Sheet and Tutorial:

http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html

用Gvim建立IDE编程环境 (Windows篇):

http://rokin.iteye.com/blog/475274

USB系統開發工具

Bus Hound: 可顯示設備配置資訊,並能夠擷取USB主機對USB設備進行列舉的過程。

也可利用USB Hound來除錯。

使用用方法

1.在Devices tab中

image fig 1. Step 1

 

2. 介面操作

image fig 2. 設備資訊介面

3.使用

a.選擇Endpoint

b.設定USB command

c.發送

d.查看

image fig 3. 向設備發送取得設備描述資訊請求

image fig 4. 獲得設備配置描述資訊集合

4.利用Bus Hound來Capture取設備和主機所進行的過程***

image

image

 

參考資料:USB 2.0 系統開實例精解

queue

佇列;

定義

,只允許在一端進行插入操作,而在另一端中進行刪除操作的線性表(有限、有序)

其為一種先進先出(FIFO,first in first out)的線性表。

q=(a1,a2,...,an-1,an);則可設定a1為首,而an為尾。

image

queue的ADT(抽象資料類型)

ADT queue
Data
    元素為相同的類型,相鄰元素具有前後關係.
Operater
    InitQueue(*Q);//初始化,建立一個空queue
    DestoryQueue(*Q);//若queue存在,則刪除
    ClearQueue(*Q);//清除queue.
    QueueEmpty(Q);//若Q存在且為空,則回傳true
    GetHead(Q,*e);//若queue且非空,則e傳回Q首
    EndQueue(*Q,e);//若queue存在,插入新元素e到queue中.其e成為queue尾
    DeQueue(*Q,*e);//刪除queue首元素,並用e傳回
    QueueLenght(Q);//反回queue中的元素個數.
 
endADT


因為是線性表,故相同地有



順序儲存



其順序存儲時,有下列問題



image



其加入元素時,其時間O(1)



image



刪除時,則時間變為O(n)。這是因為使其queue首必須要在前面的位置上,所導致的。



而其可以改為下列,用二個變數指標來指定其首'尾.



image



 



1.空



image



2.滿



image



3.非空非滿



image



在此時,會出現"虛溢出",指還有空間(0)。但無法存放。



image



而為了改進此我們把rear放在0來形成循環,稱為循環queue



image



但其該如何來判斷其是是滿或空



方法1:



加一個flag



在初始時front==rear,flag=0.為空



若下次出現front==rear且flag==0.則改flag=1(滿)



方2:



保留一個空間。如下圖的情況即代表為滿。



image



image



而其



判斷是否為滿



(rear+1)%QueueSize==front



EX:



rear=0,front=1



((0+1)%5==1)?滿:非滿



rear=4,front=0



(4+1)%5==0? 滿



rear=4,front=1



(4+1)%5==1?非滿





長度



(rear-front+QueueSize)%QueueSize





typedef int QElemType;
typedef struct
{
QElemType data[MAXSIZE];
int front;
int rear;
}SqQueue;




Status InitQueue(SqQueue *Q)
{
Q->front=0;
Q->rear=0;
return OK;
}




int QueueLength(Q)
{
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE);




Status EnQueue(SqQueue *q,QElemType e)
{
if((q->rear+1)%MAXSIZE==q->front))
  return ERROR;
q->data[q->rear]=e;
q->rear=q->rear+1%MAXSIZE;
}




Status DeQueue(SqQueue *q, QElemType *e)
{
if(q->rear==q->front)
    return ERROR;
*e=q->data[q->front];
q->front=q->front+1%MAXSIZE;
return OK;
}


 



 



link list

2012年8月21日 星期二

vim basic

分為7個課程

一;

基本:                                                                           

h j k l 為vi/vim的方向向                                                                                                                                                                                  

i為進入插入模式. 輸入文字. 並用Esc來回到normal mode

x為刪除目前的字元, X為刪前一個(left)的字元

A 到這行的最後,並進入insert mode.

Extras:

u為回復上一動作

0 跳到行首,$則為跳行尾 ; ^則這行的第一個noo-blank

w,b,e 為沿著'words'移動(wrods is a sequence of all alphannumerc or punctuation signs)

W,B,E則為沿著'WORDS'移動(WORDS is sequence of any non-blank charater)

 

二:

Basic:

f 在這行中前往字母; F則為往後.

t及T和f相同,但是其字母的前面.

d(delete):dw,df-

c(change)同delete且進入insert mode

.  repeate 最後的動作.

Extras:

Prepend a count to any command /motion to repeat it that number of time:

d2w :刪除二個word.

d2t, :刪除到第二個comma.

2i :做二次的輸入字串 ,按Esc

cc 及 dd 為以行動作.

v 進入visual mode.V以行為單位

三:

Basic:

y : copy(也可動作在visual mode)

p : paste

P : paste before.

yy : copy current line

d,c,x : 除了動作外,也同樣有copy動作

Extras:

" + a-z :選擇yank/deltete/paste 選擇暫存器

"* or "+ :system clipboard(系統的)

四:

/ :基本的search motion

? :也是search motion 但是向後的.

n :為重複最後的search 動作, N為反向的direction

Extras:

* :search 目前遊標的words

# :同*,但是方向相反

五:

m+a-z :設定mark

`+a-z :跳到mark

'+character :跳到mark行中的,第一個non-blank

A-Z mark are global,a-z 為per-buffer

'+. 跳到最後修改的地方.

Macros :

使用q + a-z來開啓 recording.

Esc+q :exit recording.

@ + a-z : play recording

@@:play last recording.

六:

% : jump 對應的pairs of '(' ')' , '[' ,']' ,etc...

HML : jump 對scren的top ,middle/bottom

G :到檔案的最後.

-/+ :上下行移動.

( 及) 跳到目前文句(sentence)的前尾.

{及} 跳到上下一個空白行.

[[ 跳到前一個'{' 行.

]] 跳到前一個'}' 行.

七:

Basic:

J : joins the current line with the next one ,or all the lines in the current visual selection.

r + character 取代目前的一個字元.

C 同c $,修改到行尾.

D 同d $,刪除到行尾.

Y 同yy ,復制整行.

s 刪除目前的子元,並進入insert mode.

S 刪除這一行,及insert mode.

Extras:

> : indent one or more lines.

< : unindent.

~ 改變目前的字母的大小寫.

參考:

Graphical vi-vim Cheat Sheet and Tutorial

http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html

2012年6月26日 星期二

The Linux Directory Structure Explained

在一開始使用Unix-like system時,對於其檔案系統架構。最為不了解,

 

The Filesystem Hierarchy Standard (FHS) defines the structure of file systems on Linux and other UNIX-like operating systems.


/ – The Root Directory
Everything on your Linux system is located under the / directory, known as the root directory.
/bin – Essential User Binaries
The /bin directory contains the essential user binaries (programs) that must be present when the system is mounted in single-user mode.
Applications such as Firefox are stored in /usr/bin, while important system programs and utilities such as the bash shell are located in /bin.
The /sbin directory is similar – it contains essential system administration binaries.
image
image
image
/boot – Static Boot Files
The /boot directory contains the files needed to boot the system – for example, the GRUB boot loader’s files and your Linux kernels are stored here. The boot loader’s configuration files aren’t located here, though – they’re in /etc with the other configuration files.
/cdrom – Historical Mount Point for CD-ROMs
It’s a temporary location for CD-ROMs inserted in the system. However, the standard location for temporary media is inside the /media directory.
/dev – Device Files
Linux exposes devices as files, and the /dev directory contains a number of special files that represent devices.
These are not actual files as we know them, but they appear as files – for example, /dev/sda represents the first SATA drive in the system.
image
/etc – Configuration Files
The /etc directory contains configuration files, which can generally be edited by hand in a text editor. Note that the /etc/ directory contains system-wide configuration files – user-specific configuration files are located in each user’s home directory.
image
/home – Home Folders
The /home directory contains a home folder for each user. For example, if your user name is bob, you have a home folder located at /home/bob. This home folder contains the user’s data files and user-specific configuration files.
/lib – Essential Shared Libraries
The /lib directory contains libraries needed by the essential binaries in the /bin and /sbin folder. Libraries needed by the binaries in the /usr/bin folder are located in /usr/lib.
/lost+found – Recovered Files
Each Linux file system has a lost+found directory. If the file system crashes, a file system check will be performed at next boot. Any corrupted files found will be placed in the lost+found directory, so you can attempt to recover as much data as possible.
/media – Removable Media
The /media directory contains subdirectories where removable media devices inserted into the computer are mounted.
For example, when you insert a CD into your Linux system, a directory will automatically be created inside the /media directory. You can access the contents of the CD inside this directory.
/mnt – Temporary Mount Points
Historically speaking, the /mnt directory is where system administrators mounted temporary file systems while using them. For example, if you’re mounting a Windows partition to perform some file recovery operations, you might mount it at /mnt/windows. However, you can mount other file systems anywhere on the system.
/opt – Optional Packages
The /opt directory contains subdirectories for optional software packages. It’s commonly used by proprietary software that doesn’t obey the standard file system hierarchy – for example, a proprietary program might dump its files in /opt/application when you install it.
/proc – Kernel & Process Files
The /proc directory similar to the /dev directory because it doesn’t contain standard files. It contains special files that represent system and process information.
image
/sbin – System Administration Binaries
The /sbin directory is similar to the /bin directory. It contains essential binaries that are generally intended to be run by the root user for system administration.
image
/selinux – SELinux Virtual File System
If your Linux distribution uses SELinux for security (Fedora and Red Hat, for example), the /selinux directory contains special files used by SELinux.
none.
/srv – Service Data
The /srv directory contains “data for services provided by the system.” If you were using the Apache HTTP server to serve a website, you’d likely store your website’s files in a directory inside the /srv directory.
image
/tmp – Temporary Files
Applications store temporary files in the /tmp directory. These files are generally deleted whenever your system is restarted and may be deleted at any time by utilities such as tmpwatch.
/usr – User Binaries & Read-Only Data
The /usr directory contains applications and files used by users, as opposed to applications and files used by the system. For example, non-essential applications are located inside the /usr/bin directory instead of the /bin directory and non-essential system administration binaries are located in the /usr/sbin directory instead of the /sbin directory
image
/var – Variable Data Files
The /var directory is the writable counterpart to the /usr directory, which must be read-only in normal operation. Log files and everything else that would normally be written to /usr during normal operation are written to the /var directory. For example, you’ll find log files in /var/log.
image

The Linux Directory Structure Explained



















簡單字元裝置驅動程式

以字元裝置驅動來學習,建立出寫一個linux裝置驅動的結構及楖念。
以下均是以CDK EVB上做為實例。而可能在其資料或macro等在不同環境可能也有所不同。


首先,在Linux底下分為三種的裝置驅動,分別為"字元"、"區塊"及"網路"。
其中字元及區塊的驅動的分別:
1.字元
指的是那些一次只能一個位元組來進行讀寫動作的的裝置,而且無法隨機讀取裝置記憶体中的任何一個位置上的資料。如:滑、鍵盤、序列埠等
2.區塊
可以從裝置中任意位置中讀寫一定長度資料的裝置,而且讀寫資料也不必按照先後順序。如:HD、SD 'USB HD.
其各裝置可在"/dev"中查看
image

看其檔案屬性的第一位字元,c,d,b;
及裝置的主裝置編號、次編號
)










主編號及次編號和稱為裝置編號。
而主編號用表示一個特定的驅動;次編號則是用來表示是那個裝置。
(如二個LED,使用主編號10,而第一個LED的次編號可設為1;另一個為2。如此就可以分別驅動
其在linux 2.6.19中,是以dev_t來做為其裝置的編號。
A.
image
B.其對於主編號、次編號的操作
MRJOR:取得主編號
MINOR:次編號
MKDEV:裝置編號
image
















C.靜態設定
因為在linux中已預設了一些裝置編號,在使用靜態時,需去查看
image
或是直接到/proc/device檔案中查看(目前已使用)
image 
D.動態設定
為了避免別台電腦的裝置衝突,建議使用動態
alloc_chrdev_region() 申請裝置號(靜態)
由其函數說明,可得其from為dev_t(必須已有其major number) count為個數; name則為其裝置名稱
image
而為了避免發生問題,更提供了alloc_chrdev_region申請裝置號(動態)
image
E.釋放字元裝置號碼
image

F.註冊裝置到系統
在申請裝置號碼後,將下來則是要將註冊裝置到系統
F.1 ,cdev struct來描述其字元裝置
image
Char device的Structure中,它可以看成是所有字元裝置的
主要結構,裡面是所有字元裝置的抽象元素。
struc kobject kobj //用於核心裝置驅動模型的管理。
struct module *owner;//指向包含該結構的模組指標,用於參考計數。
const struct file_operation *ops;//指向字元裝置操作函數集的指標。
struct list_head list;//將字元裝置連接成一個link list.
dev_t dev;//為該裝置的起始裝置號.
unsigned int count;//該裝置的數量.

其中各元素內容之定義。多在include/linux中 (file_operations= fs.h , kobject=Kobject.h)
list_head list是與inode structure中的i_devices(也為link list)有關
其在裝置檔案開啓時,系統中就會產生一個inode出來而從其inode中的i_cdev就可找到cdev的struct了
及其ops。
image
F.2
在linux中,將各裝置都視為一個file來操作。其存取相對應函式如下。
image
ower:指向擁有這結構模組的指標。用來維持模組的參考計數,當模組還在使用時,無法使用rmmod(初始為THIS_MODULE)
llseek():改變檔案中的讀寫位置,並將其新位置回。
read():從裝置中獲取資料,傳回其資料的位元組數。
write(): 寫資料到裝置中,傳回其寫入的位元組數。
open():開啓。
release():釋放裝置。只有其裝置的參考數為0時,才可以呼叫。通常用close()來關閉,但不一定call release()。
F.3 cdev與file_operations關係
   1: static struct socle_FPGA_Driver {

   2:     int busy;

   3:     dev_t FPGA_devt;

   4:     struct class *class;

   5:     struct class_device *class_dev;

   6:     struct cdev *cdev;

   7: } socle_FPGA;

在一個字元裝置的中,必定含有其cdev。

從cdev可以有file_opeations,dev_t dev等資訊。

F.4 inode(include/linux/fs.h)

image

inode/block/superblock

可以看成inode會對應一個或多個block.

inode為其檔案的屬性及位置; 而block則為其真正的資料.

而一個字元裝置也是一個檔案。故也有它的inode。

故在使用時,也會用到。如open()中是用inode指標。用得到該節點的資訊。

int (*open) (struct inode*,struct file*);

在struct inode中,重要的有

dev_t i_rdev,表示裝置對應裝置號

struct list_head i_devices,為裝置連接對應的cdev結構。

struct cdev * i_cdev,指向cdev裝置。







G.字元裝置的模版.

字元裝置的申請和cdev的註冊。


   1: struct xxx_dev //自定device struct

   2: {

   3: struct cdev cdev; //cdev struct

   4: ...

   5: };

   6:  

   7: static int __init xxx_init(void)

   8: {

   9: ...

  10: /*申請裝置號,當xxx_major不為0時,為靜能;否則為動態

  11: if(xxx_major)

  12:     result=register_chrdev_region(xxx_devno,1,"dev_name");

  13: else

  14:     {

  15:     result=alloc_chrdev_region(&xxx_devno,0,1,"dev_name");

  16:     xxx_major=(xxx_devno);//重新取得主編號

  17:     }

  18: //初始化cdev,並傳file_opearations

  19:     cdev_init(&xxx_dev.cdev,&xxx_fops);

  20:     dev->cdev.ower=THIS_MODULE; //指定所屬模組

  21:     err=cdev_add(&xxx_dev.cdev,xxx_devno,1); //註冊裝置

  22: }

  23:  

  24: static void __exit xxx_exit(void)

  25: {

  26:     cdev_del(&xxx+dev.cdev);//註消cdev

  27:     unregister_chrdev_region(xxx_devno,1);//釋放裝置號碼

  28: }




   1:  

   2: //file_opeartions

   3: static const struct file_operations xxx_fops=

   4: {

   5:     .owner=THIS_MODULE,

   6:     .read=xxx_read,

   7:     .write=xxx_write,

   8:     .ioctl=xxx_ioctl

   9: };

  10: //read opeartion

  11: //size為資料大小; ppos為其讀寫位置

  12: static ssize_t xxx_read(struct file *file,char __user *buf,size_t size,loff_t *ppos)

  13: {

  14:   ...

  15: copy_to_user(buf,...,..);

  16: ..

  17: put_user(...,buf);

  18: }

  19: //write opeartion

  20: static ssize_t xxx_write(struct file *file,char __user *buf,size_t size,loff_t *ppos)

  21: {

  22:   ...

  23: copy_from_user(buf,...,..);

  24: ..

  25: get_user(...,buf);

  26: }

  27: ///ioctl

  28: static long xxx_ioctl(struct file*file,unsigned int cmd,unsigned long arg)

  29: {

  30: ..

  31: switch(cmd)

  32:     {

  33:     case xx_cm1:

  34:         ..

  35:         break;

  36:     case xx_cm2:

  37:         ..

  38:         break;

  39:     default:

  40:         return -EINVAL;    

  41:     }

clip_image002

參考資料:

鳥哥的 Linux 私房菜Linux 磁碟與檔案系統管理

http://linux.vbird.org/linux_basic/0230filesystem.php#inode

code:





   1: //=========================摰儔include瑼?define瑼?======================

   2: #define SOCLE_FPGA_MAJOR        0     // 0: dynamic major number

   3: #define SOCLE_FPGA_MINOR        0     //甈∠楊??

   4: #define FPGA_START            0x1CB20000

   5: #define SIZE_OF_DEVICE        (0x4000*32)

   6:  

   7: #include<linux/sched.h>

   8: #include <linux/kernel.h>

   9: #include <linux/fs.h>                     //摰儔file蝯?

  10: #include <linux/types.h>

  11: #include <linux/module.h>

  12: #include <linux/cdev.h>

  13: #include <linux/device.h>

  14: #include <linux/ioport.h>

  15: #include <asm/uaccess.h>                  //copy from/to user

  16: #include <linux/ioctl.h>

  17: #include <asm/io.h>

  18: #include <asm/system.h>

  19: #include <asm/arch/regs-pwmt.h>

  20: #include <asm/arch/hardware.h>

  21:  

  22: //=======================================================================

  23:  

  24: //============================摰儔?航炊閮憿舐內?澆?========================

  25: //#define SOCLE_FPGA_DEBUG

  26: #ifdef SOCLE_FPGA_DEBUG

  27: #define FPGA_DBG(fmt, args...) printk(KERN_DEBUG "SOCLE_FPGA: " fmt, ## args)

  28: #else

  29: #define FPGA_DBG(fmt, args...)

  30: #endif

  31: //=======================================================================

  32:  

  33: //===============================摰儔鋆蔭蝺刻?=============================

  34: static int socle_FPGA_major = SOCLE_FPGA_MAJOR;  //銝餌楊??

  35: static int socle_FPGA_minor = SOCLE_FPGA_MINOR;  //甈∠楊??

  36: module_param(socle_FPGA_major, int, 644);

  37: module_param(socle_FPGA_minor, int, 644);

  38: //=======================================================================

  39:  

  40: //==========================摰儔??蝵桃?蝯??==========================

  41: static struct socle_FPGA_Driver {

  42:     int busy;

  43:     dev_t FPGA_devt;

  44:     struct class *class;

  45:     struct class_device *class_dev;

  46:     struct cdev *cdev;

  47: } socle_FPGA;

  48: //=======================================================================

  49:  

  50: static ssize_t socle_FPGA_read    (struct file *fd, char __user *buf, size_t size, loff_t *f_pos);

  51: static ssize_t socle_FPGA_write   (struct file *fd, const char __user *buf, size_t size, loff_t *f_pos);

  52: static int     socle_FPGA_ioctl   (struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg);

  53: static int     socle_FPGA_open    (struct inode *inodep, struct file *filep);

  54: static int     socle_FPGA_release (struct inode *inodep, struct file *filep);

  55: u32 val;    //?脣?霈€撖怎???

  56: volatile unsigned long  *FPGA_wSTART;

  57:  

  58: //===========================撽?蝔?????==============================

  59: static struct file_operations socle_FPGA_fops = {

  60:          .owner = THIS_MODULE,             //摰儔??linux/module.h>

  61:      .llseek =  no_llseek,            //銝祕雿lseek

  62:        .read = socle_FPGA_read,         //敺ernel-sapce?酌ser-space

  63:       .write = socle_FPGA_write,        //敺ser-space?逃ernel-space

  64:       .ioctl = socle_FPGA_ioctl,        //鋆蔭撠惇?誘

  65:        .open = socle_FPGA_open,         //??獢?

  66:     .release = socle_FPGA_release       //?鋆蔭瑼?

  67: };

  68: //=======================================================================

  69:  

  70: //=========================Application霈€????========================

  71: static int socle_FPGA_read(struct file *fd, char __user *buf, size_t size, loff_t *f_pos)

  72: {

  73:        val=ioread32(FPGA_wSTART);

  74:     mb();

  75:        copy_to_user(buf, &val,size);

  76:     return 0;

  77: }

  78: //=======================================================================

  79:  

  80: //=========================Application摮鞈?=========================

  81: static int socle_FPGA_write(struct file *fd, const char __user *buf, size_t size, loff_t *f_pos)

  82: {

  83:        copy_from_user(&val, buf, size);

  84:     iowrite32(val,FPGA_wSTART);

  85:     mb();

  86:     return 0;

  87: }

  88: //=======================================================================

  89:  

  90:  

  91: //============================摰儔撠惇?誘===============================

  92: static int socle_FPGA_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg)

  93: {

  94:     

  95:     return 0;

  96: }

  97: //=======================================================================

  98:  

  99: //===================?箏?蝥?璆剝€脰?敹???????=========================

 100: //ex:瑼X鋆蔭?寞??隤扎€璅?蝵桀?憪???逆_op??蝑?

 101: static int socle_FPGA_open(struct inode *inodep, struct file *filep)

 102: {

 103:  

 104:     FPGA_DBG("socle_FPGA_open\n");

 105:  

 106:        return nonseekable_open(inodep,filep);

 107: }

 108: //=======================================================================

 109:  

 110:  

 111: //================?鋆蔭瑼??逵ile撠◤???鋡怨孛??===================

 112: //ex:?open?脣??審ilp->private_data?镼?

 113: static int socle_FPGA_release(struct inode *inodep, struct file *filep)

 114: {

 115:  

 116:     FPGA_DBG("socle_FPGA_release\n");

 117:     return 0;

 118: }

 119: //=======================================================================

 120:  

 121:  

 122: //=====================??cdev_init()???迨蝯?=======================

 123: static int socle_FPGA_setup_cdev(struct socle_FPGA_Driver *p_FPGA)

 124: {

 125:     int ret, err;

 126:  

 127:     p_FPGA->FPGA_devt = MKDEV(socle_FPGA_major, socle_FPGA_minor);

 128:     

 129:     if (socle_FPGA_major) {

 130:     ret = register_chrdev_region(p_FPGA->FPGA_devt, 1, "FPGA-Driver");

 131:     } else {

 132: ret = alloc_chrdev_region(&p_FPGA->FPGA_devt, socle_FPGA_minor, 1, "FPGA-Driver");

 133:         socle_FPGA_major = MAJOR(p_FPGA->FPGA_devt);

 134:         socle_FPGA_minor = MINOR(p_FPGA->FPGA_devt);

 135:     }

 136:     if (ret < 0)

 137:         return ret;

 138:  

 139:     p_FPGA->class = class_create(THIS_MODULE, "socle-FPGA-Driver");

 140:     if (IS_ERR(p_FPGA->class)) {

 141:        printk("socle_FPGA_setup_cdev: Can't create FPGA Driver class!\n");

 142:         ret = PTR_ERR(p_FPGA->class);

 143:         goto error1;

 144:     }

 145:     p_FPGA->cdev = cdev_alloc();        

 146:     if (NULL == p_FPGA->cdev) {

 147:         printk("socle_FPGA_setup_cdev: Can't alloc FPGA Driver cdev!\n");

 148:         ret = -ENOMEM;

 149:         goto error2;

 150:     }

 151:  

 152:     p_FPGA->cdev->owner = THIS_MODULE;

 153:     p_FPGA->cdev->ops = &socle_FPGA_fops;

 154:  

 155:     err = cdev_add(p_FPGA->cdev, p_FPGA->FPGA_devt, 1);

 156:     if (err) {

 157:         printk("socle_FPGA_setup_cdev: Can't add FPGA cdev to system!\n");

 158:         ret = -EAGAIN;

 159:         goto error2;

 160:     }

 161:  

 162: p_FPGA->class_dev = class_device_create(p_FPGA->class, NULL, p_FPGA->FPGA_devt, NULL, "FPGA-Driver");

 163:     if (IS_ERR(p_FPGA->class_dev)) {

 164:     printk("socle_FPGA_setup_cdev: Can't create FPGA class_dev to system!\n");

 165:         ret = PTR_ERR(p_FPGA->class_dev);

 166:         goto error3;

 167:     }

 168: printk("FPGA-Driver_class_dev info: FPGA-Driver (%d:%d)\n", MAJOR(p_FPGA->FPGA_devt), MINOR(p_FPGA->FPGA_devt));

 169:  

 170: //=================request_mem_region==========================

 171:        if(!request_mem_region(FPGA_START,SIZE_OF_DEVICE*4,"socle_FPGA"))

 172:            {

 173:             printk("error:Request_mem_region\n");

 174:             return -ENODEV;

 175:            }

 176: //========ioremap_nocache==========

 177:     FPGA_wSTART=(unsigned long *) ioremap_nocache(FPGA_START,SIZE_OF_DEVICE*4);

 178:  

 179:  

 180: printk("FPGA> socle_FPGA_ioport_write  : %p\n",FPGA_wSTART);

 181: //=============================================================================

 182:  

 183:  

 184:     return 0;

 185:  

 186: error3:

 187:     cdev_del(p_FPGA->cdev);

 188: error2:

 189:     class_destroy(p_FPGA->class);

 190: error1:

 191:     unregister_chrdev_region(p_FPGA->FPGA_devt, 1);

 192:     return ret;

 193: }

 194: //=======================================================================

 195:  

 196: //============================頛?詨??銵?=============================

 197: static int __init socle_FPGA_init(void)

 198: {

 199:     int ret = 0;

 200:  

 201:     socle_FPGA_setup_cdev(&socle_FPGA); //_init()???ocle_FPGA_setup_cdev

 202:  

 203:     return ret;

 204: }

 205: //=======================================================================

 206:  

 207: //===========================?頂蝯梯酉瘨酉??==============================

 208: static void socle_FPGA_remove_cdev(struct socle_FPGA_Driver *p_FPGA)

 209: {

 210:     class_device_unregister(p_FPGA->class_dev);

 211:     cdev_del(p_FPGA->cdev);

 212:     class_destroy(p_FPGA->class);

 213:     unregister_chrdev_region(p_FPGA->FPGA_devt, 1);

 214: //========ioremap_nocache==========

 215:         iounmap((void *)FPGA_wSTART);

 216:  

 217:        release_mem_region(FPGA_START,SIZE_OF_DEVICE*4);

 218: }

 219: //=======================================================================

 220:  

 221: //=========================蝯?撽?蝔?撌乩?===============================

 222: static void __exit socle_FPGA_cleanup(void)

 223: {

 224:     socle_FPGA_remove_cdev(&socle_FPGA);

 225:  

 226: }

 227: //=======================================================================

 228:  

 229:  

 230: module_init(socle_FPGA_init);

 231: module_exit(socle_FPGA_cleanup);

 232:  

 233: MODULE_DESCRIPTION("Socle FPGA Driver");

 234: MODULE_LICENSE("GPL");