adc驱动基于mini2440
2011-04-12 12:47
337 查看
在mini2440中只有一个ad转换器,为了和触摸屏共享资源,在adc驱动中声明了一个全局信号量
ADC_LOCK:DECLARE_MUTEX(ADC_LOCK)
在adc驱动中导出符号供触摸屏驱动使用:EXPORT_SYSBOL(ADC_LOCK);
这个信号量只是解决了不合触摸屏同时使用AD转换器,但是还需要一个变量来说明当前的驱动是否在使用这个资源:我们暂且用adc_own变量来表示。还定义了一个static volatile int ev_adc = 0; //用来标识adc事件是否发生
在init函数中首先应完成把虚拟地址映射到内存空间,这样直接写内存地址的时候就实现了对ad寄存器的操作。、
static void __iomem *base_addr;
base_addr=ioremap(S3C2410_PA_ADC,0x20);
通过clk_get(NULL,"adc")获取时钟,在s3c中设备的时钟在plat-s3c下有定义。具体位置可以使用soure-insight去定位
再 clk_enable();------>request_irq(IRQ_ADC, adcdone_int_handler, IRQF_SHARED, DEVICE_NAME, &adcdev);这里需要注意最后一个参数,由于该驱动要和触摸屏共享一个中断号IRQ_ADC,这里需要使用adcdev来加以区分
在adcdone_int_handler中断处理函数中,读取寄存器中转换后的数据,设adc时间标志为1,ev_adc = 1; 之后调用
wake_up_interruptible(&adcdev.wait); 唤醒wait等待队列上的进程
在s3c2410_adc_read函数中,通过wait_event_interruptible(adcdev.wait, ev_adc);函数等待ad转换的完成。下面看下该函数的
定义
这就解释了为什么开始初始化的时候设置ev_adc = 0,这个变量在adcdone_int_handler处理函数中ad转换完成就被设置成了1,这样就从wait_event_interruptible(adcdev.wait, ev_adc);函数中跳出了。。。。特别要注意condition的设置。
ADC_LOCK:DECLARE_MUTEX(ADC_LOCK)
在adc驱动中导出符号供触摸屏驱动使用:EXPORT_SYSBOL(ADC_LOCK);
这个信号量只是解决了不合触摸屏同时使用AD转换器,但是还需要一个变量来说明当前的驱动是否在使用这个资源:我们暂且用adc_own变量来表示。还定义了一个static volatile int ev_adc = 0; //用来标识adc事件是否发生
在init函数中首先应完成把虚拟地址映射到内存空间,这样直接写内存地址的时候就实现了对ad寄存器的操作。、
static void __iomem *base_addr;
base_addr=ioremap(S3C2410_PA_ADC,0x20);
通过clk_get(NULL,"adc")获取时钟,在s3c中设备的时钟在plat-s3c下有定义。具体位置可以使用soure-insight去定位
再 clk_enable();------>request_irq(IRQ_ADC, adcdone_int_handler, IRQF_SHARED, DEVICE_NAME, &adcdev);这里需要注意最后一个参数,由于该驱动要和触摸屏共享一个中断号IRQ_ADC,这里需要使用adcdev来加以区分
在adcdone_int_handler中断处理函数中,读取寄存器中转换后的数据,设adc时间标志为1,ev_adc = 1; 之后调用
wake_up_interruptible(&adcdev.wait); 唤醒wait等待队列上的进程
在s3c2410_adc_read函数中,通过wait_event_interruptible(adcdev.wait, ev_adc);函数等待ad转换的完成。下面看下该函数的
定义
#define __wait_event_interruptible(wq, condition, ret) do { DEFINE_WAIT(__wait); for (;;) { prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); if (condition) //只有当condition变为1了才会跳出! break; if (!signal_pending(current)) { schedule(); continue; } ret = -ERESTARTSYS; break; } finish_wait(&wq, &__wait); } while (0) #define wait_event_interruptible(wq, condition) ({ int __ret = 0; if (!(condition)) //只有当condition=0时才会进入等待! __wait_event_interruptible(wq, condition, __ret); __ret; }) 这样看,就是说必须确保condition在进入signal_pending之前都是0,之后变为1!
这就解释了为什么开始初始化的时候设置ev_adc = 0,这个变量在adcdone_int_handler处理函数中ad转换完成就被设置成了1,这样就从wait_event_interruptible(adcdev.wait, ev_adc);函数中跳出了。。。。特别要注意condition的设置。
相关文章推荐
- Linux-4.9.2内核在mini2440上的移植(十)——ADC驱动移植
- 基于mini2440触摸屏驱动
- 基于Linux-2.6.32.2在mini2440驱动分析一:串口驱动
- MINI2440Linux驱动01-mini2440_adc
- 基于 51单片机、74HC154/595的液晶显示、ADC驱动以及电压采集。
- linux sd卡驱动分析,基于mini2440,sdio mmc sd卡驱动编写
- 基于 mini2440 电阻式触摸屏(二):S3C2440 电阻式触摸屏接口、内部ADC结构
- 基于 mini2440 电阻式触摸屏(二):S3C2440 电阻式触摸屏接口、内部ADC结构
- 基于linux的mini2440触摸屏驱动分析(yz版)
- Linux-2.6.32.2内核在mini2440上的移植(七)---添加ADC驱动
- 基于linux的mini2440触摸屏驱动分析
- 基于linux的mini2440按键驱动及应用程序
- Mini2440的ADC linux驱动 之 定格式
- 基于 mini2440 电阻式触摸屏(四):mini2440触摸屏驱动分析
- 基于linux2.6.30.4的s3c2440的ADC驱动
- Linux设备驱动开发基础---字符设备驱动程序开发之mini2440_ADC驱动
- 基于mini2440的Linux音频驱动完全解读(二)——ASoc层的初始化(1)
- 简单、规范的Linux下的ds18b20驱动(基于mini2440开发板,2.6.29内核)
- 基于 mini2440 电阻式触摸屏(四):mini2440触摸屏驱动分析
- 基于linux的mini2440 led驱动及应用程序