本文内容由浅入深主要介绍了JZ2440LED裸板程序,LED的简单驱动程序

      一、LED裸板程序

         arm开发板的裸板程序和51单片机类似,需要通过配置寄存器来实现。s3c2440130I/O口,共分为A-J9组。

         1.硬件原理图:

         JZ2440的硬件连接图,如下图所示:

spacer.gif

从图中可以看出LED1LED2LED3LED4这四个LED灯分别于GPB5-GPB8相连,因此需要通过控制GPB5-GPB8的寄存器的输出来控制,LED等的亮灭。

       2.寄存器的配置

       s3c2440I/O口可以用于输入、输出或是其他特殊功能,因此需要有寄存器来对引脚的功能进行配置。GPB引脚的位置及配置可以从s3c2440手册上查到,如下图所示:

spacer.gif

由上图可以看出对GPB引脚进行设置的有4个寄存器,其中包括一个保留的,即有三个寄存器来对GPB引脚进行设置。

这三个寄存器的功能如下:

GPBCON:主要用于配置,选择引脚的功能。GPBDAT:用于读写引脚,当引脚被设为输入时,读此寄存器可知相应引脚的电平状态是高还是低;当引脚被设为输出时,写此寄存器相应位可令此引脚输出高电平或低电平。GPBUP寄存器:某位为1时,相应引脚无内部上拉电阻;为0时,相应引脚使用内不上拉电阻。

3、代码分析

点亮LEDC语言代码很简单,如下所示:

/*定义GPBCON的地址,其中的volatile主要是为了防止编译器在编译时对代码进行优化,从而产生错误*/

#define GPBCON (*(volatile unsigned long*)0x56000010)

#define GPBDAT (*(volatile unsigned long*)0x56000014)

 

int main()

{

         GPBCON=0x00015400;//设置GPB5-GPB8位输出端口

         GPBDAT=0x00000000;//GPB5-GPB8输出0LED1-4点亮

}

二、LED驱动程序

1.驱动简介

一个软件系统可以分为:应用程序、库、操作系统、驱动程序四部分,其架构图如下所示:

spacer.gif

首先应用程序使用库提供的open函数打开代表LED的设备文件;库根据open函数传入的参数执行swi指令,该指令引起系统调用;内核的异常处理函数根据这些参数找到对应的驱动程序,返回文件的句柄;应用程序得到文件句柄后,使用库提供的writeioctl函数发出控制命令;库根据writeioctl函数传入的参数执行swi指令,这条指令会引起CPU异常,进入内核;内核的异常处理函数根据这些参数调用驱动程序的相关函数,点亮LED

Linux的外设可以分为3类:字符设备、块设备和网络设备。字符设备是能够像字节流一样被访问的设备,对设备的读写是以字节为单位的。块设备的数据是以块的形式存放的,如硬盘、U盘等。

2.源码分析

#define LED_MATOR0

Static unsignedlong led_table[]={

S3C2410_GPB(5),

S3C2410_GPB(6),

S3C2410_GPB(7),

S3C2410_GPB(8),

};

staticint s3c2440_leds_open(struct inode *inode,struct file *file)

{

         int i;

         for(i=0;i<4;i++)

         {

         S3c2410_gpio_cfgpin(led_table[i], S3C2410_GPIO_OUTPUT);//配置引脚为输出

         }

         return 0;

}

staticint s3c2440_leds_ioctl(struct inode *inode,struct file *file,unsigned intcmd,unsigned long arg){

         if(arg>4)

         return –EINVAL;

        

         switch(cmd){

         case IOCTL_LED_ON:

         s3c2410_gpio_setpin(led_table[arg],0);//设置引脚输出电平为0

         return 0;

         case IOCTL_LED_OFF:

         s3c2410_gpio_setpin(led_table[arg],1); //设置引脚输出电平为1

         return 0;

         defaule:

         return –EINVAL;

         }

}

/*驱动的操作函数集*/

static structfile_operations s3c2440_leds_fops={

         .owner=THIS_MODULE,

         .open=s3c2440_leds_open,

         .ioctl=s3c2440_leds_ioctl,

};

staticint  s3c2440_leds_init(void)

{

         int ret;

         ret=register_chrdev(LED_MATOR,”leds”,&s3c2440_leds_fops);//向内核注册驱动函数

         if(ret<0)

         return ret;

        

         return 0;

}

Staticvoid s3c2440_leds_exit(void)

{

         Unregister_chrdev(LED_MATOR, ”leds”);//卸载驱动的函数

}

module_init(s3c2440_leds_init);//指定驱动程序的初始化函数

module_exit(s3c2440_leds_exit);//指定驱动程序的卸载函数