S3C2440 LED驱动实验-基于FES2440

如何编写?

  1. 首先找到板子的原理图,找到对应的引脚。
  2. 接着打开数据手册,找到对应的寄存器。
  3. 开始编写LED驱动程序
  4. 编写makefile
  5. 编写应用程序
  6. 连接实验箱,调试
核心板LED部分的原理图:

这里写图片描述

可直接根据核心板找到LED是由哪个GPIO控制的:
解释:
  1. LED1->EINT4->GPF4;
  2. LED2->EINT5->GPF5;
  3. LED3->EINT6->GPF6;
  4. LED4->EINT7->GPF7;
打开芯片手册,找到对应的寄存器

这里写图片描述

将GPF4、GPF5、GPF6、GPF7置01=输出;
其他位保留,
即GPFCON=55FF.

驱动程序流程设计

这里先贴上大连飞翔的例程,理解一下驱动框架在具体实例中的应用,

后续将会分析里面具体一些比较吃力的函数(对我这个小白来说)。

/*****************************************************************
文件名:led.c
硬件描述:
    S3C2410_GPF(4)连接LED0,
    S3C2410_GPF(5)连接LED1,
    S3C2410_GPF(6)连接LED2,
    S3C2410_GPF(7)连接LED3。
主要函数描述:led_ioctl()函数控制驱动设备,led_init()函数初始化驱动设备
*****************************************************************/
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include <mach/regs-gpio.h>
#include <linux/cdev.h>
#define LED_DRIVER  "FES2440 LED Driver"//自定义驱动称为"utu2440 LED Driver v1.00"

/* 用来指定LED所用的引脚设置 */
static unsigned long led_table [] = {
    S3C2410_GPF(4),
    S3C2410_GPF(5),
    S3C2410_GPF(6),
    S3C2410_GPF(7),
};

/******************************************************************************
功能描述:控制驱动程序
输入参数:inode为设备节点结构体, file为被操作的设备文件,cmd为传送的命令,arg为传送的数据
输出参数:无
返回结果:0表示成功,-1表示失败
******************************************************************************/
static int led_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
    case 0:
    case 1:
        if (arg > 4) {return -EINVAL;}
        s3c2410_gpio_setpin(led_table[arg], !cmd); //点亮相应的管脚
    default:
        return -EINVAL;
    }
    return 0;
}

/*定义文件操作结构体*/
static struct file_operations led_fops = {
    .ioctl = led_ioctl,
};

/*定义杂类设备结构体*/
static struct miscdevice led_dev = {
    MISC_DYNAMIC_MINOR,  //主设备号
    "LED",              //设备名
    &led_fops          // 设备文件操作结构体地址
};

/******************************************************************************
功能描述:设备初始化函数
输入参数:无
输出参数:无
返回结果:0表示成功,-1表示失败
******************************************************************************/
static int led_init(void)
{
    pr_info("%s\n", LED_DRIVER);
    __raw_writel(0xFFFF55FF,S3C2410_GPFCON);//设置控制寄存器
    printk("GPF4=%d",s3c2410_gpio_getpin(S3C2410_GPF(4)));
    misc_register(&led_dev);//注册设备驱动
    return 0;
}

/******************************************************************************
功能描述:设备退出函数
输入参数:无
输出参数:无
******************************************************************************/
static void __exit led_exit(void)
{
    misc_deregister(&led_dev);
}

/*模块参数设置*/
module_init(led_init);
module_exit(led_exit);
MODULE_AUTHOR("FES");
MODULE_LICENSE("GPL");

Makefile

PWD=$(shell pwd)
KERNEL_SRC= /Linux-2.6.32
obj-m += led.o
all:
    $(MAKE) -C $(KERNEL_SRC) M=$(PWD)
clean:
    rm -rf *.ko *.o *.mod.c *.symvers

测试程序

/*****************************************************************
文件名:ledtest.c
主要函数描述:main()函数实现对led驱动设备的测试
*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

/**************************************************************************
功能描述:完成对LED的显示
输入参数:无
输出参数:无
*************************************************************************/
int main(int argc, char **argv)
{
    int on,i;//开关标志
    int led_number;//要控制的LED number
    int fd;//文件操作
    char c,d;
    int left_num;

    /*打开LED设备文件*/
    fd = open("/dev/LED", 0);
    if (fd < 0)
    {
        perror("open device /dev/LED failed!");
        exit(1);
    }

    /*开始测试*/
    while(1)
    {
    l1:printf("Please input led_number(0-3)\n");
    scanf("%d", &led_number);
    if(led_number>3||led_number<0)
    {
    printf("you input wrong led_number,try again!\n");
    goto l1;
    }
    l2:printf("Please input Command(0 or 1)\n");
    scanf("%d", &on) ;
    if(on!=0&&on!=1)
    {
    printf("you input wrong command,try again!\n");
    goto l2;
    }
    scanf("%c",&d); //把回车去掉
    ioctl(fd, on, led_number);
    l3:printf("go on or not Y/N:\n");
    scanf("%c",&c);
    if(c=='n'||c=='N') {for(i=0;i<4;i++) ioctl(fd,0,i);break;}
    else if(c=='Y'||c=='y') ;
    else {printf("you input wrong chose,try again!\n");goto l3;}
    }
    close(fd);//关闭设备文件
    return 0;
}

驱动make完成得到的内核模块文件(.ko文件)就可以加载到实验箱上调试了,

用交叉编译环境arm-linux-gcc编译调试程序,在试验箱中运行进行调试。

连接实验箱

我这里采用的时串口-USB连接

连接试验箱时串口出现黄色感叹号

看我

问题:驱动没装

解决办法:驱动下载连接 密码: Zane

1.打开设备管理器,在黄色感叹号的设备上右键点击更新

2.点击让我从计算机中可用的驱动列表里选

这里写图片描述

3.找到这个驱动,下一步!!

出现设备列表选择串口(COM口)就会进入这个界面

这里写图片描述

win7超级终端实现PC机上调试驱动

超级终端for win7可以实现pc机与试验箱间的数据交互,high不high??哈哈。

超级终端 提取密码: Zane

1.点击新建连接,输入名称

这里写图片描述

2.选择com口

这里写图片描述

3.波特率设置成115200,数据流控制选择

这里写图片描述

4.进去了点一下回车就会弹出命令行

这里写图片描述

5.插入模块insmod led.ko
6.执行应用程序./ledtest

注意:若是显示permission denied 错误则是权限不够,没有可执行权限

只需chmod u+x ledtest即可

调试过程:

这里写图片描述

7.实验现象展示

这里写图片描述

这里写图片描述

欢迎指错交流

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值