一、 实验目的和要求
1. 学习嵌入式Linux的GPIO的使用方式;
2. 学习嵌入式Linux的Arduino接口库;
3. 学习使用面包板搭简单的外部电路;
4. 学习Linux设备驱动程序的开发过程;
5. 学习在内核中访问外设寄存器,操作外设的方法
二、 实验器材
1. Linux实验板卡一块;
2. 5V/1A电源一个;
3. microUSB线一根;
4. 面包板一块;
5. MAX7219驱动的8*8 LED矩阵一个;
6. 面包线若干;
7. MacOS一台;
8. USE-TTL串口线一根
9. 以太网线一根;
10. 交叉编译软件
三、 实验内容和原理
1.设计方法,画连接示意图;
2.在面包板上连线,完成外部电路;
3.编写C/C++程序,采用Arduino-ish库或虚拟文件系统访问GPIO,实现在矩阵上显示文字或图案;
4.编写字符设备驱动程序,直接访问GPIO控制寄存器,能将write()送来的单个字符在矩阵上显示出来
四、 实验过程和数据记录
1. 以下是实物连接图
GPIO端口使用bcm编号的23,24,25,对应WiringPi的4,5,6号端口,分别连接到驱动板的DIN,CS,CLK
2. 使用Wiring访问GPIO
在用户级别程序访问GPIO,使用Wiring是个很好的选择。
#include
#include
#define PIN_DIN 4 // GPIO端口号,对应驱动板的DIN
#define PIN_CS 5 //GPIO端口号,对应驱动板的CS
#define PIN_CLK 6 //GPIO端口号,对应驱动板的CLK
unsigned char disp1[256][8] = { //ASCII码字体数据
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x0
{ 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E }, //0x1
{ 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E }, //0x2
{ 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x3
{ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x4
{ 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C }, //0x5
{ 0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C }, //0x6
{ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 }, //0x7
{ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF }, //0x8
{ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 }, //0x9
{ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF }, //0xA
{ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78 }, //0xB
{ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18 }, //0xC
{ 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0 }, //0xD
{ 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0 }, //0xE
{ 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 }, //0xF
{ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00 }, //0x10
{ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00 }, //0x11
{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18 }, //0x12
{ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 }, //0x13
{ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00 }, //0x14
{ 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78 }, //0x15
{ 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00 }, //0x16
{ 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF }, //0x17
{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0x18
{ 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00 }, //0x19
{ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00 }, //0x1A
{ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00 }, //0x1B
{ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00 }, //0x1C
{ 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00 }, //0x1D
{ 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00 }, //0x1E
{ 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00 }, //0x1F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x20
{ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00 }, //0x21
{ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x22
{ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00 }, //0x23
{ 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00 }, //0x24
{ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00 }, //0x25
{ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00 }, //0x26
{ 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x27
{ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00 }, //0x28
{ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00 }, //0x29
{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 }, //0x2A
{ 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00 }, //0x2B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x2C
{ 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00 }, //0x2D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x2E
{ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00 }, //0x2F
{ 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00 }, //0x30
{ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00 }, //0x31
{ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00 }, //0x32
{ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00 }, //0x33
{ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00 }, //0x34
{ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00 }, //0x35
{ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00 }, //0x36
{ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00 }, //0x37
{ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x38
{ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00 }, //0x39
{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x3A
{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x3B
{ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00 }, //0x3C
{ 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00 }, //0x3D
{ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00 }, //0x3E
{ 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00 }, //0x3F
{ 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00 }, //0x40
{ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00 }, //0x41
{ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00 }, //0x42
{ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00 }, //0x43
{ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00 }, //0x44
{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00 }, //0x45
{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00 }, //0x46
{ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00 }, //0x47
{ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x48
{ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x49
{ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00 }, //0x4A
{ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00 }, //0x4B
{ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00 }, //0x4C
{ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00 }, //0x4D
{ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00 }, //0x4E
{ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00 }, //0x4F
{ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 }, //0x50
{ 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00 }, //0x51
{ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00 }, //0x52
{ 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00 }, //0x53
{ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x54
{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00 }, //0x55
{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x56
{ 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00 }, //0x57
{ 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00 }, //0x58
{ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00 }, //0x59
{ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00 }, //0x5A
{ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00 }, //0x5B
{ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00 }, //0x5C
{ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00 }, //0x5D
{ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 }, //0x5E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, //0x5F
{ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x60
{ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 }, //0x61
{ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00 }, //0x62
{ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00 }, //0x63
{ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00 }, //0x64
{ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x65
{ 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00 }, //0x66
{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x67
{ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00 }, //0x68
{ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x69
{ 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78 }, //0x6A
{ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00 }, //0x6B
{ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x6C
{ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00 }, //0x6D
{ 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x6E
{ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x6F
{ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0 }, //0x70
{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E }, //0x71
{ 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00 }, //0x72
{ 0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00 }, //0x73
{ 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00 }, //0x74
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 }, //0x75
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x76
{ 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00 }, //0x77
{ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00 }, //0x78
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x79
{ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00 }, //0x7A
{ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00 }, //0x7B
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, //0x7C
{ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00 }, //0x7D
{ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x7E
{ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00 }, //0x7F
{ 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78 }, //0x80
{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x81
{ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x82
{ 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00 }, //0x83
{ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x84
{ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x85
{ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x86
{ 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38 }, //0x87
{ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00 }, //0x88
{ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x89
{ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x8A
{ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8B
{ 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00 }, //0x8C
{ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8D
{ 0xC6, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00 }, //0x8E
{ 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00 }, //0x8F
{ 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00 }, //0x90
{ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00 }, //0x91
{ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00 }, //0x92
{ 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x93
{ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x94
{ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x95
{ 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x96
{ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x97
{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x98
{ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00 }, //0x99
{ 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x9A
{ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18 }, //0x9B
{ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00 }, //0x9C
{ 0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30 }, //0x9D
{ 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7 }, //0x9E
{ 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70 }, //0x9F
{ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0xA0
{ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0xA1
{ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0xA2
{ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0xA3
{ 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00 }, //0xA4
{ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00 }, //0xA5
{ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00 }, //0xA6
{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00 }, //0xA7
{ 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00 }, //0xA8
{ 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00 }, //0xA9
{ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00 }, //0xAA
{ 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F }, //0xAB
{ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03 }, //0xAC
{ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xAD
{ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00 }, //0xAE
{ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00 }, //0xAF
{ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 }, //0xB0
{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA }, //0xB1
{ 0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE }, //0xB2
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xB3
{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB4
{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB5
{ 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36 }, //0xB6
{ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36 }, //0xB7
{ 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB8
{ 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xB9
{ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }, //0xBA
{ 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xBB
{ 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00 }, //0xBC
{ 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00 }, //0xBD
{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xBE
{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18 }, //0xBF
{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xC0
{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00 }, //0xC1
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xC2
{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC3
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xC4
{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xC5
{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC6
{ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36 }, //0xC7
{ 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00 }, //0xC8
{ 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xC9
{ 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCA
{ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCB
{ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xCC
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCD
{ 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCE
{ 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCF
{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00 }, //0xD0
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xD1
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36 }, //0xD2
{ 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00 }, //0xD3
{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xD4
{ 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xD5
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36 }, //0xD6
{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36 }, //0xD7
{ 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xD8
{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xD9
{ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18 }, //0xDA
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDB
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDC
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 }, //0xDD
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, //0xDE
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }, //0xDF
{ 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00 }, //0xE0
{ 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0 }, //0xE1
{ 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00 }, //0xE2
{ 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00 }, //0xE3
{ 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00 }, //0xE4
{ 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00 }, //0xE5
{ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0 }, //0xE6
{ 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xE7
{ 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC }, //0xE8
{ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00 }, //0xE9
{ 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00 }, //0xEA
{ 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00 }, //0xEB
{ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00 }, //0xEC
{ 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0 }, //0xED
{ 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00 }, //0xEE
{ 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0xEF
{ 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00 }, //0xF0
{ 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00 }, //0xF1
{ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00 }, //0xF2
{ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00 }, //0xF3
{ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xF4
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70 }, //0xF5
{ 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00 }, //0xF6
{ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00 }, //0xF7
{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00 }, //0xF8
{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 }, //0xF9
{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 }, //0xFA
{ 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C }, //0xFB
{ 0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00 }, //0xFC
{ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00 }, //0xFD
{ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 }, //0xFE
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0xFF
};
void write_byte(unsigned char data) //最底层的传输一个byte的函数
{
unsigned char i;
digitalWrite(PIN_CS, LOW);
for(i=8; i>=1; i--)
{
digitalWrite(PIN_CLK, LOW);
digitalWrite(PIN_DIN, data&0x80);
data = data<<1;
digitalWrite(PIN_CLK, HIGH);
}
}
void write(unsigned char addr, unsigned char data) //传输一行数据函数
{
digitalWrite(PIN_CS, LOW);
write_byte(addr);
write_byte(data);
digitalWrite(PIN_CS, HIGH);
}
void init() //初始化芯片
{
write(0x09, 0x00);
write(0x0a, 0x03);
write(0x0b, 0x07);
write(0x0c, 0x01);
write(0x0f, 0x00);
}
int main()
{
unsigned char i, j;
wiringPiSetup();
pinMode(PIN_DIN, OUTPUT);
pinMode(PIN_CS, OUTPUT);
pinMode(PIN_CLK, OUTPUT);
init();
while (1)
{
for(j=0; j<256; j++)
{
for(i=1; i<9; i++)
write(i, disp1[j][i-1]);
printf("0x%02X
", j);
delay(500);
}
}
return 0;
}
从以下两个图片来看,显示效果良好
3. Linux字符设备驱动
Linux内核模块能更方便快捷地调整内核功能,而无需重新编译内核花费巨大的时间。通过编写字符设备驱动模块,能够使得系统通过/dev以字符设备的方式来写数据到8*8的led矩阵中显示。
#include // 用于标记函数的宏,如_init、__exit
#include // 将内核模块加载到内核中的核心头文件
#include // 支持内核驱动模型的头文件
#include // 包含内核中的类型、宏和函数
#include // 支持Linux文件系统的头文件
#include // 复制到用户用户空间函数需要的头文件
#include // GPIO
#define DEVICE_NAME "matrix" ///< 使用此值,设备将会展示在/dev/matrix
#define CLASS_NAME "mat" ///< 设备类名,这是一个字符设备驱动
MODULE_LICENSE("GPL"); ///< 许可类型,这回影响到可用功能
MODULE_VERSION("0.1"); ///< 告知用户的版本号
static int majorNumber; ///< 保存主设备号,这里自动确定
static char message[256] = {0}; ///< 用于保存从用户空间传输过来字符串的内存
static short size_of_message; ///< 用于记录保存的字符串长度
static int numberOpens = 0; ///< 用于保存设备打开次数的计数器
static struct class* matClass = NULL; ///< 设备驱动类结构体指针
static struct device* matDevice = NULL; ///< 设备驱动设备结构体指针
// 字符设备操作的函数原型,必须在结构体定义前定义
static int dev_open(struct inode *, struct file *);
static int dev_release(struct inode *, struct file *);
static ssize_t dev_read(struct file *, char *, size_t, loff_t *);
static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);
/** @brief 设备在内核中被表示为文件结构。 /linux/fs.h中定义的file_operations结构体,
* 它使用C99语法的结构体,列举了文件操作关联的回调函数。
* 字符设备通常需要实现open、read、write和release函数。
*/
static struct file_operations fops =
{
.open = dev_open,
.read = dev_read,
.write = dev_write,
.release = dev_release,
};
/** @brief 可加载内核模块初始化函数
* static关键字限制该函数的可见性在该C文件之内。 The __init
* __init宏对于内置驱动(非可加载内核模块)来说,只在初始化时调用,在此之后,该函数将被废弃,内存将被回收。
* @return 如果成功返回0
*/
static int __init matrix_init(void){
printk(KERN_INFO "Initializing matrix.
");
// 尝试为这个设备动态生成一个主设备号,虽然麻烦一点,但这是值得的
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
if (majorNumber<0){
printk(KERN_ALERT "Failed to register a major number.
");
return majorNumber;
}
// printk(KERN_INFO "EBBChar: registered correctly with major number %d
", majorNumber);
// 注册设备类
matClass = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(matClass)){ // 如果有错误,清理环境
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to register device class.
");
return PTR_ERR(matClass); // 对于指针类型返回错误消息正确的方式
}
// printk(KERN_INFO "EBBChar: device class registered correctly
");
// 注册设备驱动
matDevice = device_create(matClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
if (IS_ERR(matDevice)){ // 如果有错误,清理环境
class_destroy(matClass); // 重复的代码,可选方式是使用goto语句
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to create the device.
");
return PTR_ERR(matDevice);
}
// printk(KERN_INFO "EBBChar: device class created correctly
"); // 搞定,设备已经初始化
return 0;
}
/** @brief 可加载内核模块清理函数
* 和初始化函数类似,该函数是静态的。__exit宏标识如果这个代码是使用在内置驱动(非可加载内核模块)中,该函数不需要。
*/
static void __exit matrix_exit(void){
device_destroy(matClass, MKDEV(majorNumber, 0)); // 移除设备
class_unregister(matClass); // 注销设备类
class_destroy(matClass); // 移除设备类
unregister_chrdev(majorNumber, DEVICE_NAME); // 注销主设备号
printk(KERN_INFO "Goodbye!
");
}
static unsigned PIN_DIN = 23;
static unsigned PIN_CS = 24;
static unsigned PIN_CLK = 25;
static unsigned char disp1[256][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x0
{ 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E }, //0x1
{ 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E }, //0x2
{ 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x3
{ 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, //0x4
{ 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C }, //0x5
{ 0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C }, //0x6
{ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 }, //0x7
{ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF }, //0x8
{ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 }, //0x9
{ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF }, //0xA
{ 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78 }, //0xB
{ 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18 }, //0xC
{ 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0 }, //0xD
{ 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0 }, //0xE
{ 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 }, //0xF
{ 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00 }, //0x10
{ 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00 }, //0x11
{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18 }, //0x12
{ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 }, //0x13
{ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00 }, //0x14
{ 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78 }, //0x15
{ 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00 }, //0x16
{ 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF }, //0x17
{ 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0x18
{ 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00 }, //0x19
{ 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00 }, //0x1A
{ 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00 }, //0x1B
{ 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00 }, //0x1C
{ 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00 }, //0x1D
{ 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00 }, //0x1E
{ 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00 }, //0x1F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x20
{ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00 }, //0x21
{ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x22
{ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00 }, //0x23
{ 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00 }, //0x24
{ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00 }, //0x25
{ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00 }, //0x26
{ 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x27
{ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00 }, //0x28
{ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00 }, //0x29
{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 }, //0x2A
{ 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00 }, //0x2B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x2C
{ 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00 }, //0x2D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x2E
{ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00 }, //0x2F
{ 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00 }, //0x30
{ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00 }, //0x31
{ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00 }, //0x32
{ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00 }, //0x33
{ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00 }, //0x34
{ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00 }, //0x35
{ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00 }, //0x36
{ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00 }, //0x37
{ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x38
{ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00 }, //0x39
{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00 }, //0x3A
{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60 }, //0x3B
{ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00 }, //0x3C
{ 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00 }, //0x3D
{ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00 }, //0x3E
{ 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00 }, //0x3F
{ 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00 }, //0x40
{ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00 }, //0x41
{ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00 }, //0x42
{ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00 }, //0x43
{ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00 }, //0x44
{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00 }, //0x45
{ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00 }, //0x46
{ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00 }, //0x47
{ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x48
{ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x49
{ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00 }, //0x4A
{ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00 }, //0x4B
{ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00 }, //0x4C
{ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00 }, //0x4D
{ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00 }, //0x4E
{ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00 }, //0x4F
{ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 }, //0x50
{ 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00 }, //0x51
{ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00 }, //0x52
{ 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00 }, //0x53
{ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x54
{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00 }, //0x55
{ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x56
{ 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00 }, //0x57
{ 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00 }, //0x58
{ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00 }, //0x59
{ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00 }, //0x5A
{ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00 }, //0x5B
{ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00 }, //0x5C
{ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00 }, //0x5D
{ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 }, //0x5E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, //0x5F
{ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x60
{ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00 }, //0x61
{ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00 }, //0x62
{ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00 }, //0x63
{ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00 }, //0x64
{ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x65
{ 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00 }, //0x66
{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x67
{ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00 }, //0x68
{ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x69
{ 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78 }, //0x6A
{ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00 }, //0x6B
{ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x6C
{ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00 }, //0x6D
{ 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0x6E
{ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x6F
{ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0 }, //0x70
{ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E }, //0x71
{ 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00 }, //0x72
{ 0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00 }, //0x73
{ 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00 }, //0x74
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00 }, //0x75
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00 }, //0x76
{ 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00 }, //0x77
{ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00 }, //0x78
{ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x79
{ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00 }, //0x7A
{ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00 }, //0x7B
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, //0x7C
{ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00 }, //0x7D
{ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0x7E
{ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00 }, //0x7F
{ 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78 }, //0x80
{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x81
{ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x82
{ 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00 }, //0x83
{ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x84
{ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x85
{ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0x86
{ 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38 }, //0x87
{ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00 }, //0x88
{ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x89
{ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00 }, //0x8A
{ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8B
{ 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00 }, //0x8C
{ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0x8D
{ 0xC6, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00 }, //0x8E
{ 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00 }, //0x8F
{ 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00 }, //0x90
{ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00 }, //0x91
{ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00 }, //0x92
{ 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x93
{ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x94
{ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0x95
{ 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x96
{ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0x97
{ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8 }, //0x98
{ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00 }, //0x99
{ 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00 }, //0x9A
{ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18 }, //0x9B
{ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00 }, //0x9C
{ 0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30 }, //0x9D
{ 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7 }, //0x9E
{ 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70 }, //0x9F
{ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00 }, //0xA0
{ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 }, //0xA1
{ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00 }, //0xA2
{ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00 }, //0xA3
{ 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00 }, //0xA4
{ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00 }, //0xA5
{ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00 }, //0xA6
{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00 }, //0xA7
{ 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00 }, //0xA8
{ 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00 }, //0xA9
{ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00 }, //0xAA
{ 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F }, //0xAB
{ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03 }, //0xAC
{ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xAD
{ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00 }, //0xAE
{ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00 }, //0xAF
{ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 }, //0xB0
{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA }, //0xB1
{ 0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE }, //0xB2
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xB3
{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB4
{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB5
{ 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36 }, //0xB6
{ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36 }, //0xB7
{ 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18 }, //0xB8
{ 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xB9
{ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }, //0xBA
{ 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36 }, //0xBB
{ 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00 }, //0xBC
{ 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00 }, //0xBD
{ 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xBE
{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18 }, //0xBF
{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xC0
{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00 }, //0xC1
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xC2
{ 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC3
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xC4
{ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xC5
{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xC6
{ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36 }, //0xC7
{ 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00 }, //0xC8
{ 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xC9
{ 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCA
{ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCB
{ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36 }, //0xCC
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCD
{ 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36 }, //0xCE
{ 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00 }, //0xCF
{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00 }, //0xD0
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18 }, //0xD1
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36 }, //0xD2
{ 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00 }, //0xD3
{ 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00 }, //0xD4
{ 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18 }, //0xD5
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36 }, //0xD6
{ 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36 }, //0xD7
{ 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18 }, //0xD8
{ 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00 }, //0xD9
{ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18 }, //0xDA
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDB
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, //0xDC
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 }, //0xDD
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, //0xDE
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }, //0xDF
{ 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00 }, //0xE0
{ 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0 }, //0xE1
{ 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00 }, //0xE2
{ 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00 }, //0xE3
{ 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00 }, //0xE4
{ 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00 }, //0xE5
{ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0 }, //0xE6
{ 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00 }, //0xE7
{ 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC }, //0xE8
{ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00 }, //0xE9
{ 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00 }, //0xEA
{ 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00 }, //0xEB
{ 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00 }, //0xEC
{ 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0 }, //0xED
{ 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00 }, //0xEE
{ 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00 }, //0xEF
{ 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00 }, //0xF0
{ 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00 }, //0xF1
{ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00 }, //0xF2
{ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00 }, //0xF3
{ 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18 }, //0xF4
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70 }, //0xF5
{ 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00 }, //0xF6
{ 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00 }, //0xF7
{ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00 }, //0xF8
{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 }, //0xF9
{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 }, //0xFA
{ 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C }, //0xFB
{ 0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00 }, //0xFC
{ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00 }, //0xFD
{ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 }, //0xFE
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0xFF
};
static void writeMatrix_byte(unsigned char data)
{
unsigned char i;
gpio_set_value(PIN_CS, 0);
for(i=8; i>=1; i--)
{
gpio_set_value(PIN_CLK, 0);
gpio_set_value(PIN_DIN, data&0x80);
data = data<<1;
gpio_set_value(PIN_CLK, 1);
}
}
static void writeMatrix(unsigned char addr, unsigned char data)
{
gpio_set_value(PIN_CS, 0);
writeMatrix_byte(addr);
writeMatrix_byte(data);
gpio_set_value(PIN_CS, 1);
}
/** @brief 每次设备被代开的时候调用的设备打开函数
* 在本例中,该函数只是简单的累加numberOpens计数器。
* @param inodep 指向inode对象的指针(定义在linux/fs.h头文件中)
* @param filep 指向文件对象指针(定义在linux/fs.h头文件中)
*/
static int dev_open(struct inode *inodep, struct file *filep)
{
int req_din = gpio_request(PIN_DIN, "PIN_DIN");
int req_cs = gpio_request(PIN_CS, "PIN_CS");
int req_clk = gpio_request(PIN_CLK, "PIN_CLK");
if (req_din || req_cs || req_clk) {
return -1;
}
gpio_direction_output(PIN_DIN, 0);
gpio_direction_output(PIN_CS, 0);
gpio_direction_output(PIN_CLK, 0);
numberOpens++;
printk(KERN_INFO "Device has been opened %d time(s)
", numberOpens);
writeMatrix(0x09, 0x00);
writeMatrix(0x0a, 0x03);
writeMatrix(0x0b, 0x07);
writeMatrix(0x0c, 0x01);
writeMatrix(0x0f, 0x00);
return 0;
}
/** @brief 该函数在设备从用户空间读取的时候被调用,即数据从设备向用户空间传输。
* 在本例中,通过copy_to_user()函数将缓冲区中的字符串发送给用户,并且捕获任何异常。
* @param filep 指向文件对象的指针(定义在linux/fs.h头文件中)
* @param buffer 指向本函数写入数据的缓冲区指针
* @param len 缓冲区长度
* @param offset 此次读取在内核缓冲区中的偏移量
*/
static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
{
return 0;
}
/** @brief 该函数在设备想用户空间写入的时候调用,即从数据从用户发往设备。
* 在此内核模块中,数据通过sprintf()函数复制到message[]数组中,同时字符串长度被保存到size_of_message变量中。
* @param filep 指向文件对象的指针
* @param buffer 包含待写入设备字符串的缓冲区
* @param len 传递到const char类型缓冲区的数据长度
* @param offset 文件设备当前偏移量
*/
static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset)
{
//sprintf(message, "%s(%d letters)", buffer, len); // 通过长度追加当前接受到的字符串
unsigned char i;
for(i = 1; i < 9; i++)
writeMatrix(i, disp1[(unsigned char)buffer[0]][i-1]);
size_of_message = 1;
printk(KERN_INFO "Received characters %c from the user
", buffer[0]);
return len;
}
/** @brief 当设备被用户空间程序关闭/释放时调用的函数。
* @param inodep 指向inode对象的指针(定义在linux/fs.h头文件中)
* @param filep 指向文件对象的指针(定义在linux/fs.h头文件中)
*/
static int dev_release(struct inode *inodep, struct file *filep)
{
gpio_free(PIN_DIN);
gpio_free(PIN_CS);
gpio_free(PIN_CLK);
printk(KERN_INFO "Device closed.
");
return 0;
}
/** @brief 内核模块必须使用linux/init.h头文件中提供的module_init()、module_exit()宏,
* 在插入和清理的时候标识对应的函数(如上所列)
*/
module_init(matrix_init);
module_exit(matrix_exit);
编译后,生成后缀为ko的内核模块,使用insmod插入内核模块时,可以看到内核日志中带有初始化的信息提示,在使用open()打开设备文件后,可以看到其打开的信息提示。而通过write()往设备文件中写入数据时,亦可以看到内核日志中接收到字符的提示。