求大佬幫我,為什么測驗dht11在tiny4412上的驅動時,顯示resource temporary unavailable?
附上程式:
驅動:
#include <asm/cacheflush.h>
#include <linux/fdtable.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/nsproxy.h>
#include <linux/poll.h>
#include <linux/debugfs.h>
#include <linux/rbtree.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/gpio.h>
/* 定義DHT11接入的GPIO口 */
#define DHT11_PIN EXYNOS4_GPX1(7)
/* 定義檢測標志,用來判斷接收到的溫濕度資料是否正確 */
static unsigned char check_flag;
static unsigned char dht11_data_buf[6];
/*
* 讀取一個bit的資料
*/
static int dht11_read_one_bit(void)
{
gpio_direction_input(DHT11_PIN);
return gpio_get_value(DHT11_PIN);
}
/*set pin is out and set value of this pin*/
static void dht11_gpio_out(int value)
{
gpio_direction_output(DHT11_PIN, value);
}
/*read a byte data from dht11*/
static unsigned char dht11_read_byte(void)
{
int i = 0;
int num;
unsigned char flag = 0;
unsigned char data = 0;
for(num = 0; num < 8; num++)
{
i = 0;
/* 等待DHT11的引腳變為高電平 */
while(!gpio_get_value(DHT11_PIN))
{
udelay(10);
i++;
if(i > 10)
break;
}
flag = 0x00;
udelay(28);
if(gpio_get_value(DHT11_PIN))
{
flag = 0x01;
}
i = 0;
while(gpio_get_value(DHT11_PIN))
{
udelay(10);
i++;
if(i > 12)
break;
}
data <<= 1;
data |= flag;
}
return data;
}
/** read data format :
* 8bit : humidity integer
* 8bit : humidity decimal
* 8bit : temperature integer
* 8bit : temperature decimal
* 8bit : check code
* buf store data :
* dht11_data_buf[0] : humidity integer
* dht11_data_buf[1] : humidity decimal
* dht11_data_buf[2] : temperature integer
* dht11_data_buf[3] : temperature decimal
* dht11_data_buf[4] : check code
* dht11_data_buf[5] : self calculate check code
*/
static void dht11_read_data(void)
{
int i = 0;
dht11_gpio_out(0);
mdelay(30);
dht11_gpio_out(1);
udelay(20);
if(dht11_read_one_bit() == 0)
{
while(!gpio_get_value(DHT11_PIN)) /* 等待IO口變為高電平 */
{
udelay(5);
i++;
if(i > 20)
{
printk("dht11_read_data %d err!\n", __LINE__);
break;
}
}
i = 0;
while(gpio_get_value(DHT11_PIN)) /* 等待IO口變為低電平 */
{
udelay(5);
i++;
if(i > 20)
{
printk("dht11_read_data %d err!\n", __LINE__);
break;
}
}
for(i = 0; i < 5; i++) /* 讀取溫濕度資料 */
dht11_data_buf[i] = dht11_read_byte();
/* 對讀取到的資料進行校驗 */
dht11_data_buf[5] = dht11_data_buf[0]+dht11_data_buf[1]+dht11_data_buf[2]+dht11_data_buf[3];
/* 判斷讀到的校驗值和計算的校驗值是否相同 */
if(dht11_data_buf[4] == dht11_data_buf[5]) /* 相同則把標志值設為0xff */
{
check_flag = 0xff;
}
else if(dht11_data_buf[4] != dht11_data_buf[5]) /* 不相同則把標志值設為0 */
{
check_flag = 0x00;
printk("dht11 check fail\n");
}
}
}
/* 打開雜項設備,這里寫為空函式 */
static int dht11_open (struct inode *inode, struct file *file)
{
return 0;
}
/* 雜項設備的讀取函式 */
static ssize_t dht11_read (struct file *file, char __user *buffer, size_t size, loff_t *offset)
{
int ret;
unsigned long flags;
/* 因為DHT11的時序要求很高,所以在讀溫濕度的時候要讓代碼進入臨界區,防止內核調度和搶占 */
local_irq_save(flags);
dht11_read_data();
local_irq_restore(flags);
if(check_flag == 0xff)
{
/* 將讀取的溫濕度資料拷貝到用戶空間 */
ret = copy_to_user(buffer, dht11_data_buf, sizeof(dht11_data_buf));
if(ret < 0)
{
printk("copy to user err\n");
return -EAGAIN;
}
else
{
return 0;
}
}
else
{
return -EAGAIN;
}
}
/* 釋放函式,這里寫為空函式 */
static int dht11_release (struct inode *inode, struct file *file)
{
return 0;
}
/* 定義雜項設備操作的結構體并初始化成員函式指標 */
static const struct file_operations dht11_fops = {
.owner = THIS_MODULE,
.open = dht11_open,
.read = dht11_read,
.release = dht11_release,
};
/* 定義設備雜項設備結構體 */
static struct miscdevice dht11_miscdev = {
.minor = MISC_DYNAMIC_MINOR, /* 自動分配次設備號 */
.name = "dht11", /* 雜項設備的名字 */
.fops = &dht11_fops /* 雜項設備操作的結構體 */
};
/* 入口函式 */
static int yl_dht11_init(void)
{
int ret;
/* 申請對應的GPIO引腳資源,只有引腳資源沒有被使用才可以申請成功 */
ret = gpio_request(DHT11_PIN , "dht11");
if(ret)
{
printk("gpio_request for dht11 is failed!\n");
return ret;
}
/* 注冊雜項設備 */
ret = misc_register(&dht11_miscdev);
return ret;
}
/* 函式出口 */
static void yl_dht11_exit(void)
{
/* 釋放注冊的雜項設備和GPIO資源 */
misc_deregister(&dht11_miscdev);
gpio_free(DHT11_PIN);
}
module_init(yl_dht11_init);
module_exit(yl_dht11_exit);
MODULE_LICENSE("GPL");
測驗程式:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* 程式的入口函式 */
int main(int argc, char *argv[])
{
int fd;
unsigned char buf[6]; /* 定義存放資料的陣列 */
int length;
/* 以只讀方式打開設備節點 */
fd = open("/dev/dht11", O_RDONLY);
if(fd == -1)
{
printf("open failed!\n");
return -1;
}
while(1)
{
length = read(fd, buf, 6); /* 讀取溫濕度資料 */
if(length == -1)
{
printf("read error!\n");
return -1;
}
/* 將資料從終端列印出來 */
printf("Temp : %d, Humi : %d\n", buf[2], buf[0]);
sleep(2);
}
/* 關閉DHT11設備節點 */
close(fd);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/230060.html
標籤:硬件設計
上一篇:Verilog HDL
下一篇:1602液晶屏顯示
