星期六, 5月 12, 2007

DIP 驅動程式

V1.1

copyright@2006

email: mesmerli@hotmail.com

DIP 驅動程式實驗步驟

Host 端

  1. root file system 組態設定。
    1. 建構新的 root file system (RAMDISK)
      1. dd if=/dev/zero of=ext2new bs=1k count=8192
      2. mke2fs -F -m0 -I 2000 ext2new
      3. mount -w -o loop ext2new /mnt/loop
      4. mount -w -o loop ext2org /mnt/looporg
      5. cp -dpR /mnt/looporg/. /mnt/loop/.
      6. cd /mnt/loop/dev (/dev 檔案夾下,建立 裝置節點)
      7. mknod 777 dip0 c 43 0
      8. cd /
      9. umount -l /mnt/loop
      10. gzip -9 ext2new
    2. 重新燒錄 root file system。
  2. 建構 DIP 驅動程式
    1. 進入 dip-demo 目錄
    2. make

Taget 端

  1. 使用 NFS 的方式,mount host 端的目錄,以存取剛剛建立的 DIP 驅動程式。
    1. mount 192.168.0.200:/usr/src/creator/nfs /mnt

  1. 安裝驅動程式

    1. cd /dev
    2. mknod -m 777 dip0 c 43 0
    3. cd /mnt/Day3/char-driver/dip-demo
    4. insmod dip-creator.o
  2. 執行應用程式
    1. ./dip-demo.exe

dip-creator.c

// --------------------------------------------------------------------
//
// Title : dip-creator.c
// :
// Library :
// :
// Developers: MICROTIME MDS group (V1.0)
// : mesmerli@gmail.com (V1.1)
// :
// Purpose : Driver for DIP of Creator
// :
// Limitation:
// :
// Note :
// :
// --------------------------------------------------------------------
// modification history :
// --------------------------------------------------------------------
// Version| mod. date: |
// V1.0 | 03/05/2004 | First release
// V1.1 | 11/15/2004 | DIP by mesmerli
// --------------------------------------------------------------------
//
// Note:
//
// MICROTIME COMPUTER INC.
//
//

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

#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include "asm/arch/irqs.h"

#if LINUX_VERSION_CODE < 0x020100
#define GET_USER(a,b) a = get_user(b)
#else
#include <asm/uaccess.h>
#define GET_USER(a,b) get_user(a,b)
#endif

#include "asm/arch/lib/creator_s3c2410_addr.h"
#include "asm/arch/lib/genfont8_8.h"
#include "dip-creator.h"

/*
* Define driver major number.
*/
#define MAJOR_NUM DIP_MAJOR_NUM
#define MODULE_VERSION "1.10"
#define MODULE_NAME "DIP_CREATOR"
#define COPYRIGHT "Copyright (C) 2003-2004, Microtime Computer Inc."
#define MODULE_AUTHOR_STRING "Microtime Computer Inc."
#define MODULE_DESCRIPTION_STRING "Creator DIP module"

/*****************************************************************************/

static int drv_dip_open(struct inode *inode, struct file *filp)
{
MOD_INC_USE_COUNT;
return(0);
}
/*****************************************************************************/


static int drv_dip_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return 0;
}

int drv_dip_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
int rc = 0;

/*
分離type如果遇到錯誤的cmd, 就直接傳回ENOTTY
*/
if (_IOC_TYPE(cmd) != DIP_IOCTL_MAGIC) return (-ENOTTY);

switch (cmd) {
case DIPSW_IOCTL_GET :{
unsigned short DIPSWs ;

DIPSWs = (UC)(IO_REG1);
if (copy_to_user((unsigned short*)arg, &DIPSWs, sizeof(unsigned short)))
return (-EINVAL);
break;
}
default:
rc = -ENOTTY;
break;
}

return(rc);
}

/*
* Exported file operations structure for driver...
*/

struct file_operations drv_dip_fops =
{
ioctl: drv_dip_ioctl,
open: drv_dip_open,
release: drv_dip_release,
};

/*****************************************************************************/
static int __init init_module_drv_dip(void)
{
int rc;

SET_MODULE_OWNER(&drv_dip_fops);

/* Register lcdtxt as character device */
if ((rc = register_chrdev(MAJOR_NUM, MODULE_NAME, &drv_dip_fops)) < 0) {
printk("<1>%s: can't get major %dn", MODULE_NAME, MAJOR_NUM);

return (-EBUSY);
}
printk("<1>%s: Version : %s %sn", MODULE_NAME, MODULE_VERSION, COPYRIGHT);

/* Hardware specific initialization */
return 0;
}

static void __exit cleanup_module_drv_dip(void)
{
unregister_chrdev(MAJOR_NUM, MODULE_NAME);
printk("<1>%s: removedn", MODULE_NAME);
}

/* here are the compiler macro for module operation */
module_init(init_module_drv_dip);
module_exit(cleanup_module_drv_dip);

MODULE_AUTHOR(MODULE_AUTHOR_STRING);
MODULE_DESCRIPTION(MODULE_DESCRIPTION_STRING);

EXPORT_NO_SYMBOLS;

/*****************************************************************************/

dip-creator.h

//=============================================================================
// File Name : dip-creator.h
// Function : DIP device drvier definition
// Program :
// Date : 11/15/2004
// Version : 1.10
// History
// 1.0.0 : Programming start (03/05/2004) -> SOP
// 1.1.0 : DIP version
//=============================================================================
#ifndef DIP_CREATOR_H_
#define DIP_CREATOR_H_

#include <linux/config.h>
#if defined(__linux__)
#include <asm/ioctl.h> /* For _IO* macros */
#define DIP_IOCTL_NR(n) _IOC_NR(n)
#elif defined(__FreeBSD__)
#include <sys/ioccom.h>
#define DIP_IOCTL_NR(n) ((n) & 0xff)
#endif

#define DIP_MAJOR_NUM 43
#define DIP_IOCTL_MAGIC DIP_MAJOR_NUM
#define DIP_IO(nr) _IO(DIP_IOCTL_MAGIC,nr)
#define DIP_IOR(nr,size) _IOR(DIP_IOCTL_MAGIC,nr,size)
#define DIP_IOW(nr,size) _IOW(DIP_IOCTL_MAGIC,nr,size)
#define DIP_IOWR(nr,size) _IOWR(DIP_IOCTL_MAGIC,nr,size)

/* DIP specific ioctls */
/* 當Switch調到ON時所傳回值為 */
/* 讀取DIP SW的狀態,bit 0是1 bit 7是8 */
#define DIPSW_IOCTL_GET DIP_IOR( 0x50, unsigned short)

#endif // DIP_CREATOR_H_

dip-demo.c

#include <signal.h>
#include <stdio.h>
#include <strings.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>

#include "dip-creator.h"

int main()
{
int fd;

unsigned int data = 0x0;

int ret;

fd = open("/dev/dip0", O_RDWR);
if (fd < 0)
{
printf("open /dev/dip0 errorn");
return (-1);
}


while(1)
{
ioctl(fd, DIPSW_IOCTL_GET, &data);

sleep(1);

printf("DIP is %02X", data);

}

printf("DIP Demo!!!n");

return 0;
}

0 意見: