arm中驱动模块加载并由应用程序调用

发布者:ArtisticSoul最新更新时间:2016-06-21 来源: eefocus关键字:arm  驱动模块  程序调用 手机看文章 扫描二维码
随时随地手机看文章
开发板:s3c2440

驱动模块程序如下:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include "my_ioctl.h"

unsigned int test_major= 253;//主设备号
unsigned int test_minor= 0;//次设备号
struct cdev cdevc;
MODULE_LICENSE("Dual BSD/GPL");//告知内核,该模块带有一个自由的许可证

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中的数据赋值给GPGDAT,不可直接赋值,一定要调用此函数
    printk ("write_test/n");
    return 0;
}

int write_CFG(GPIO_Data_S *arg)
{
    __raw_writel (0x0001<<2*arg->bit, S3C2410_GPACON+arg->port*0x10);//找到寄存器的某个引脚,并配置成输入或输出
    __raw_writel (arg->value<bit, S3C2410_GPADAT+arg->port*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库函数中得到宏定义,可查阅

    printk ("open_test/n");
    return 0;
}

static int release_test(struct inode *inode, struct file *file)
{
    printk ("release_test/n");
    return 0;
}
//初始化字符设备驱动的file_operations结构体,在设备编号和驱动程序之间建立链接
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);//获取设备编号
    result= register_chrdev_region(dev, 1, "dev_test");//静态方式注册设备驱动
    
    printk ("major= %d, minor= %d/n", test_major, test_minor);
    if(result<0)
    {
        printk (KERN_INFO"test:can't 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);

 

应用程序如下:

#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("Can't 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库函数如下:

#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 it's 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

 

 

执行顺序:

      1.编译驱动模块程序和应用程序,分别生成dev_test1.ko和data_deal1,并用串口烧到开发板

      2.加载模块:insmod  dev_test1

      3.创建设备结点,mknod /dev/dev_test1 c 253 0

      4.执行应用程序:./data_deal1(可能需要修改权限)

串口烧写方式简介:

      1.启动开发板,进入开发板系统,按ctrl+a并释放,再按z键

      2.出现很多选项,选s--传输文件

      3.enter键选zmoden

      4.按向右方向键,选中[转到],按enter键

      5.打入所要传输文件在你主机上的绝对路径,按enter键

      6.选中要传输文件,按enter键

关键字:arm  驱动模块  程序调用 引用地址:arm中驱动模块加载并由应用程序调用

上一篇:ARM 位置无关代码PIC的分析理解
下一篇:ARM 的分散加载

推荐阅读最新更新时间:2024-03-16 14:58

基于3G手机的视频监控系统设计与实现
  随着3G 网络技术的快速发展以及3G 手机各项功能的增强, 使得利用3G 手机实现随时随地的视频监控已成为可能。而嵌入式技术作为当今IT 业的热门技术, 各种嵌入式芯片如 DSP , A RM, SOC 等被广泛应用于数码、安防、交 通信 号采集、远程医疗等领域[ 1] , 可以预见未来 便携式 多功能的个人医疗数字服务终端会像手机一样普及[ 2] , 用户可以随时随地地将自己重要的生理信息实时、准确、快速地传送到远程医疗中心或家庭护理专家处, 从而得到医生的专业建议和指导, 实现远程医疗监护的应用。文献[ 3] 中的无线监控系统也用到ARM9 芯片和WinCE 操作系统, 但对软件设计部分论述不清晰, 文献[ 4] 论述的基
[电源管理]
基于3G手机的视频监控系统设计与实现
基于嵌入式ARM Linux步进电机驱动程序的设计
0 引言 随着激光雕刻机的不断发展和改进,嵌入式Linux的激光雕刻机比CNC(Computer numerical control)激光雕刻的优势不断显现,它大幅度提高了处理能力,方便了设计开发,节约了成本,是未来经济型激光雕刻机发展的趋势。而嵌入式ARM(Advanced RISC Machines)Linux步进电机驱动是实现激光雕刻的核心。 嵌入式开发过程中,经常需要为特定设备开发驱动程序。这些驱动程序的编写和编译与PC上的Linux驱动开发相比存在明显的差异,需要考虑的因素较多,实现过程较为复杂。本文以Samsung公司的友善之譬S3C2440开发板为例,探讨如何使用嵌入式Linux开发字符设备驱动程序来驱动步进
[单片机]
基于嵌入式<font color='red'>ARM</font> Linux步进电机<font color='red'>驱动</font><font color='red'>程序</font>的设计
arm与flash连接错位的原因
外设位宽为8、16、32时,CPU与外设之间地址线的连接方法 有不少人问到: flash连接CPU时,根据不同的数据宽度,比如16位的NOR FLASH (A0-A19),处理器的地址线要(A1-A20)左移偏1位。为什么要偏1位? 从软件和CPU的角度而言,一个地址对应一个字节,就是8位数据。这是肯定的,不要怀疑这点。 对于具体器件而言,它的位宽是一定的,所谓位宽,指的是 读/写操作时,最小的数据单元 ──别说最小单元是 位 ,一般设备上没有单独的 位操作 ,修改位时通过把整个字节、字或双字读出来、修改,再回写。 CPU的地址线(A0-A20)对应的最小数据单元是字节,即8位; 而位宽为16的NOR FLASH的地址线(
[单片机]
arm技术修改D1N4002的仿真参数介绍
步骤一:绘出电路图、设置分析参数、存档及执行仿真 1、半导体元件均有其对应的仿真模型,所以我们可以根据自己的需求更改其模型型参数,以产生一个与元件有不一 样输入输出特性的二极管。首先新开一个项目D1N4002_1,然后如图1绘制电路图(也可以由D1N4002绘图页内复制 过来)。 2、然后用鼠标左键在D1N4002项目绘图页内的DIN4002地元件上单击,它会变成紫色并由一个虚线框所围绕,再选 EditPSpice Model功能选项打开如图2所示的OrCAD Model Editor窗口。 3、OrCAD Model Editor窗口的左半部分内容显示目前要处理的元件模型名称为D1N4002,元件形式为二极管(Diode) 如图
[单片机]
基于ARM-Linux的自主避障机器鱼设计
随着科技的发展与进步,出现了具有特殊功能的智能机器,如索尼公司生产的能够以自我“意识”来“感觉”“学习”和“饲养”的宠物机器狗,以弗吉尼亚理工大学研制的CHARLI-L1机器人为基础进行升级改造的SAFFIR的消防机器人等。机器鱼作为一项比较新的产品,涉及到机器鱼的智能开发并不深,因此机器鱼的智能化程度并不高,但随着机器鱼研究的加深,相信机器鱼的智能度会大大提高,功能也会更趋完善。目前的机器鱼类型主要有遥控机器鱼和语音控制机器鱼,例如曾在德国汉诺威电子展上展现的通过机器鱼体内收缩来提供动力的遥控式机器鱼和在西南民族大学诞生的国内首个的声控机器鱼等。据调查显示同内涉及到具有自主避障与自主视觉功能的智能机器鱼的研究与开发并不多。由于技术
[单片机]
基于<font color='red'>ARM</font>-Linux的自主避障机器鱼设计
入门级ARM汇编指令
无论是体系结构还是指令集,大家或多或少都应该对X86汇编有些了解,而对于嵌入式领域已被广泛采用的ARM 处理器,了解的可能并不多。如果你有兴趣从事嵌入式方面的开发,那么了解一些RISC 体系结构和ARM汇编的知识还是有必要的。这里,我们找出了这两种体系结构最明显的不同之处,并对此进行介绍,让大家对于RISC体系结构的汇编有一个基本的了解。首先,我们就来看一看基于RISC的ARM的体系结构。 基于RISC 的ARM CPU ARM是一种RISC体系结构的处理器芯片。和传统的CISC体系结构不同,RISC 有以下的几个特点: ◆ 简洁的指令集 为了保证CPU可以在高时钟频率下单周期执行指令,RISC指令集只提供很有限的操作(例如add,
[单片机]
入门级<font color='red'>ARM</font>汇编指令
嵌入式Linux下ARM处理器与DSP的数据通信
摘要:本文通过一个开发实例详细说明如何通过DSP的HPI接口与运行Linux操作系统的ARM架构处理器进行数据通信。给出接口部分的实际电路和ARM-Linux下驱动程序的开发过程。 关键词:设备驱动程序 嵌入式Linux HPI ARM DSP 1 引言 基于ARM核心处理器的嵌入式系统以其自身资源丰富、功耗低、价格低廉、支持厂商众多的缘故,越来越多地应用在各种需要复杂控制和通信功能的嵌入式系统中。 内核源码开放的Linux与ARM体系处理器相结合,可以发挥Linux系统支持各种协议及存在多进程调度机制的优点,从而使开发周期缩短,扩展性增强。作为数字处理专用电路,DSP的数字信号处理能力十分强大,但对诸如任务管理、通信、
[嵌入式]
arm 64位实时处理器Cortex-R82,5nm工艺,性能高达5.82 MHz
虽然Arm的芯片部门存在被出售的可能,但Arm公司的技术人员并没有停下脚步。 本周,Arm推出了其首款64位实时处理器,这是其Cortex-R系列的最新产品,其中包括Linux支持以及对企业存储应用的重视。该策略反映了使处理和分析更接近数据的日益增长的需求。 64位Cortex-R82添加了“计算存储”(computational storage)功能,例如通过内存管理选件支持Linux微服务和云本机软件开发。它还满足了解决更大内存容量的需求,该公司表示,这正在成为运行Linux或新兴计算存储设备时性能的障碍。 Arm指出:“计算存储就是使存储设备更智能,以便直接在存储数据的地方处理数据。” 根据工作负载测试
[嵌入式]
<font color='red'>arm</font> 64位实时处理器Cortex-R82,5nm工艺,性能高达5.82 MHz
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved