当前位置: 首页 > ds >正文

ADC platfrom day65

5. ADC

5.1 代码
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio.h>
#include <linux/miscdevice.h>
#include <asm/ioctl.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/workqueue.h>#define DEV_NAME "adc"
static wait_queue_head_t wq;
static int condition = 0;
static struct work_struct work;
#define ADCCON 0x58000000
#define ADCDAT0 0x5800000C
#define CLKCON 0x4C00000C
static volatile unsigned long * adccon;
static volatile unsigned long * adcdat0;
static volatile unsigned long * clkcon;#define MAGIC_NUM 'x'
#define SET_CHANNEL 0x20
#define CMD_SET_CHANNEL   _IO(MAGIC_NUM, SET_CHANNEL)static inline void init_adc(void)
{*adccon = (1 << 14) | (49 << 6);
}static inline int adc_set_channel(unsigned char channel)
{if(channel > 7)return -EINVAL;*adccon &= ~(0x7 << 3);*adccon |= ((channel & 0x7) << 3);	return 0;
}static inline void adc_start(void)
{*adccon |= (1 << 0);
}static inline unsigned short adc_read(void)
{unsigned short data = *adcdat0 & 0x3ff;return data;
}static void work_func(struct work_struct *work)
{condition = 1;wake_up_interruptible(&wq);printk("task_func ....\n");
}static irqreturn_t adc_handler(int irq_num, void * dev)
{schedule_work(&work);return IRQ_HANDLED;
}static int open(struct inode * node, struct file * file)
{init_adc();printk("adc  open ...\n");return 0;
}static ssize_t read(struct file * file, char __user * buf, size_t len, loff_t * offset)
{unsigned short data = 0;printk("adc read start...\n");condition = 0;adc_start();wait_event_interruptible(wq, condition);data = adc_read();copy_to_user(buf, &data, sizeof(data));printk("adc read end...\n");return sizeof(data);
}static ssize_t write(struct file * file, const char __user * buf, size_t len, loff_t * offset)
{printk("adc write ...\n");return 0;
}static long ioctl(struct file * file, unsigned int cmd, unsigned long arg)
{int ret = 0;switch(cmd){case CMD_SET_CHANNEL :ret = adc_set_channel((unsigned char)arg);break;default:ret = -EINVAL;break;}return ret;
}static int close(struct inode * node, struct file * file)
{printk("adc close ...\n");return 0;
}static struct file_operations fops = 
{.owner = THIS_MODULE,.open = open,.read = read,.write = write,.unlocked_ioctl = ioctl,.release = close
};static struct miscdevice misc = 
{.minor = MISC_DYNAMIC_MINOR,.name = DEV_NAME,.fops = &fops
};static int __init adc_init(void)
{int ret = misc_register(&misc);if(ret < 0)goto err_misc_register;ret = request_irq(IRQ_ADC, adc_handler, IRQF_DISABLED, "irq_adc", NULL);if(ret < 0)goto err_request_irq;init_waitqueue_head(&wq);INIT_WORK(&work, work_func);adccon = ioremap(ADCCON, 4);adcdat0 = ioremap(ADCDAT0, 4);clkcon = ioremap(CLKCON, 4);*clkcon |= (1 << 15);printk("adc_init   ....\n");return ret;
err_request_irq:disable_irq(IRQ_ADC);free_irq(IRQ_ADC, NULL);printk("request_irq failed\n");return ret;err_misc_register:misc_deregister(&misc);printk("misc_register  faikey\n");return ret;	
}static void __exit key_exit(void)
{iounmap(adcdat0);iounmap(adccon);disable_irq(IRQ_ADC);free_irq(IRQ_ADC, NULL);misc_deregister(&misc);printk("adc_exit   ....\n");
}module_init(adc_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");
5.2用户空间和内核空间的配对
//内核空间
#define MAGIC_NUM 'x'
#define SET_CHANNEL 0x20
#define CMD_SET_CHANNEL   _IO(MAGIC_NUM, SET_CHANNEL)static long ioctl(struct file * file, unsigned int cmd, unsigned long arg)
{int ret = 0;switch(cmd){case CMD_SET_CHANNEL :ret = adc_set_channel((unsigned char)arg);break;default:ret = -EINVAL;break;}return ret;
}//用户空间unsigned short data;while(1){ioctl(fd,CMD_SET_CHANNEL,0);read(fd,&data,sizeof data);float v = data *3.3 / 1024;printf("0---------data = %d v = %3.2f \n",data,v);sleep(1);ioctl(fd,CMD_SET_CHANNEL,1);read(fd,&data,sizeof data);v = data *3.3 / 1024;printf("1----------data = %d v = %3.2f \n",data,v);sleep(1);ioctl(fd,CMD_SET_CHANNEL,100);read(fd,&data,sizeof data);v = data *3.3 / 1024;printf("err--------data = %d v = %3.2f \n",data,v);sleep(1);}

十:platform

1. bus_type

struct bus_type {const char		*name;struct bus_attribute	*bus_attrs;struct device_attribute	*dev_attrs;struct driver_attribute	*drv_attrs;int (*match)(struct device *dev, struct device_driver *drv);int (*uevent)(struct device *dev, struct kobj_uevent_env *env);int (*probe)(struct device *dev);int (*remove)(struct device *dev);void (*shutdown)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;struct bus_type_private *p;
};

2. platform 总线

匹配先看匹配表,因为这个是独一无二的,名字可能会重名 extern struct bus_type platform_bus_type;
extern struct device platform_bus;struct platform_device {const char	* name;		//匹配的名字int		id;struct device	dev;u32		num_resources;	//设备资源数量struct resource	* resource;	//设备资源struct platform_device_id	*id_entry;	//匹配表/* arch specific additions */struct pdev_archdata	archdata;
};//resource
struct resource {resource_size_t start;		//起始位置resource_size_t end;		//终点位置const char *name;			//eg:gpbunsigned long flags;		//对应的类型 struct resource *parent, *sibling, *child;
};
extern int platform_driver_register(struct platform_driver *);
extern void platform_driver_unregister(struct platform_driver *);struct platform_driver {int (*probe)(struct platform_device *);		//注册	device和driver都要加载完成后执行int (*remove)(struct platform_device *);	//销毁	device和driver,任意一个要卸载后执行void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;struct platform_device_id *id_table;	//匹配表
};-------
//driver
struct device_driver {const char		*name;	//根据名字匹配struct bus_type		*bus;struct module		*owner;const char		*mod_name;	/* used for built-in modules */bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */int (*probe) (struct device *dev);int (*remove) (struct device *dev);void (*shutdown) (struct device *dev);int (*suspend) (struct device *dev, pm_message_t state);int (*resume) (struct device *dev);const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p;
};

3.代码

先加载device,再加载driver //如果不用release的话

//driver
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio.h>
#include <linux/miscdevice.h>
#include <asm/ioctl.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>#define DEV_NAME "adc"
static wait_queue_head_t wq;
static int condition = 0;
static struct work_struct work;
static volatile unsigned long * adccon;
static volatile unsigned long * adcdat0;
static volatile unsigned long * clkcon;#define MAGIC_NUM 'x'
#define SET_CHANNEL 0x20
#define CMD_SET_CHANNEL   _IO(MAGIC_NUM, SET_CHANNEL)static inline void init_adc(void)
{*adccon = (1 << 14) | (49 << 6);
}static inline int adc_set_channel(unsigned char channel)
{if(channel > 7)return -EINVAL;*adccon &= ~(0x7 << 3);*adccon |= ((channel & 0x7) << 3);	return 0;
}static inline void adc_start(void)
{*adccon |= (1 << 0);
}static inline unsigned short adc_read(void)
{unsigned short data = *adcdat0 & 0x3ff;return data;
}static void work_func(struct work_struct *work)
{condition = 1;wake_up_interruptible(&wq);printk("task_func ....\n");
}static irqreturn_t adc_handler(int irq_num, void * dev)
{schedule_work(&work);return IRQ_HANDLED;
}static int open(struct inode * node, struct file * file)
{init_adc();printk("adc  open ...\n");return 0;
}static ssize_t read(struct file * file, char __user * buf, size_t len, loff_t * offset)
{unsigned short data = 0;printk("adc read start...\n");condition = 0;adc_start();wait_event_interruptible(wq, condition);data = adc_read();copy_to_user(buf, &data, sizeof(data));printk("adc read end...\n");return sizeof(data);
}static ssize_t write(struct file * file, const char __user * buf, size_t len, loff_t * offset)
{printk("adc write ...\n");return 0;
}static long ioctl(struct file * file, unsigned int cmd, unsigned long arg)
{int ret = 0;switch(cmd){case CMD_SET_CHANNEL :ret = adc_set_channel((unsigned char)arg);break;default:ret = -EINVAL;break;}return ret;
}static int close(struct inode * node, struct file * file)
{printk("adc close ...\n");return 0;
}static struct file_operations fops = 
{.owner = THIS_MODULE,.open = open,.read = read,.write = write,.unlocked_ioctl = ioctl,.release = close
};static struct miscdevice misc = 
{.minor = MISC_DYNAMIC_MINOR,.name = DEV_NAME,.fops = &fops
};static int probe(struct platform_device * pdev)
{int ret = misc_register(&misc);if(ret < 0)goto err_misc_register;ret = request_irq(pdev->resource[3].start, adc_handler, IRQF_DISABLED, "irq_adc", NULL);if(ret < 0)goto err_request_irq;init_waitqueue_head(&wq);INIT_WORK(&work, work_func);adccon = ioremap(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1);adcdat0 = ioremap(pdev->resource[1].start, pdev->resource[1].end - pdev->resource[1].start + 1);clkcon = ioremap(pdev->resource[2].start, pdev->resource[2].end - pdev->resource[2].start + 1);*clkcon |= (1 << 15);printk("adc probe    ....\n");return ret;
err_request_irq:disable_irq(pdev->resource[3].start);free_irq(pdev->resource[3].start, NULL);printk("request_irq failed\n");return ret;err_misc_register:misc_deregister(&misc);printk("misc_register  failed\n");return ret;	return 0;
}static int remove(struct platform_device * pdev)
{iounmap(clkcon);iounmap(adcdat0);iounmap(adccon);disable_irq(pdev->resource[3].start);free_irq(pdev->resource[3].start, NULL);misc_deregister(&misc);printk("adc remove   ....\n");return 0;
}static struct platform_driver drv = 
{.probe = probe,.remove = remove,.driver = {.name = DEV_NAME}
};static int __init adc_driver_init(void)
{int ret = platform_driver_register(&drv);if(ret < 0){platform_driver_unregister(&drv);	return ret;}printk("adc_driver_init  ...\n");return 0;
}static void __exit adc_driver_exit(void)
{platform_driver_unregister(&drv);	printk("adc_driver_exit  ...\n");
}module_init(adc_driver_init);
module_exit(adc_driver_exit);
MODULE_LICENSE("GPL");
//device
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>#define DEV_NAME "adc"
#define ADCCON 0x58000000
#define ADCDAT0 0x5800000C
#define CLKCON 0x4C00000C
#define ADC_IRQ_NUM IRQ_ADCstatic struct resource res[4] = 
{[0] = {.start = ADCCON,.end = ADCCON + 4 - 1,.name = "adccon",.flags = IORESOURCE_IO },[1] = {.start = ADCDAT0,.end = ADCDAT0 + 4 - 1,.name = "adcdat0",.flags = IORESOURCE_IO},[2] = {.start = CLKCON,.end = CLKCON + 4 - 1,.name = "clkcon",.flags = IORESOURCE_IO },[3] = {.start = ADC_IRQ_NUM,.end = ADC_IRQ_NUM,.name = "irq_adc",.flags = IORESOURCE_IRQ}
};static void release(struct device *dev){}static struct platform_device pdev = 
{.name = DEV_NAME,.id = -1,.dev = {.release = release	},.num_resources = sizeof(res) / sizeof(res[0]),.resource = res,
};static int __init adc_device_init(void)
{int ret = platform_device_register(&pdev);if(ret < 0){platform_device_unregister(&pdev);	return ret;}printk("adc_device_init  ...\n");return 0;
}static void __exit adc_device_exit(void)
{platform_device_unregister(&pdev);	printk("adc_device_exit  ...\n");
}module_init(adc_device_init);
module_exit(adc_device_exit);
MODULE_LICENSE("GPL");
http://www.xdnf.cn/news/19502.html

相关文章:

  • MVC架构模式
  • Blender建模:对于模型布线的一些思考
  • 介绍GSPO:一种革命性的语言模型强化学习算法
  • 现代C++性能陷阱:std::function的成本、异常处理的真实开销
  • Luma 视频生成 API 对接说明
  • AI 智能体汇总,自动执行任务的“真 Agent”
  • 查看所有装在c盘软件的方法
  • Trae接入自有Deepseek模型,不再排队等待
  • OpenStack 03:创建实例
  • 并发编程——11 并发容器(Map、List、Set)实战及其原理分析
  • Opencv的数据结构
  • wifi控制舵机
  • AI热点周报(8.24~8.30):Grok 2.5开源,OpenAI Realtime正式商用,Meta或与OpenAI或Google合作?
  • 从零开始的python学习——语句
  • python pyqt5开发DoIP上位机【自动化测试的逻辑是怎么实现的?】
  • lumerical_FDTD_光源_TFSF
  • 《中国棒垒球》垒球世界纪录多少米·垒球8号位
  • 第2.3节:AI大模型之Claude系列(Anthropic)
  • [特殊字符]️ STL 容器快速参考手册
  • LangChain实战(五):Document Loaders - 从多源加载数据
  • Python库2——Matplotlib2
  • JAVA EE初阶 4:文件操作和IO
  • PCIe 6.0 vs 5.0:带宽翻倍背后的技术革新与应用前景
  • 防护墙技术(一):NAT
  • 粒子群优化算法(PSO)
  • 从分子工具到技术革新:链霉亲和素 - 生物素系统与 M13 噬菌体展示的交叉应用解析
  • 项目管理方法适用场景对比
  • 每k个节点一组反转链表
  • 11 C 语言 sizeof 与指针实战指南:一维 / 二维数组计算注意事项 + 笔试真题解析 + sizeof strlen 对比
  • Python数据处理