歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux驅動:信號量同步測試

Linux驅動:信號量同步測試

日期:2017/3/1 10:38:56   编辑:Linux編程

環境:

主機:Fedora12

目標板:MINI6410

目標板LINUX內核版本:2.6.38


信號量主要函數:

//定義信號量

struct semaphore sem;

//初始化信號量

void sema_init(struct semaphore *sem,int val);

//獲得信號量,會導致睡眠,不可在中斷中使用

void down(struct semaphore *sem);

//獲得信號量,能被信號打斷,返回0表示正常返回,返回-EINTR表示被信號打斷

int down_interruptible(struct semaphore *sem);

//嘗試獲得信號量sem,如果能夠立即獲得,返回0,否則返回非0值,它不會導致調用者睡眠,可以在中斷上下文使用

int down_trylock(struct semaphore *sem);

//釋放信號,喚醒等待者

void up(struct semaphore *sem);


測試代碼:

[cpp]
  1. #include <linux/miscdevice.h>
  2. #include <linux/delay.h>
  3. #include <asm/irq.h>
  4. //#include <mach/regs-gpio.h>
  5. #include <mach/hardware.h>
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/init.h>
  9. #include <linux/mm.h>
  10. #include <linux/fs.h>
  11. #include <linux/types.h>
  12. #include <linux/delay.h>
  13. #include <linux/moduleparam.h>
  14. #include <linux/slab.h>
  15. #include <linux/errno.h>
  16. #include <linux/ioctl.h>
  17. #include <linux/cdev.h>
  18. #include <linux/string.h>
  19. #include <linux/list.h>
  20. #include <linux/pci.h>
  21. #include <asm/uaccess.h>
  22. #include <asm/atomic.h>
  23. #include <asm/unistd.h>
  24. #include <linux/major.h>
  25. #include <mach/map.h>
  26. #include <mach/regs-clock.h>
  27. #include <mach/regs-gpio.h>
  28. #include <plat/gpio-cfg.h>
  29. #include <mach/gpio-bank-e.h>
  30. #include <mach/gpio-bank-k.h>
  31. #include <mach/gpio-bank-h.h>
  32. #include <mach/gpio-bank-n.h>
  33. #include <mach/gpio-bank-l.h>
  34. #include <mach/gpio-bank-p.h>
  35. #include <linux/device.h>
  36. #include <linux/jiffies.h>
  37. #define DEVICE_NAME "led_driver"
  38. #define T_MAJORS 700
  39. static struct cdev fun_cdev;
  40. static dev_t dev;
  41. static struct class *led_class;
  42. struct semaphore sem;
  43. //功能:初始化IO
  44. static void init_led(void)
  45. {
  46. unsigned temp;
  47. //GPK4-7設置為輸出
  48. temp = readl(S3C64XX_GPKCON);
  49. temp &= ~((0xf << 4) | (0xf << 5) | (0xf << 6) | (0xf<< 7));
  50. temp |= (1 << 16) | (1 << 20) | (1 << 24) | (1 << 28);
  51. writel(temp, S3C64XX_GPKCON);
  52. }
  53. //功能:ioctl操作函數
  54. //返回值:成功返回0
  55. static long led_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  56. {
  57. unsigned int temp = 0;
  58. //unsigned long t = 0;
  59. wait_queue_head_t wait;
  60. //獲取信號量
  61. if (down_interruptible(&sem))
  62. {
  63. return -1;
  64. }
  65. temp = readl(S3C64XX_GPKDAT);
  66. if (cmd == 0)
  67. {
  68. temp &= ~(1 << (arg + 3));
  69. }
  70. else
  71. {
  72. temp |= 1 << (arg + 3);
  73. }
  74. //等待2S
  75. //t = jiffies;
  76. //while (time_after(jiffies,t + 2 * HZ) != 1);
  77. init_waitqueue_head(&wait);
  78. sleep_on_timeout(&wait,2 * HZ);
  79. writel(temp,S3C64XX_GPKDAT);
  80. printk (DEVICE_NAME"\tjdh:led_driver cmd=%d arg=%d jiffies = %d\n",cmd,arg,jiffies);
  81. //釋放信號量
  82. up(&sem);
  83. return 0;
  84. }
  85. static struct file_operations io_dev_fops = {
  86. .owner = THIS_MODULE,
  87. .unlocked_ioctl = led_driver_ioctl,
  88. };
  89. static int __init dev_init(void)
  90. {
  91. int ret;
  92. unsigned temp;
  93. init_led();
  94. dev = MKDEV(T_MAJORS,0);
  95. cdev_init(&fun_cdev,&io_dev_fops);
  96. ret = register_chrdev_region(dev,1,DEVICE_NAME);
  97. if (ret < 0) return 0;
  98. ret = cdev_add(&fun_cdev,dev,1);
  99. if (ret < 0) return 0;
  100. printk (DEVICE_NAME"\tjdh:led_driver initialized!!\n");
  101. led_class = class_create(THIS_MODULE, "led_class1");
  102. if (IS_ERR(led_class))
  103. {
  104. printk(KERN_INFO "create class error\n");
  105. return -1;
  106. }
  107. device_create(led_class, NULL, dev, NULL, "led_driver");
  108. //初始化信號量
  109. sema_init(&sem,1);
  110. return ret;
  111. }
  112. static void __exit dev_exit(void)
  113. {
  114. unregister_chrdev_region(dev,1);
  115. device_destroy(led_class, dev);
  116. class_destroy(led_class);
  117. }
  118. module_init(dev_init);
  119. module_exit(dev_exit);
  120. MODULE_LICENSE("GPL");
  121. MODULE_AUTHOR("JDH");

測試

用http://www.linuxidc.com/Linux/2012-01/51818.htm中的測試程序進行測試:

開啟兩個程序,同時打開,雙進程同時操作LED

Copyright © Linux教程網 All Rights Reserved