历史上的今天
返回首页

历史上的今天

今天是:2025年03月23日(星期日)

正在发生

2021年03月23日 | S3C6410开发板adc驱动代码分析及测试代码分析

2021-03-23 来源:eefocus

在本文中,我们对S3C6410开发板adc驱动代码的实现过程进行分析,然后通过一个实例对adc功能进行测试。在本文的资源中包含了设备驱动的源码和测试的源码。


一、设备驱动源码分析

adc的设备驱动主要实现了模块的初始化、模块的卸载、设备打开、设备关闭、设备读取的功能。


1、模块初始化

模块的初始化的源码如下所示。


static int __init dev_init(void)

{

int ret;

 

base_addr = ioremap(SAMSUNG_PA_ADC, 0x20);

if (base_addr == NULL) {

printk(KERN_ERR "Failed to remap register blockn");

return -ENOMEM;

}

 

adc_clock = clk_get(NULL, "adc");

if (!adc_clock) {

printk(KERN_ERR "failed to get adc clock sourcen");

return -ENOENT;

}

clk_enable(adc_clock);

/* normal ADC */

ADCTSC = 0;

 

ret = request_irq(IRQ_ADC, adcdone_int_handler, IRQF_SHARED, DEVICE_NAME, &adcdev);

if (ret) {

iounmap(base_addr);

return ret;

}

 

ret = misc_register(&misc);

 

printk (DEVICE_NAME"tinitializedn");

return ret;

}


这段代码主要实现的功能是是能adc的始终,并且开启了adc的中断功能,最后使用misc_register()函数向内核注册adc的混杂设备。adc的中断初始化过程将adc的中断号与中断处理函数、中断描述结构体绑定在一起。其中,IRQ_ADC是中断号,adcdone_int_handler是中断处理函数,adcdev是指向中断描述结构体的指针,当启用了adc转换后并转换完成后,中断会把相应的中断描述结构体保持下来,并转到adcdone_int_handler函数去处理中断。


adcdone_int_handler()函数的源码如下所示。


static irqreturn_t adcdone_int_handler(int irq, void *dev_id)

{

if (__ADC_locked) {

adc_data = ADCDAT0 & 0x3ff;

 

ev_adc = 1;

wake_up_interruptible(&adcdev.wait);

 

/* clear interrupt */

__raw_writel(0x0, base_addr + S3C_ADCCLRINT);

}

 

return IRQ_HANDLED;

}


这段代码的功能是将adc的转换结果保存到adc_data变量中,并将阻塞的等待队里唤醒。


2、模块卸载

模块的卸载代码如下所示


static void __exit dev_exit(void)

{

free_irq(IRQ_ADC, &adcdev);

iounmap(base_addr);

 

if (adc_clock) {

clk_disable(adc_clock);

clk_put(adc_clock);

adc_clock = NULL;

}

 

misc_deregister(&misc);

}


代码实现的功能是关闭adc的中断功能,禁能adc的始终,并且将adc的混杂设备从内核中取消注册。


3、设备打开

adc的设备打开代码如下所示。


static int s3c2410_adc_open(struct inode *inode, struct file *filp)

{

init_waitqueue_head(&(adcdev.wait));

 

adcdev.channel=0;

adcdev.prescale=0xff;

 

DPRINTK("adc openedn");

return 0;

}


设备打开代码实现了内核阻塞等待队列的初始化,还有adc通道号的初始化。


4、设备关闭

设备关闭代码比较简单,如下所示。


static int s3c2410_adc_release(struct inode *inode, struct file *filp)

{

DPRINTK("adc closedn");

return 0;

}


代码没有做任何操作,只是打印了一串字符串。


5、设备读取

设备读取的代码如下所示。


static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)

{

char str[20];

int value;

size_t len;

 

if (mini6410_adc_acquire_io() == 0) {

__ADC_locked = 1;

 

START_ADC_AIN(adcdev.channel, adcdev.prescale);

 

wait_event_interruptible(adcdev.wait, ev_adc);

ev_adc = 0;

 

DPRINTK("AIN[%d] = 0x%04x, %dn", adcdev.channel, adc_data, ADCCON & 0x80 ? 1:0);

 

value = adc_data;

 

__ADC_locked = 0;

mini6410_adc_release_io();

} else {

value = -1;

}

 

len = sprintf(str, "%dn", value);

if (count >= len) {

int r = copy_to_user(buffer, str, len);

return r ? r : len;

} else {

return -EINVAL;

}

}


读取代码首先使能了adc转换功能,然后阻塞等待转换完成,转换完成后会进入中断进行数据读取,在中断中会将读取函数中的阻塞唤醒。唤醒后读取函数读取adc返回的数据,并将ad值转换成字符串str,最后将str复制给用户程序中的buf。


二、测试代码分析

编写了一个简单的测试代码对adc的驱动进行测试,代码如下。


int main()

{

int fd;

char buf[10];

fd = open("/dev/adc",O_RDONLY);

 

while(1)

{

read(fd,buf,10);

printf("%sn",buf);

sleep(1);

}

 

close(fd);

return 0;

}


代码中,首先打开adc端口,然后进入while(1)循环,在循环中,每隔1秒读取一次ad值,并将ad值打印到终端中。

推荐阅读

史海拾趣

DURAKOOL公司的发展小趣事

面对日益激烈的市场竞争和不断变化的客户需求,DURAKOOL公司始终保持着对创新的追求。公司不断投入研发资源,推动产品升级和技术进步。同时,公司也关注行业趋势和未来发展,积极探索新的业务领域和市场机会。展望未来,DURAKOOL将继续致力于成为全球电子行业的领先者。

请注意,以上故事均为虚构,旨在提供与DURAKOOL公司发展相关的故事概要。如需了解更多关于DURAKOOL公司的详细信息,建议查阅相关报道或公司官方资料。

光磊(GL)公司的发展小趣事

随着技术的不断进步,DURAKOOL公司不断投入研发,推出了一系列创新产品,如Durakool接触器和电流互感器。这些产品凭借其高可靠性和稳定性,在电力监控和智能计量等领域得到了广泛应用。公司也逐渐扩大了市场覆盖范围,不仅在美国本土取得了成功,还逐步进入国际市场。

E-Z-HOOK公司的发展小趣事

E-Z-HOOK公司非常重视与客户的关系建立与维护。他们始终坚持以客户为中心的经营理念,努力为客户提供高质量的产品和优质的服务。为了更好地了解客户需求和反馈,公司建立了完善的客户服务体系,包括售前咨询、售后服务和技术支持等。此外,公司还定期组织客户交流会和技术研讨会等活动,加强与客户的沟通与互动。这些努力使得E-Z-HOOK公司赢得了广大客户的信任和支持。

Habia Cable公司的发展小趣事

在1956年的一个晴朗午后,E-Z-HOOK的创始人阿尔伯特·史密斯(化名)在实验室里遇到了一个棘手的问题。他正在测试一个复杂的电子系统,但发现现有的测试工具无法满足他的需求。于是,他动手设计并制造出了第一个E-Z-HOOK测试钩,这个简单但实用的工具极大地方便了他的工作。史密斯看到了这个产品的巨大潜力,于是决定成立一家公司来专门生产这种测试钩。这就是E-Z-HOOK公司的起源。

GTE Microcircuits公司的发展小趣事
复合放大器因其高性能特点,在通信、音频、医疗、测试测量等多个领域有广泛应用。例如,在通信系统中用于信号放大和处理;在音频设备中用于提高音质和音量;在医疗设备中用于生物电信号的放大等。
常州星海电子(Starsea)公司的发展小趣事

随着市场需求的不断变化和消费者需求的多样化,常州星海电子不断调整和优化产品结构。公司现已形成了包括普通整流、开关、快速恢复、高效率、超快速、肖特基、双向触发管、整流桥、高反压以及瞬间突波电压吸收、稳压等多种系列、多种封装形式的二极管产品。这些产品广泛应用于电脑、家电、邮电通讯等行业,为公司赢得了广阔的市场空间。

问答坊 | AI 解惑

求助

现急需一张电路图.要求用AT89C52控制,有2个1M的闪存,一个EEPROM,4*4键盘,8个LED数码显示,一个RS232接口,需要用IIC 控制.请哪位好心的大虾帮帮忙.小弟在这里先谢过了.…

查看全部问答>

同济大学软件学院院长谈择业—关于嵌入式方向

二、关于嵌入式系统方向   嵌入式系统无疑是当前最热门最有发展前途的IT应用领域之一。嵌入式系统用在一些特定专用设备上,通常这些设备的硬件资源(如处理器、存储器等)非常有限,并且对成本很敏感,有时对实时响应要求很高等。特别是随着消费家 ...…

查看全部问答>

在蓝牙协议中,主从设备间只支持一条ACL链路和三条SCO链路,是不是就是说在某一时刻,主从服务间只有一个服务使用这个ACL链路???

如题,现在很急的一个问题, 想请教高手,     蓝牙协议中的主从设备间只支持一条ACL链路和三条SCO链路,是不是就是等价于说在某一时刻,主从服务间只有一个服务使用这个ACL链路???    举个例子就是,某一时刻文件传输服务和蓝 ...…

查看全部问答>

S3C2440 SPI接收问题请教?

S3C2440 SPI接收问题请教, 程序代码如下所示. 我通过示波器能够抓到MISO,MOSI的正确波形,说明数据发送和接收都是正确的,可就是2440寄存器SPRDAT0没有数值,始终是0. 各位大侠估计什么原因?ARM MISO管脚显示信号都是正确的,相应接收寄存器却 ...…

查看全部问答>

有没有人使用过Windows下的RTX实时扩展?

最近做仿真软件开发,要求实时性很强,为了方便开发和用户使用,就不想换操作系统,看到可以在Windows下使用RTX来实现,只是我同用过,哪位大侠用过,说下~~ …

查看全部问答>

根据读txt文件自动配置控件的类型,可以实现吗?

根据读txt文件自动配置控件的类型,可以实现吗? 要是可以,怎么实现? 谢谢各位路过的大侠了,希望给我指点一二! 谢谢!!!!…

查看全部问答>

关于51定时器的小问题求教

题目是:同时用两个定时器控制蜂鸣器发声,定时器0控制频率,定时器1控制同个频率持续的时间,间隔300ms输出1k(hz)的方波。 我的代码是:#include #include #define uint unsigned int #define uchar unsigned char uint t1=0,t2=0; sbit b ...…

查看全部问答>

奇怪!下面函数通不过?

 奇怪!下面函数通不过?     {   uchar  a;    a=1;      if( a!=1 )  break;       } 错误提示:COMJM.C(64): error C171: \'break\': ...…

查看全部问答>

招聘兼/全职

1.负责32位MCU/ARM开发,硬件模块驱动设计和开发,上层应用程序编写和维护等工作。 2.熟悉ARM体系架构,嵌入式操作系统开发环境及流程 3.具备扎实的计算机软件基础,精通C程序设计、扎实的数/模电路知识。 4.熟练操作DXP/99se等工具。5、熟悉FPGA内 ...…

查看全部问答>

C2000学习进度没有截图完!希望还有机会

这几天拼命在学这个了! 学了几遍,因为学完的比较早,做题过的也比较早,后来就只看资料了,没有想到当时忘记把图截完了! 当时以后系统可以在后台统计! 麻烦管理员朋友帮忙查看一下!辛苦了!!…

查看全部问答>