1. 程式人生 > >FL2440字元裝置驅動之LED

FL2440字元裝置驅動之LED

今天開始我們來學習linux驅動的開發,驅動分為字元裝置驅動,塊裝置,網路裝置驅動,講這個之前我說一下我用的虛擬機器版本和LInux核心版本,開始我用的redhat 9.0  開始用的好好的,到後來自己編譯busybox的時候總是出錯誤,這個期間我嘗試了很多次,在網上也找到了很多方法,可還是解決不了問題,後來找到了原因是虛擬機器版本的問題,後來我換了ubuntu9.10,那些錯誤就沒有了。

在這裡我我在說明一下FL2440光碟自帶的Linux2.6.28.7是不是支援自動建立裝置節點的,需要在/etc/init.d/rcS中新增  mdev -s 。學習的同時可以參考韋東山老師的視訊,講得非常好,注意下我們的程式碼和他的程式碼有一點區別,就是一些函式可能用的不同(是核心版本的問題),以後我講的驅動都是用的Linux2.6.28.7,這樣也方便你們學習。

這些程式碼你直接copy上去都是可以用的廢話不多說了,直接上程式碼:

/s3c2440_leds.c
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
//#include <linux/devfs_fs_kernel.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/device.h>
#include <linux/gpio.h>


#define DEVICE_NAME "leds"
#define LED_MAJOR 231
#define LED_OFF        0
#define LED_ON        1
#define ALL_LED_OFF      3
#define ALL_LED_ON       4


MODULE_LICENSE("Dual BSD/GPL");


static struct class *led_2;


static unsigned long led_table [] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB8,
S3C2410_GPB10,
};
/*等價於設定GPFCON*/
static unsigned int led_cfg_table [] = {
S3C2410_GPB5_OUTP, //0x01<<10 defined in refg-gpio.h
S3C2410_GPB6_OUTP,
S3C2410_GPB8_OUTP,
S3C2410_GPB10_OUTP,
};


static int s3c2440_leds_ioctl( struct inode *inode, struct file *file,unsigned int cmd,unsigned long arg)
{
     int i;
if (arg > 4)
{
return -EINVAL;
}
switch(cmd)
{
case LED_ON:  //set the pin
s3c2410_gpio_setpin(led_table[arg], 0);
break;


case LED_OFF:  //clr the pin
s3c2410_gpio_setpin(led_table[arg], 1);
break;

case ALL_LED_ON:  //set all pin
for (i = 0; i < 4; i++)
s3c2410_gpio_setpin(led_table[i], 0);
break;

case ALL_LED_OFF:  //clr all pin
for (i = 0; i < 4; i++)
s3c2410_gpio_setpin(led_table[i], 1);
break;


default:
return -EINVAL;
}
}


static struct file_operations s3c2440_leds_fops = {
.owner = THIS_MODULE,
.ioctl = s3c2440_leds_ioctl,
};


 static int major;
static int __init s3c2440_leds_init(void)
{


  int i;
major = register_chrdev(0, DEVICE_NAME, &s3c2440_leds_fops);
if (major < 0) 
{
   printk(DEVICE_NAME " can't register major number\n");
   return  major;
}
       led_2 = class_create(THIS_MODULE, DEVICE_NAME);
device_create(led_2, NULL, MKDEV(major, 0), NULL, "led_2"); 


for (i = 0; i < 4 ; i++)
{
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
s3c2410_gpio_setpin(led_table[i], 1); 
}
printk(DEVICE_NAME " initialized\n");
return 0;
}
static void __exit s3c2440_leds_exit(void)
{
unregister_chrdev(major, DEVICE_NAME);
device_destroy(led_2,MKDEV(major, 0));
class_destroy(led_2);
}
module_init(s3c2440_leds_init);
module_exit(s3c2440_leds_exit);

測試程式:

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/ioctl.h"
#include "stdlib.h"
#include "termios.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "sys/time.h"






int main(int argc, char **argv)
{
unsigned int on;
unsigned int led_num;
int fd;
fd=open("/dev/led_2",O_RDWR);//開啟檔案返回值是個非負值
if (fd < 0)
{
printf("open device led");
      return -1;
}

      printf("%s <on/off>\n",argv[0]);
  
if (argc == 2)

{
sscanf(argv[1], "%d", &on);
if (on < 2)
{
ioctl(fd, on+3, 0);
}
else
{
printf("Usage: led led_num 0|1  or  led 0|1\n");
exit(1);
}
}

if (argc == 3)
{
sscanf(argv[1], "%d", &led_num);
sscanf(argv[2], "%d", &on);
if ((on < 2) && (led_num>0 || led_num < 4))
ioctl(fd, on, (led_num-1));
else
{
printf("Usage: led led_num 0|1  or  led 0|1\n");
exit(1);
}
}


close(fd);
return 0;
}

在編寫個Makefile:

obj-m :=test.o
KERNELDIR ?= /home/work/Linux/linux-2.6.28.7//核心路徑
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -f  *o  *.mod.o  *mod.c  *.symvers *.order

相關推薦

FL2440字元裝置驅動LED

今天開始我們來學習linux驅動的開發,驅動分為字元裝置驅動,塊裝置,網路裝置驅動,講這個之前我說一下我用的虛擬機器版本和LInux核心版本,開始我用的redhat 9.0  開始用的好好的,到後來自己編譯busybox的時候總是出錯誤,這個期間我嘗試了很多次,在網上也找到

linux driver ------ 字元裝置驅動“ 建立裝置節點流程 ”

在字元裝置驅動開發的入門教程中,最常見的就是用device_create()函式來建立裝置節點了,但是在之後閱讀核心原始碼的過程中卻很少見device_create()的蹤影了,取而代之的是device_register()與device_add(),將device_create()函式展開不難發現:其實de

字元裝置驅動控制led

開發板:龍芯1B PC:ubuntu13.10 本程式為字元裝置驅動,提供控制led燈功能,如要實現控制需要自己寫應用程式,開啟驅動檔案就可控制led燈,led燈通過gpio控制 #include <linux/init.h> #include <lin

嵌入式Linux驅動開發(四)——字元裝置驅動中斷方式以及中斷方式獲取按鍵值

之前我們完成了關於通過查詢的方式獲取按鍵鍵值的驅動程式,可以參考:嵌入式Linux開發——裸板程式之中斷控制器。 雖然讀取鍵值沒有什麼問題,但是測試程式佔用CPU過高,一直在不斷的查詢,資源消耗過大,這個問題非常嚴重,我們必須要來解決一下。但是在解決這個問題之前,我們先來思考一個問題,除

linux裝置驅動led子系統

/include/linux/leds.h enumled_brightness{      LED_OFF          = 0,      LED_HALF     = 127,      LED_FULL     = 255, }; led_classd

字元裝置驅動筆記-中斷上下部

  中斷下半部 在中斷處理函式執行的過程中: 1. 它可以被其他中斷打斷 2. 它不會再次響應同一個中斷(同一個中斷不會巢狀處理) 3. 如果中斷處理函式執行的時間很長,系統性能會受影響 舉例: net_irq() {  1. 從網絡卡晶片讀資料到記憶體裡 (比較快)  

字元裝置驅動程式非同步通知

非同步通知:      驅動程式的所謂非同步通知,指的是應用程式不是主動對驅動程式進行操作,而是驅動程式查詢到有事件發生或者有資料發生變化的時候通知應用程式。角色發生了變化,應用程式由主動改為被動執行。 比如按鍵驅動: 1、要不斷進行查詢引腳狀

字元裝置驅動------非同步通知 按鍵使用非同步通知(詳解)

引入: 按鍵驅動方式對比 查詢:一直讀,耗資源 中斷: 沒有超時機制,當沒有中斷,read函式一直休眠 poll機制,加入超時機制 以上3種,都是讓應用程式主動去讀,本節我們學習非同步通知,它的作用就是當驅動層有資料時,主動告訴應用程式,然後應用程式再來讀, 這樣,應用程式就可以幹其它

Linux裝置驅動字元裝置驅動---轉

一、linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。 應用程式呼叫的流程框圖: 三種裝置的定義分別如下, 字元裝置:只能一個位元組一個位元組的讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後順序進行。字元裝置是面向流的裝置,常見的字

ARM學習筆記驅動程式篇七----字元裝置驅動

1.11 字元裝置驅動模型 在任何一種驅動模型中,裝置都會用核心中的一種結構來描述。字元裝置在核心中使用struct cdev來描述。 struct cdev{ struct kobject kobj; struct module *owner; const stru

I2C裝置驅動字元裝置簡寫

最近有機會需要寫一個 掛載在I2C匯流排的I2C裝置驅動,外設晶片是MCP23017 IO擴充套件晶片,測試是否可以通訊成功,以下是部分程式碼以及除錯的一些注意項: #include <linux/kernel.h> #include <linux/init.h>

字元裝置驅動----LED驅動程式

一. 概念介紹 一般使用者在應用程式裡呼叫的 open, read, write 函式是 c 庫的函式, 這些函式會觸發 swi val異常,從而引發系統呼叫,進入到核心空間, 核心通過VFS(virtual Filesystem)來實現呼叫不同的驅動函式

從零開始寫linux字元裝置驅動程式(一)(基於友善臂tiny4412開發板)

從這篇博文開始,我將開始手把手教會大家寫linux裝置驅動程式這是開篇,如何來寫第一個字元裝置驅動程式。首先,寫一個最簡單的字元裝置驅動程式需要什麼?或者說我們需要了解什麼?1、每一個字元裝置至少需要有一個裝置號2、裝置號 = 主裝置號 + 次裝置號3、同一類裝置的主裝置號一

Linux裝置驅動字元裝置(一)

Linux中裝置驅動的分類 從上圖可以看到Linux系統將各異的裝置分為三大類:字元裝置,塊裝置和網路裝置。核心針對每一類裝置都提供了對應驅動模型架構,包括基本的核心設施和檔案系統介面。 字元裝置:在傳送過程中以字元為單位,一個位元組一個位元組的讀寫,不

字元裝置驅動程式——按鍵中斷互斥阻塞操作

一、互斥操作 在程式設計中,引入了物件互斥鎖的概念,來保證共享資料操作的完整性。每個物件都對應於一個可稱為" 互斥鎖" 的標記,這個標記用來保證在任一時刻,只能有一個執行緒訪問該物件。 實現方式 原子操作 原子操作指的是在執行過程中不會被別的程式碼路徑所中斷的操作。 常用

字元裝置驅動程式——按鍵中斷非同步通知

一、驅動程式的實現 1、定義static struct fasync_struct *newdrv_async; 2、加入 static struct file_operations new_drv_fops = { .fasync =new_drv_fasync, }; static

韋東山嵌入式Linux學習筆記——第12課第8節 字元裝置驅動程式定時器防抖動

注:本文部分內容摘自《魚樹學員筆記》。 當按鍵按得比較快的時候,這裡出現了兩次中斷值,也即產生了抖動。 這裡產生了“抖動”,按鍵是機械開關,按下鬆開時裡面的金屬彈片可能抖動了好幾次。這種抖動產生了多次“脈衝”導致多次中斷。 方法: 使用定時器來防抖動。

Linux裝置驅動字元裝置驅動

一、linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。 應用程式呼叫的流程框圖: 三種裝置的定義分別如下, 字元裝置:只能一個位元組一個位元組的讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後順序進行。字元裝置是面向流的裝置,常見的字元裝置如

Linux裝置驅動字元裝置驅動

    Linux裝置中最大的特點就是裝置操作猶如檔案操作一般,在應用層看來,硬體裝置只是一個裝置檔案。應用程式可以像操作檔案一樣對硬體裝置進行操作,如open(),close(),read(),write()等。     下面是一個字元裝置驅動程式的簡單實現test.c  

linux驅動字元裝置驅動

字元裝置驅動框架: cdev結構體: 描述字元裝置; dev_t:定義裝置號(分為主、次裝置號)以確定字元裝置的唯一性; file_operations:定義字元裝置驅動提供給VFS的介面函式,如常見的open()、read()、write()等;