⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tosmac.c

📁 无线发射
💻 C
字号:
/* *   driver/tosmac/TOSMac.c * *   TOS_MAC Driver based on CC2420 radio chip *   It is compatible with TinyOS MAC layer. * *   Author: Gefan Zhang *   Last modified by Y.Cheng:11/April/2008  *              */#include <linux/config.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/interrupt.h>#include <linux/time.h>#include <linux/timer.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/ioctl.h>#include <linux/cdev.h>#include <linux/delay.h>#include <linux/poll.h>#include <asm/uaccess.h>#include <asm/irq.h>#include <asm/mach/irq.h>#include <asm/mach-types.h>#include <asm/hardware.h>#include <asm/system.h>#include <asm/arch/pxa-regs.h>#include <asm/arch/stargate2.h>#include "../platx/pmic.h"#include "SG2_CC2420.h"#include "TOSMac.h"#include "CC2420.h"#include "CC2420Const.h"#include "AM.h"#include "byteorder.h"/* module information */MODULE_AUTHOR("Gefan Zhang <gefan@soe.ucsc.edu>");MODULE_LICENSE("Dual BSD/GPL");MODULE_DESCRIPTION("TOS_MAC Driver based on CC2420");MODULE_VERSION ("0.2");//static int devno;static int devno_result;static int cdev_result;static int tosmac_major = TOSMAC_MAJOR;static int tosmac_minor = 0;u16 local_addr = 99;u16 TOS_LOCAL_ADDRESS = 99;module_param(tosmac_major, int, S_IRUGO);module_param(tosmac_minor, int, S_IRUGO);module_param(local_addr, ushort, S_IRUGO);struct tosmac_device *tosmac_dev;//size of payload dataint TOSH_DATA_LENGTH;// size of the full packetint MSG_DATA_SIZE;// size of header(including length byte) and payload dataint MSG_HEADER_DATA_SIZE;// size of the whole TOSMSGint TOSMSG_SIZE;static ssize_t tosmac_read (struct file *file, char __user *buffer,                            size_t length, loff_t *ppos);static ssize_t tosmac_write (struct file *file, const char __user *buffer,                             size_t length, loff_t *ppos);static unsigned int tosmac_poll (struct file *file, struct poll_table_struct *wait);static int tosmac_ioctl (struct inode *inode, struct file * file,                         unsigned int cmd, unsigned long arg);static int tosmac_open (struct inode *inode, struct file *file);static int tosmac_release (struct inode *inode, struct file *file);static struct file_operations tosmac_fops = {        .owner          THIS_MODULE,        .read           tosmac_read,        .write          tosmac_write,	.poll		tosmac_poll,        .ioctl          tosmac_ioctl,        .open           tosmac_open,        .release        tosmac_release,};static int tosmac_open (struct inode *inode, struct file *filp){    uint8_t ret;    struct tosmac_device *dev;    uint8_t is_non_blocking;    dev = container_of(inode->i_cdev, struct tosmac_device, cdev);    filp->private_data = dev;        if(filp->f_flags & O_NONBLOCK)	is_non_blocking = TRUE;    else	is_non_blocking = FALSE;        down(&dev->sem);    CC2420_start(is_non_blocking);        up(&dev->sem);    return 0;}static unsigned int tosmac_poll (struct file *filp, struct poll_table_struct *wait){    struct tosmac_device *dev = filp->private_data;    unsigned int mask;        mask = CC2420_poll(filp, wait);        return mask;}static ssize_t tosmac_read (struct file *filp, char __user *buffer,                            size_t count, loff_t *ppos){    struct tosmac_device *dev = filp->private_data;    int ret = 0;    int i;        if(CC2420_read( )){	if(rx_packet.length != 255) {	        count = ((count+TOSMSG_SIZE - TOSH_DATA_LENGTH)  < TOSMSG_SIZE) ? (count+(TOSMSG_SIZE - TOSH_DATA_LENGTH)) : TOSMSG_SIZE;//YC//                printk("count in tosmac: %d, TOSMSG: %d\n",count,TOSMSG_SIZE);         	if(copy_to_user(buffer, &rx_packet, count)) {			ret = -EFAULT;			goto out;	 	}         	ret = count;	} else 		ret = -EFAULT;    }    else {//		printk(KERN_INFO "non_blocking read, no data in rxfifo\n");		ret = -EAGAIN;     	}out:    return ret;}static ssize_t tosmac_write (struct file *filp, const char __user *buffer,                             size_t count, loff_t *ppos){    struct tosmac_device *dev = filp->private_data;    int i, ret = 0;    TOS_Msg *packet_buf;    int buf_length;    int retval;//    down(&dev->sem);    packet_buf = kmalloc(sizeof(TOS_Msg), GFP_KERNEL);    count = (count > TOSH_DATA_LENGTH) ? TOSH_DATA_LENGTH : count;    buf_length = MSG_HEADER_SIZE + 1 + count;    if (copy_from_user(packet_buf, buffer, buf_length)) {        ret = -EFAULT;        goto out;    }       //reset length to count    packet_buf->length = count;	    retval = CC2420_send(packet_buf);    if(retval && (tx_buf_ptr->length != 255))    	ret = count;    else	ret = -EFAULT;    out:    kfree(packet_buf);//    up(&dev->sem);    return ret;}static int tosmac_ioctl (struct inode *inode, struct file * file,                         unsigned int cmd, unsigned long arg){    int ret = 0;    int err = 0;    int channel, freq;    int power;    //arguments check    if (_IOC_TYPE(cmd) != TOSMAC_IOCTL_MAGIC) return -ENOTTY;    if (_IOC_DIR(cmd) & _IOC_READ)	err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));    else if (_IOC_DIR(cmd) & _IOC_WRITE)	err =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));    if (err) return -EFAULT;    // FIXME:  Most of this should be pushed to the lower layer so that other     // systems such as PSI can make use of it.  Only the LINUX specific    // stuff should be here...    switch(cmd) {     case TOSMAC_IOSETADDR:	TOS_LOCAL_ADDRESS = arg;	CC2420_set_short_addr(TOS_LOCAL_ADDRESS);	break;     case TOSMAC_IOGETADDR:	return TOS_LOCAL_ADDRESS;		break;     case TOSMAC_IOAUTOACK:	CC2420_enable_ack();	break;     case TOSMAC_IODISAUTOACK:	CC2420_disable_ack();	break;     case TOSMAC_IOSETCHAN: 	channel = arg;	if(channel < 11) channel = 11;	if(channel > 26) channel = 26;	CC2420_tune_preset(channel);	break;            case TOSMAC_IOGETCHAN:	return CC2420_get_preset();	break;     case TOSMAC_IOSETFREQ: 	freq = arg;	if(freq < 2405) freq = 2405;	if(freq > 2480) freq = 2480;	CC2420_tune_manual(freq);	break;            case TOSMAC_IOGETFREQ:	return CC2420_get_frequency();	break;     case TOSMAC_IOSETMAXDATASIZE:	TOSH_DATA_LENGTH = arg;    	MSG_DATA_SIZE = 10 + TOSH_DATA_LENGTH + sizeof(uint16_t);    	MSG_HEADER_DATA_SIZE = 10 + TOSH_DATA_LENGTH;    	TOSMSG_SIZE = MSG_HEADER_DATA_SIZE + TOSMSG_FOOTER_SIZE;	break;     case TOSMAC_IOGETMAXDATASIZE:	return TOSH_DATA_LENGTH;	break;     case TOSMAC_IOSETPOWER:	power = arg;	if (power > 31) power = 31;	if (power < 3 ) power = 3;	CC2420_set_rf_power((uint8_t)power);		break;     case TOSMAC_IOGETPOWER:	return CC2420_get_rf_power();	break;     default:	ret = -ENOTTY;    }    return ret;}static int tosmac_release (struct inode *inode, struct file *filp){    struct tosmac_device *dev;    dev = container_of(inode->i_cdev, struct tosmac_device, cdev);    filp->private_data = dev;//    printk(KERN_INFO "close tosmac\n");    CC2420_stop(dev);    return 0;}static void __exit tosmac_exit(void){   printk(KERN_INFO "TOSMAC driver is unloading...\n");   if(tosmac_dev != NULL) {	/*power off radio */	CC2420_exit(tosmac_dev);	if(!cdev_result)            cdev_del(&(tosmac_dev->cdev));	if(!devno_result)            unregister_chrdev_region(tosmac_dev->devno, 1);	kfree(tosmac_dev);   }   printk(KERN_INFO "Unloading is done.\n");}static int __init tosmac_init(void){    int ret = 0;    int devno;    int devno_ret = -1;    int cdev_ret = -1;    TOSH_DATA_LENGTH = 28;    MSG_DATA_SIZE = 10 + TOSH_DATA_LENGTH + sizeof(uint16_t);    MSG_HEADER_DATA_SIZE = 10 + TOSH_DATA_LENGTH;    TOSMSG_SIZE = MSG_HEADER_DATA_SIZE + TOSMSG_FOOTER_SIZE;     printk(KERN_INFO "TOSMAC driver is loading...\n");       tosmac_dev = kmalloc(sizeof(struct tosmac_device), GFP_KERNEL);    if (!tosmac_dev) {	    printk(KERN_INFO "kmalloc error, failed to load driver\n");            ret = -ENOMEM;            goto fail;    }    memset(tosmac_dev, 0, sizeof(struct tosmac_device));    init_MUTEX(&tosmac_dev->sem);    devno = MKDEV(tosmac_major, tosmac_minor);    devno_result = register_chrdev_region(devno, 1, "tosmac");    if (devno_result < 0) {        printk(KERN_ERR "Failed to get driver major num:%d\n", tosmac_major);        goto fail;    }    tosmac_dev->devno = devno;    init_waitqueue_head(&(tosmac_dev->rq));    /* turn on radio */    if(CC2420_init(tosmac_dev) == FAIL)	goto fail;        cdev_init(&tosmac_dev->cdev, &tosmac_fops);    tosmac_dev->cdev.owner = THIS_MODULE;    tosmac_dev->cdev.ops = &tosmac_fops;    cdev_result = cdev_add(&tosmac_dev->cdev, devno, 1);    if(cdev_result) {        printk(KERN_ERR "Failed to register TOS-MAC driver\n");        goto fail;    }    else        printk(KERN_INFO "TOS-MAC driver installed\n");   return ret;   fail:        tosmac_exit();        return ret;}module_init(tosmac_init);module_exit(tosmac_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -