Linux driver programming step-by-step (2)

Source: Internet
Author: User
Simple character Device Driver

1. Primary and secondary device numbers
The main device ID identifies the driver connected to the device. This device ID is used by the kernel and identifies the device under the corresponding driver.
In Linux, the slave number is a 32-bit dev_t type.

Typedef _ u32 _ kernel_dev_t;
Typedef _ kernel_dev_t dev_t; CrW ------- 1 Root 10, 1 Apr 11
2011 psaux
CrW ------- 1 Root 4, 1 Oct 2803: 04
Tty1
CrW-RW-1 root tty 4, 64 Apr 11
2011 ttys0
CrW-RW ---- 1 root uucp4, 65 Apr 11 2011
TTYs

Yes. In the/dev directory, use the $ LS-l command to display some results. We can see that the master device number of the tty driver is 4 (different system versions), and the secondary device number is different.

The first 12 digits identify the master device number Major (dev_t Dev) Obtain the master device number
The last 20 digits identify the device number Minor (dev_t Dev) Get this device number

The device number is generated by the Primary and Secondary device numbers.
Macro mkdev can be used.
Dev_t dev_num = mkdev (dev_t major, dev_t minor );

2. Allocate and release device numbers

In the character device of linux2.6 (as well as kernel3.0), the first thing to do is to apply for one or more device numbers.

  1. /* Statically allocate the device number
  2. * Parameter:
  3. * First: the first device number allocated.
  4. * Count: Number of allocated Devices
  5. * Name: Device Name
  6. * Return value:
  7. * 0: Success
  8. * Negative value: error, error code
  9. */
  10. Int register_chrdev_region (dev_t first, unsigned int count, char * Name );
  11. /* Dynamically allocate device numbers
  12. * Parameter:
  13. * Dev: used to store the assigned device number value.
  14. * Firstminor: Device number (usually 0)
     
  15. * Count: Number of allocated Devices
  16. * Name: Device Name
  17. * Return value:
  18. * 0: Success
  19. * Negative value: error, error code
  20. */
  21. Int alloc_chrdev_region (dev_t * Dev, unsigned int firstminor, unsigned int count, char * Name );
  22. /* Release the device number
  23. * Parameter:
  24. * First: Device number
  25. * Count: Number of allocated Devices
  26. */
  27. Void unregister_chrdev_region (dev_t first, unsigned int count );

Static allocation of device numbers is used when an available device number is known. Before programming, programmers mostly know whether the device number is available or not, it cannot be ensured that the device is still available during system upgrade.
Therefore, dynamic allocation is strongly recommended in the Linux community. It will find available device numbers without conflict. You must release the device number when detaching the device.

3. An ineffective character Device Driver

  1. # Include <Linux/init. h>
  2. # Include <Linux/module. h>
  3. # Include <Linux/types. h>
  4. # Include <Linux/fs. h>
  5. # Define simple_debug 1
  6. # Define dev_count 2
  7. # Define simple_name "simple_char"
  8. Static int simple_major= 108;
  9. Static int simple_minor = 0;
  10. Static _ init int simple_init (void)
  11. {
  12. Dev_t dev;
  13. Int err;
  14. # If simple_debug
  15. Printk (kern_info "in % s \ n", _ FUNC __);
  16. # Endif
  17. Dev = mkdev (simple_major, simple_minor); // obtain the device ID.
  18. If (Dev> 0) // The device number is valid.
  19. {
  20. # If simple_debug
  21. Printk (kern_info "try to register static char Dev % d \ n", Dev );
  22. # Endif
  23. Err = register_chrdev_region (Dev, dev_count, simple_name); // statically allocate the device number
  24. If (ERR <0) // static Allocation Error try to use Dynamic Allocation
  25. {
  26. Printk (kern_warning "register static char Dev error \ n ");
  27. Err = alloc_chrdev_region (& Dev, 0, dev_count, simple_name); // dynamically allocate device numbers
  28. If (ERR <0)
  29. {
  30. Printk (kern_err "register char Dev error in line % d \ n" ,__ line __);
  31. Goto error;
  32. }
  33. Else
  34. {
  35. Simple_major = major (Dev); // recalculate the master device number
  36. Simple_minor = minor (Dev); // recalculate the device number
  37. }
  38. }
  39. Else {
  40. }
  41. }
  42. Else // The device number cannot be dynamically allocated
  43. {
  44. # If simple_debug
  45. Printk (kern_info "try to register alloc char Dev \ n ");
  46. # Endif
  47. Err = alloc_chrdev_region (& Dev, 0, dev_count, simple_name );
  48. If (ERR <0)
  49. {
  50. Printk (kern_err "register char Dev error in line % d \ n" ,__ line __);
  51. Goto error;
  52. }
  53. Else
  54. {
  55. Simple_major = major (Dev );
  56. Simple_minor = minor (Dev );
  57. }
  58. }
  59. # If simple_debug
  60. Printk (kern_info "register char Dev success major = % d Minor = % d \ n", simple_major, simple_minor );
  61. # Endif
  62. Error:
  63. Return err;
  64. }
  65. Static _ exit void simple_exit (void)
  66. {
  67. Dev_t dev;
  68. # If simple_debug
  69. Printk (kern_info "in % s \ n", _ FUNC __);
  70. # Endif
  71. Dev = mkdev (simple_major, simple_minor );
  72. Unregister_chrdev_region (Dev, dev_count); // release the device number.
  73. }
  74. Module_init (simple_init );
  75. Module_exit (simple_exit );
  76. Module_license ("GPL ");
  77. Module_author ("kai_zhang (jsha.zk@163.com )");
  78. Module_description ("simple char driver! ");

In this example, only the device number is assigned during module initialization, and the device Number of the driver is released when the module is canceled.
In the function, we can see the notorious goto function in application programming. In Linux-driven programming, the Goto function makes our programming more organized, it can be processed more quickly when an error occurs.
If errors are handled by the caller of the Function check, the module functions are bloated and huge. Therefore, we recommend that you use the Goto function properly.
After the module is loaded
Run $ CAT/proc/devices to view the device and master device Number of simple_char.

Here we can see that the original primary device number is not available, so we use the Dynamic Allocation of the device number, so we apply to the primary device number 249, we can add our device above, the specific operation will be discussed in the next section. Leave some suspense first.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.