#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include <delay.h>
#include "m74hc595.h"
typedef void (*sighandler_t)(int);
int num[4] = {0, 0, 0, 0};
int fd;
int flag = 1;
void *callBack(void *arg)
{
while (1)
{
if (flag == 1)
{
ioctl(fd, LED_WHICH, 0);
ioctl(fd, LED_DATA, num[0]);
ioctl(fd, LED_WHICH, 1);
ioctl(fd, LED_DATA, num[1]);
ioctl(fd, LED_WHICH, 2);
ioctl(fd, LED_DATA, num[2]);
ioctl(fd, LED_WHICH, 3);
ioctl(fd, LED_DATA, num[3]);
}
delay(100);
}
pthread_exit((void *)1);
}
int main(int argc, const char *argv[])
{
fd = open("/dev/m74hc595", O_RDWR);
if (fd < 0)
{
printf("open err\n");
exit(-1);
}
printf("打开设备文件成功\n");
pthread_t tid;
if (pthread_create(&tid, NULL, callBack, NULL) != 0)
{
perror("pthread_create");
return -1;
}
printf("线程创建成功\n");
int how;
while (1)
{
printf("是否要输入: 1是,2否\n");
scanf("%d", &how);
if (how == 1)
{
flag = 0;
}
printf("请输入你想要显示的数字,中间用空格空开:\n");
scanf("%d%d%d%d", &num[0], &num[1], &num[2], &num[3]);
flag = 1;
}
return 0;
}
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include "m74hc595.h"
int major;
struct spi_device *cli;
struct class *cls;
struct device *dev;
char buf[4];
u8 num[] = {
0x3f,
0x06,
0x5b,
0x4f,
0x66,
0x6d,
0x7d,
0x7f,
0x6f,
0x77,
0x7c,
0x39,
0x5e,
0x79,
0x71,
};
u8 which[] = {
0x1,
0x2,
0x4,
0x8,
};
long m74hc595_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case LED_WHICH:
spi_write(cli, &which[arg], 1);
break;
case LED_DATA:
spi_write(cli, &num[arg], 1);
break;
}
return 0;
}
int m74hc595_open(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
return 0;
}
int m74hc595_close(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
return 0;
}
//定义操作方法结构体
struct file_operations fops = {
.open = m74hc595_open,
.unlocked_ioctl = m74hc595_ioctl,
.release = m74hc595_close,
};
int m74hc595_probe(struct spi_device *spi)
{
cli = spi;
//注册字符设备
major = register_chrdev(0, "m74hc595", &fops);
if (major < 0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动成功\n");
//自动创建设备节点
//向上提交目录
cls = class_create(THIS_MODULE, "m74hc595");
if (IS_ERR(cls))
{
printk("向上提交目录失败\n");
return PTR_ERR(cls);
}
printk("向上提交目录成功\n");
//向上提交节点信息
dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "m74hc595");
if (IS_ERR(dev))
{
printk("向上提交节点信息失败\n");
return PTR_ERR(dev);
}
printk("向上提交节点成功\n");
return 0;
}
int m74hc595_remove(struct spi_device *spi)
{
printk("%s:%d\n", __FILE__, __LINE__);
return 0;
}
//设备树匹配表
struct of_device_id of_table[] = {
{.compatible = "hqyj,m74hc595"},
{},
};
MODULE_DEVICE_TABLE(of, of_table);
//定义SPI对象并且初始化
struct spi_driver m74hc595 = {
.probe = m74hc595_probe,
.remove = m74hc595_remove,
.driver = {
.name = "m74hc595",
.of_match_table = of_table,
},
};
module_spi_driver(m74hc595);
MODULE_LICENSE("GPL");
#ifndef __M74HC595_H__
#define __M74HC595_H__
#define LED_WHICH _IOW('a',0,int)
#define LED_DATA _IOW('a',1,int)
#endif