arm中驅(qū)動(dòng)模塊加載并由應(yīng)用程序調(diào)用
驅(qū)動(dòng)模塊程序如下:
本文引用地址:http://m.butianyuan.cn/article/201611/317891.htm#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "my_ioctl.h"
unsigned int test_major= 253;//主設(shè)備號(hào)
unsigned int test_minor= 0;//次設(shè)備號(hào)
struct cdev cdevc;
MODULE_LICENSE("Dual BSD/GPL");//告知內(nèi)核,該模塊帶有一個(gè)自由的許可證
static int read_test(struct file *file, const char *buf, int count, loff_t *f_pos)
{
if (copy_to_user(buf, S3C2410_GPGDAT, sizeof(unsigned int)))
{
printk("error!/n");
return -1;
}
return sizeof(unsigned int);
}
static int write_test(struct file *file, const char *buf, int count, loff_t *f_pos)
{
__raw_writel (*buf, S3C2410_GPGDAT);//把buf中的數(shù)據(jù)賦值給GPGDAT,不可直接賦值,一定要調(diào)用此函數(shù)
printk ("write_test/n");
return 0;
}
int write_CFG(GPIO_Data_S *arg)
{
__raw_writel (0x0001<<2*arg->bit, S3C2410_GPACON+arg->port*0x10);//找到寄存器的某個(gè)引腳,并配置成輸入或輸出
__raw_writel (arg->value
return 0;
}
static int ioctl_test (struct inode *inode, struct file *file , unsigned int cmd, unsigned long arg)
{
GPIO_Data_S *data;
data= (GPIO_Data_S *)arg;
switch(cmd)
{
// case GPIO_IO_SET_CFG: set_CFG(data); break;
case GPIO_IO_GET_CFG: get_CFG(data); break;
case GPIO_IO_WRITE: write_CFG(data); break;
// case GPIO_IO_READ: read_CFG(data); break;
default: printk("The command is errot!/n");
}
return 0;
}
static int open_test(struct inode *inode, struct file *file)
{
// __raw_writel (0x1400, S3C2410_GPGCON);//"S3C2410_GPGCON"在asm/arch/regs-gpio.h庫(kù)函數(shù)中得到宏定義,可查閱
printk ("open_test/n");
return 0;
}
static int release_test(struct inode *inode, struct file *file)
{
printk ("release_test/n");
return 0;
}
//初始化字符設(shè)備驅(qū)動(dòng)的file_operations結(jié)構(gòu)體,在設(shè)備編號(hào)和驅(qū)動(dòng)程序之間建立鏈接
struct file_operations test_fops={
.owner= THIS_MODULE,
.read= read_test,
.write= write_test,
.ioctl= ioctl_test,
.open= open_test,
.release= release_test,
};
int dev_test_init_module(void)
{
int result;
dev_t dev= 0;
dev= MKDEV (test_major, test_minor);//獲取設(shè)備編號(hào)
result= register_chrdev_region(dev, 1, "dev_test");//靜態(tài)方式注冊(cè)設(shè)備驅(qū)動(dòng)
printk ("major= %d, minor= %d/n", test_major, test_minor);
if(result<0)
{
printk (KERN_INFO"test:cant get major nuber!/n");
return result;
}
cdev_init(&cdevc, &test_fops);
cdevc.owner= THIS_MODULE;
cdevc.ops= &test_fops;
result= cdev_add(&cdevc, dev, 1);
if (result)
{
printk("Error %d adding test", result);
}
return 0;
}
void dev_test_cleanup_module(void)
{
dev_t dev= 0;
dev= MKDEV(test_major, test_minor);
cdev_del(&cdevc);
unregister_chrdev_region(dev, 1);
printk("Module Exit!/n");
}
module_init(dev_test_init_module);
module_exit(dev_test_cleanup_module);
應(yīng)用程序如下:
#include
#include
#include
#include
#include
#include
#include "my_ioctl.h"
int main(void)
{
int dev_test;
int in_port;
int in_bit;
int in_value;
GPIO_Data_S data;
printf("Input the number: ");
scanf("%d %d %d", &in_port, &in_bit, &in_value);
printf("%d, %d, %d/n",in_port, in_bit, in_value);
data.port= in_port;
data.bit= in_bit;
data.value= in_value;
dev_test= open("/dev/dev_test1", O_RDWR);
if (dev_test== -1)
{
printf("Cant open file.../n");
exit(0);
}
while(1)
{
sleep(1);
ioctl(dev_test , GPIO_IO_WRITE, &data);
sleep(1);
data.value= ~(data.value);
ioctl(dev_test , GPIO_IO_WRITE, &data);
}
close (dev_test);
}
my_ioctl.h庫(kù)函數(shù)如下:
#ifndef __IOCTL_C_H__
#define __IOCTL_C_H__
typedef struct GPIO_Data_t
{
unsigned int port;
unsigned int bit;
unsigned int value;
} GPIO_Data_S;
#define GPIO_IOC_MAGIC 12 //Documentation/ioctl-number.txt
#define GPIO_IO_SET_CFG _IOW(GPIO_IOC_MAGIC,0,sizeof(GPIO_Data_S))
#define GPIO_IO_GET_CFG _IOWR(GPIO_IOC_MAGIC,1,sizeof(GPIO_Data_S))
#define GPIO_IO_WRITE _IOW(GPIO_IOC_MAGIC,2,sizeof(GPIO_Data_S))
#define GPIO_IO_READ _IOWR(GPIO_IOC_MAGIC,3,sizeof(GPIO_Data_S))
#endif
Makefile文件如下:
# To build modules outside of the kernel tree, we run "make"
# in the kernel source tree; the Makefile these then includes this
# Makefile once again.
# This conditional selects whether we are being included from the
# kernel Makefile or not.
ifeq ($(KERNELRELEASE),)
# Assume the source tree is where the running kernel was built
# You should set KERNELDIR in the environment if its elsewhere
# KERNELDIR ?= /lib/modules/$(shell uname -r)/build
KERNELDIR = /home/wangwei/utu-linux_for_s3c2440_V1.5.3
# KERNELDIR=$(KDIR)
#
# The current directory is passed to sub-makes as argument
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
else
# called from kernel build system: just declare what our modules are
obj-m := dev_test1.o
endif
執(zhí)行順序:
1.編譯驅(qū)動(dòng)模塊程序和應(yīng)用程序,分別生成dev_test1.ko和data_deal1,并用串口燒到開發(fā)板
2.加載模塊:insmod dev_test1
3.創(chuàng)建設(shè)備結(jié)點(diǎn),mknod /dev/dev_test1 c 253 0
4.執(zhí)行應(yīng)用程序:./data_deal1(可能需要修改權(quán)限)
串口燒寫方式簡(jiǎn)介:
1.啟動(dòng)開發(fā)板,進(jìn)入開發(fā)板系統(tǒng),按ctrl+a并釋放,再按z鍵
2.出現(xiàn)很多選項(xiàng),選s--傳輸文件
3.enter鍵選zmoden
4.按向右方向鍵,選中[轉(zhuǎn)到],按enter鍵
5.打入所要傳輸文件在你主機(jī)上的絕對(duì)路徑,按enter鍵
6.選中要傳輸文件,按enter鍵
評(píng)論