分别编写一个应用程序和字符驱动程序实现wiringPi的digitalWrite(pin, value)功能 ,代码内带有注释
时间: 2024-06-11 20:07:55 浏览: 118
应用程序代码:
```c
#include <stdio.h>
#include <wiringPi.h>
int main()
{
// 初始化wiringPi库
wiringPiSetup();
// 设置GPIO17为输出模式
pinMode(0, OUTPUT);
// 设置GPIO17输出高电平
digitalWrite(0, HIGH);
return 0;
}
```
字符驱动程序代码:
```c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#define GPIO_PIN 17 // GPIO17对应的引脚号
#define DEVICE_NAME "wiringPi" // 设备名称
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple example Linux module.");
MODULE_VERSION("0.01");
static int majorNumber; // 设备号
static char message[256] = {0}; // 存储从用户空间读入的数据
static short sizeOfMessage; // message的长度
static int openCounter = 0; // 记录设备被打开的次数
static struct class* wiringPiClass = NULL; // 设备类指针
static struct device* wiringPiDevice = NULL; // 设备指针
// 在设备被打开时执行的函数
static int wiringPi_open(struct inode* inodep, struct file* filep)
{
openCounter++;
printk(KERN_INFO "wiringPi: Device has been opened %d time(s)\n", openCounter);
return 0;
}
// 在设备被关闭时执行的函数
static int wiringPi_release(struct inode* inodep, struct file* filep)
{
printk(KERN_INFO "wiringPi: Device successfully closed\n");
return 0;
}
// 在从设备中读取数据时执行的函数
static ssize_t wiringPi_read(struct file* filep, char* buffer, size_t len, loff_t* offset)
{
int errorCount = 0;
errorCount = copy_to_user(buffer, message, sizeOfMessage);
if (errorCount == 0)
{
printk(KERN_INFO "wiringPi: Sent %d characters to the user\n", sizeOfMessage);
return (sizeOfMessage = 0);
}
else
{
printk(KERN_INFO "wiringPi: Failed to send %d characters to the user\n", errorCount);
return -EFAULT;
}
}
// 在向设备中写入数据时执行的函数
static ssize_t wiringPi_write(struct file* filep, const char* buffer, size_t len, loff_t* offset)
{
int errorCount = 0;
errorCount = copy_from_user(message, buffer, len);
if (errorCount == 0)
{
sizeOfMessage = len;
printk(KERN_INFO "wiringPi: Received %d characters from the user\n", len);
// 设置GPIO17的输出值
if (message[0] == '1')
{
gpio_set_value(GPIO_PIN, 1);
}
else if (message[0] == '0')
{
gpio_set_value(GPIO_PIN, 0);
}
else
{
printk(KERN_ALERT "wiringPi: Invalid value received from user\n");
return -EINVAL;
}
return len;
}
else
{
printk(KERN_ALERT "wiringPi: Failed to receive %d characters from the user\n", errorCount);
return -EFAULT;
}
}
// 设备文件操作集
static struct file_operations fops =
{
.open = wiringPi_open,
.read = wiringPi_read,
.write = wiringPi_write,
.release = wiringPi_release,
};
// 模块初始化函数
static int __init wiringPi_init(void)
{
int error = 0;
// 初始化GPIO
if (!gpio_is_valid(GPIO_PIN))
{
printk(KERN_ALERT "wiringPi: Invalid GPIO pin\n");
return -ENODEV;
}
gpio_request(GPIO_PIN, "wiringPi");
gpio_direction_output(GPIO_PIN, 0);
// 分配设备号
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
if (majorNumber < 0)
{
printk(KERN_ALERT "wiringPi: Failed to register a major number\n");
return majorNumber;
}
// 创建设备类
wiringPiClass = class_create(THIS_MODULE, DEVICE_NAME);
if (IS_ERR(wiringPiClass))
{
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "wiringPi: Failed to create a device class\n");
return PTR_ERR(wiringPiClass);
}
// 创建设备文件
wiringPiDevice = device_create(wiringPiClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
if (IS_ERR(wiringPiDevice))
{
class_destroy(wiringPiClass);
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "wiringPi: Failed to create a device file\n");
return PTR_ERR(wiringPiDevice);
}
printk(KERN_INFO "wiringPi: Device driver successfully registered\n");
return 0;
}
// 模块退出函数
static void __exit wiringPi_exit(void)
{
gpio_set_value(GPIO_PIN, 0);
gpio_free(GPIO_PIN);
device_destroy(wiringPiClass, MKDEV(majorNumber, 0));
class_unregister(wiringPiClass);
class_destroy(wiringPiClass);
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_INFO "wiringPi: Device driver successfully unregistered\n");
}
// 注册初始化和退出函数
module_init(wiringPi_init);
module_exit(wiringPi_exit);
```
注意:以上代码中的GPIO_PIN变量定义为17,如果你使用的是其他引脚,需要修改该变量的值。另外,由于Raspberry Pi上的GPIO引脚编号和wiringPi库中的编号不同,因此需要在代码中将wiringPi库的编号转换为GPIO引脚编号。例如,将wiringPi库中的0号引脚转换为GPIO17,需要将GPIO_PIN变量定义为17。