新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > arm中驅(qū)動模塊加載并由應(yīng)用程序調(diào)用

        arm中驅(qū)動模塊加載并由應(yīng)用程序調(diào)用

        作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
        開發(fā)板:s3c2440

        驅(qū)動模塊程序如下:

        本文引用地址:http://www.104case.com/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è)備號
        unsigned int test_minor= 0;//次設(shè)備號
        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->valueport*0x10);//
        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庫函數(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ū)動的file_operations結(jié)構(gòu)體,在設(shè)備編號和驅(qū)動程序之間建立鏈接
        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è)備編號
        result= register_chrdev_region(dev, 1, "dev_test");//靜態(tài)方式注冊設(shè)備驅(qū)動

        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庫函數(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ū)動模塊程序和應(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)限)

        串口燒寫方式簡介:

        1.啟動開發(fā)板,進(jìn)入開發(fā)板系統(tǒng),按ctrl+a并釋放,再按z鍵

        2.出現(xiàn)很多選項(xiàng),選s--傳輸文件

        3.enter鍵選zmoden

        4.按向右方向鍵,選中[轉(zhuǎn)到],按enter鍵

        5.打入所要傳輸文件在你主機(jī)上的絕對路徑,按enter鍵

        6.選中要傳輸文件,按enter鍵



        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 元氏县| 长阳| 和静县| 田东县| 沂南县| 郓城县| 辽宁省| 巴林左旗| 商水县| 寿阳县| 开封市| 建水县| 股票| 图们市| 兴业县| 渭源县| 丰宁| 临夏市| 大石桥市| 扎兰屯市| 建湖县| 井陉县| 长顺县| 中牟县| 十堰市| 大冶市| 翼城县| 神木县| 红安县| 准格尔旗| 镇宁| 樟树市| 宝清县| 彩票| 东明县| 江北区| 吉木萨尔县| 江安县| 河北区| 连云港市| 阆中市|