4. 字符設備驅動程序
初始化時首先分配給這個函數設備號,注冊該設備,通過class注冊使能夠在/dev/目錄下自動生成相應的設備文件,用戶通過操作這個文件,來告訴內核怎么做。
由于是字符設備,所以對該文件的操作通過open,write,ioctl等函數,所以要把這個函數和底層的操作函數對應起來,這就要用到file_operation這個結構體來聲明。
#include 《linux/kernel.h》
#include 《linux/module.h》
#include 《linux/device.h》
#include 《mach/platform.h》
#include 《linux/platform_device.h》
#include 《linux/types.h》
#include 《linux/fs.h》
#include 《linux/ioctl.h》
#include 《linux/cdev.h》
#include 《linux/delay.h》
#include 《linux/uaccess.h》
#include 《linux/init.h》
#include 《linux/gpio.h》
#include 《linux/string.h》
#include 《linux/tty.h》
#include 《linux/sched.h》
#define uchar unsigned char
#define uint unsigned int
#define DEVICE_NAME “Pi_Matrix”
#define DRIVER_NAME “pi_matrix”
//class聲明內核模塊驅動信息,是UDEV能夠自動生成/dev下相應文件
static dev_t pi_matrix_devno; //設備號
static struct class *pi_matrix_class;
static struct cdev pi_matrix_class_dev;
struct gpio_chip *gpiochip;
#define DecodeMode 0x09 //譯碼模式寄存器
#define Intensity 0x0a //亮度寄存器
#define ScanLimit 0x0b //掃描位數寄存器
#define ShutDown 0x0c //低功耗模式寄存器
#define DisplayTest 0x0f //顯示測試寄存器
#define ShutdownMode 0x00 //低功耗方式
#define NormalOperation 0x01 //正常操作方式
#define ScanDigit 0x07 //掃描位數設置,顯示8位數碼管
#define DecodeDigit 0x00 //譯碼設置,8位均為非譯碼
#define IntensityGrade 0x0a //亮度級別設置
#define TestMode 0x01 //顯示測試模式
#define TextEnd 0x00 //顯示測試結束,恢復正常工作模式
#define DIN 2
#define CS 3
#define CLK 4
uchar mybuffer[8] = {0x00,0x66,0xff,0xff,0xff,0x7e,0x3c,0x18};
uchar digits[][8]={
{0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c}, // 0
{0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c}, // 1
{0x1c, 0x22, 0x22, 0x04, 0x08, 0x10, 0x20, 0x3e}, // 2
{0x1c, 0x22, 0x02, 0x0c, 0x02, 0x02, 0x22, 0x1c}, // 3
{0x04, 0x0c, 0x14, 0x14, 0x24, 0x1e, 0x04, 0x04}, // 4
{0x3e, 0x20, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c}, // 5
{0x1c, 0x22, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x1c}, // 6
{0x3e, 0x24, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08}, // 7
{0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c}, // 8
{0x1c, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x22, 0x1c}, // 9
};
void delay(uint t){
uint i;
while(t--)
for (i = 0; i 《 125; i++);
}
void sendChar(char ch){
char i, tmp;
for(i = 0; i 《 8; i++){
tmp = ch & 0x80;
if(tmp)
gpiochip-》set(gpiochip, DIN, 1);
else
gpiochip-》set(gpiochip, DIN, 0);
ch = ch 《《 1;
gpiochip-》set(gpiochip, CLK, 1);
gpiochip-》set(gpiochip, CLK, 0);
}
}
void writeWord(char addr, char num){
gpiochip-》set(gpiochip, CLK, 0);
gpiochip-》set(gpiochip, CS, 1);
gpiochip-》set(gpiochip, CS, 0);
sendChar(addr);
sendChar(num);
gpiochip-》set(gpiochip, CS, 1);
}
static int write_test(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos){
char wbuf[100]={0};
copy_from_user(wbuf,buffer,100);
printk(“%s ”,wbuf);
gpiochip-》set(gpiochip, CS, 1);
gpiochip-》set(gpiochip, CS, 0);
gpiochip-》set(gpiochip, CLK, 0);
return count;
}
static int pi_matrix_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos){
char i;
char ch[1]={‘0’};
copy_from_user(ch,buffer,1);
printk(“%c ok ”,ch[0]);
switch(ch[0]){
case ‘0’:
memcpy(mybuffer,digits[0],8);
break;
case ‘1’:
memcpy(mybuffer,digits[1],8);
break;
case ‘2’:
memcpy(mybuffer,digits[2],8);
break;
case ‘3’:
memcpy(mybuffer,digits[3],8);
break;
case ‘4’:
memcpy(mybuffer,digits[4],8);
break;
case ‘5’:
memcpy(mybuffer,digits[5],8);
break;
case ‘6’:
memcpy(mybuffer,digits[6],8);
break;
case ‘7’:
memcpy(mybuffer,digits[7],8);
break;
case ‘8’:
memcpy(mybuffer,digits[8],8);
break;
case ‘9’:
memcpy(mybuffer,digits[9],8);
break;
default:break;
}
評論
查看更多