微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440驱动简析——串口驱动

S3C2440驱动简析——串口驱动

时间:11-21 来源:互联网 点击:

  1. };
  2. //devicemanagement//
  3. staticints3c2440_serial_probe(structplatform_device*dev)
  4. {//完成串口的添加
  5. dbg("s3c2440_serial_probe:dev=%p/n",dev);
  6. returns3c24xx_serial_probe(dev,&s3c2440_uart_inf);
  7. }
  8. staticstructplatform_drivers3c2440_serial_driver={//注册串口设备
  9. .probe=s3c2440_serial_probe,
  10. .remove=__devexit_p(s3c24xx_serial_remove),
  11. .driver={
  12. .name="s3c2440-uart",
  13. .owner=THIS_MODULE,
  14. },
  15. };
  16. s3c24xx_console_init(&s3c2440_serial_driver,&s3c2440_uart_inf);
  17. staticint__inits3c2440_serial_init(void)
  18. {//初始化模块
  19. returns3c24xx_serial_init(&s3c2440_serial_driver,&s3c2440_uart_inf);
  20. }
  21. staticvoid__exits3c2440_serial_exit(void)
  22. {//退出模块
  23. platform_driver_unregister(&s3c2440_serial_driver);//注销串口设备
  24. }
  25. module_init(s3c2440_serial_init);
  26. module_exit(s3c2440_serial_exit);
  27. MODULE_DESCRIPTION("SamsungS3C2440,S3C2442SoCSerialportdriver");
  28. MODULE_AUTHOR("BenDooks");
  29. MODULE_LICENSE("GPLv2");
  30. MODULE_ALIAS("platform:s3c2440-uart");

几个问题需要我们注意:

1.设备如何注册、注销

串口驱动被作为一个单独的模块被加载进内核,在模块的加载和卸载函数中,只需注册和注销一个platform_driver结构体。

注册:

[c-sharp]view plaincopy

  1. staticstructplatform_drivers3c2440_serial_driver={
  2. .probe=s3c2440_serial_probe,
  3. .remove=__devexit_p(s3c24xx_serial_remove),
  4. .driver={
  5. .name="s3c2440-uart",
  6. .owner=THIS_MODULE,
  7. },
  8. };

注销:

[c-sharp]view plaincopy

  1. platform_driver_unregister(&s3c2440_serial_driver);

2.几个非常重要的结构体

s3c2410_uartcfg :保存ucon ulcon ufcon三个串口寄存器的值

[c-sharp]view plaincopy

  1. structs3c2410_uartcfg{
  2. unsignedcharhwport;//hardwareportnumber//
  3. unsignedcharunused;
  4. unsignedshortflags;
  5. upf_tuart_flags; //defaultuartflags //
  6. unsignedinthas_fracval;
  7. unsignedlongucon;//valueofuconforport//
  8. unsignedlongulcon;//valueofulconforport//
  9. unsignedlongufcon;//valueofufconforport//
  10. structs3c24xx_uart_clksrc*clocks;
  11. unsignedintclocks_size;
  12. };

s3c24xx_uart_info :提供串口设备环境信息,并提供三个函数的接口

[c-sharp]view plaincopy

  1. structs3c24xx_uart_info{
  2. char*name;
  3. unsignedinttype;
  4. unsignedintfifosize;
  5. unsignedlongrx_fifomask;
  6. unsignedlongrx_fifoshift;
  7. unsignedlongrx_fifofull;
  8. unsignedlongtx_fifomask;
  9. unsignedlongtx_fifoshift;
  10. unsignedlongtx_fifofull;
  11. //uartportfeatures//
  12. unsignedinthas_divslot:1;
  13. //clocksourcecontrol//
  14. int(*get_clksrc)(structuart_port*,structs3c24xx_uart_clksrc*clk);
  15. int(*set_clksrc)(structuart_port*,structs3c24xx_uart_clksrc*clk);
  16. //uartcontrols//
  17. int(*reset_port)(structuart_port*,structs3c2410_uartcfg*);
  18. };

platform_device :设备的信息

[c-sharp]view plaincopy

  1. structplatform_device{
  2. constchar*name;
  3. intid;
  4. structdevicedev;
  5. u32num_resources;
  6. structresource*resource;
  7. conststructplatform_device_id*id_entry;
  8. //archspecificadditions//
  9. structpdev_archdataarchdata;
  10. };

platform_driver :设备注册用

[c-sharp]view plaincopy

  1. structplatform_driver{
  2. int(*probe)(structplatform_device*);
  3. int(*remove)(structplatform_device*);
  4. void(*shutdown)(structplatform_device*);
  5. int(*suspend)(structplatform_device*,pm_message_tstate);
  6. int(*resume)(structplatform_device*);
  7. structdevice_driverdriver;
  8. conststructplatform_device_id*id_table;
  9. };

3.读写寄存器的宏定义

(1)读寄存器

unsigned long ucon = rd_regl(port, S3C2410_UCON);

#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))

static unsigned char __raw_readb(unsigned int ptr)

{

return *((volatile unsigned char *)ptr);

}

#define portaddr(port, reg) ((port)->membase + (reg))

(2)写寄存器

wr_regl(port, S3C2410_UCON, ucon);

#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))

#define portaddr(port, reg) ((port)->membase + (reg))

#define __raw_writel(v,p)(*(unsigned long *)(p) = (v))

4.函数的注册方式

细心的朋友可能会发现,我们之前一直使用的是传统的 device driver 机制(通过 driver_register 函数进行注册)本串口所使用的是一个设备用 Platform_device 表示,驱动用 Platform_driver 进行注册的机制。而后者是在内核2.6版本所提出来的新事物,其优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过 platform device 提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性(这些标准接口是安全的)。关于这两种机制更深入的分析,请看以下链接:http://blog.csdn.net/jarvis_xian/archive/2011/05/23/6440649.aspx

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top