- 论坛徽章:
- 0
|
作者:ARM混迹江湖
[摘自]http://blog.tianya.cn/blogger/post_show.asp?BlogID=648077&PostID=9434859
Linux下所有的设备都是以文件的形式来操作的。设备软件分为两部分:应用程序和驱动程序,其中,应用程序负责打开设备并对它发出读写指令,驱动程序接受指令并完成读写的过程。
本文以AD5310用于AP/BG为例,讲述其应用和驱动的编写过程。
1. 硬件电路
其中GPIO为CPU管脚,当J2上有Power Meter接上时,BNC_EN为低,程序开始从系统中获取RSSI,换算成相应的值以SPI时序送给AD5310,AD5310把它转化为相应电压,在Power Meter上显示。
2. 驱动实现
2.1 代码编写
驱动的编写主要是编写操作函数,例如读写等,因此驱动程序的结构比较单一,其主要的不同是操作函数的实现过程。
AD5310驱动的实现代码即说明如下:
#ifndef __KERNEL__ //判断驱动是编译进内核还是编译成模块
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include … //包含相关头文件
#ifndef __MOD_INC_USE_COUNT
#define AH_MOD_INC_USE_COUNT(_m) \
if (!try_module_get(_m)) { \
printk(KERN_WARNING "try_module_get failed\n"); \
return NULL; \
}
#define AH_MOD_DEC_USE_COUNT(_m) module_put(_m)
#else
#define AH_MOD_INC_USE_COUNT(_m) MOD_INC_USE_COUNT
#define AH_MOD_DEC_USE_COUNT(_m) MOD_DEC_USE_COUNT
#endif
… //此处声明函数
struct file_operations spi_fops= //告诉系统应用程序的某个命令由谁来执行
{ //file_operation 是系统定义的结构体
.owner = THIS_MODULE,
.open = AD5310_open,
.release = AD5310_release,
.write = AD5310_write,
.read = AD5310_read,
};
char spi_name[]="AD5310"; //device name
static int gmajor = 254; //device ID
/*************************************/
static int __init spidrv_init_module(void) //register device
{
int retv; //register_chrdev()是linux系统注册函数
retv=register_chrdev(gmajor,spi_name,&spi_fops);
if(retv> 12;
input = input & 0x01;
*buf = input;
return(1);
}
/*********************************************************************
*write data to output GPIO9
*AD5310 input register contents:
* DB15(MSB) ........................DB0(LSB)
* x x PD1 PD0 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 x x
*
*PD1 PD0 = 0 0 normal operation
*PD1 PD0 = 0 1 1K resister to GND power down modes
*PD1 PD0 = 1 0 100K to GND power down modes
*PD1 PD0 = 1 1 Three-State power down modes
********************************************************************/
static int AD5310_write(struct file *fp,char *buf,int len,loff_t *loff)
{
int i;
int temp;
int spibuf;
char *p;
int writedata;
p=buf; //get the data ,buf[1] low buf[0] high
writedata=*p;
p++;
writedata = (writedata 1023 || writedata /dev/null
#mknod /dev/AD5310 c 254 1
此时若驱动正常工作,就会输出打印信息 SPI device OK! ,并且在/dev 目录下可以看到 AD5310 这个设备。
3. 应用实现
Linux下应用程序以文件的形式来操作设备,其最基本的操作顺序为
Open() -> read()/write() -> close()
RSSI应用实现的代码如下:
#define __KERNEL__
#include … //包含需要的头文件
#define … //定义相关变量
/*******************************************************************
*get the RSSI value
*******************************************************************/
int GetRSSIvalue(void)
{
int8_t rssivalue;
const char *ifname;
char aa[5] = {"ath0"};
ifname = aa;
u_char buf[24*1024];
struct iwreq iwr;
u_char *cp;
int s, len;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s isi_rssi;
cp += si->isi_len, len -= si->isi_len;
} while (len >= sizeof(struct ieee80211req_sta_info));
return(rssivalue);
}
/*******************************************************************
*main function
*******************************************************************/
int main(int argc,char **argv)
{
int rssivalue;
int senddata;
int RSSIprecision;
char inputstate[2];
char databuf[2];
const int maxrssi=66;
const int minrssi=2;
int fd;
int size;
if((fd=open("/dev/AD5310",O_RDWR))==-1) //打开设备文件
{
perror("device open fail\n");
exit(1)
}
RSSIprecision=1023/maxrssi;
Delay(5);
while(1)
{
size = read(fd,inputstate,1,0); //读取GPIO12状态,查看是否有Meter接入
if(inputstate[0]==1) //no meter,high
{
printf("RSSI not enabled!\n");
printf("Please mount RSSI meter!\n");
Delay(1000);
}
else //有Meter接入
{
printf("mount RSSI meter OK!");
rssivalue = GetRSSIvalue(); //从系统中获得RSSI的值
printf("RSSI:%4d",rssivalue);
if(rssivalue > maxrssi)
{ //over load,display max vcc
senddata = 1023;
}
else if(rssivalue > 8;
write(fd,databuf,2,0); //把数据发送给AD5310
printf("databuf[1]=%d\n",databuf[1]);
printf("databuf[0]=%d\n",databuf[0]);
sleep(1); //延时
}
}
}
/**************************************************************/
/*end of RSSI_AD5310*/
另外,在编写真正的应用程序之前,为了保证驱动程序的正确性,一般会先写一些小的测试应用程序来测试驱动,在驱动正确的情况下才会编写测试我们需要的应用程序。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/98073/showart_1976386.html |
|