serial.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. ******************************************************************************
  3. * By : parai
  4. * email:parai@foxmail.com
  5. * 这并不是一个真的串口设备,只是为了能够让内核打印信息而创建
  6. ******************************************************************************
  7. */
  8. #include "rtthread.h"
  9. #define _DEBUG_SERIAL 0
  10. #include "serial.h"
  11. #include <stdio.h>
  12. struct rt_device serial_device;
  13. extern struct serial_int_rx serial_rx;
  14. /*@{*/
  15. /* RT-Thread Device Interface */
  16. /**
  17. * This function initializes serial
  18. */
  19. static rt_err_t rt_serial_init(rt_device_t dev)
  20. {
  21. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  22. {
  23. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  24. {
  25. rt_memset(serial_rx.rx_buffer, 0,
  26. sizeof(serial_rx.rx_buffer));
  27. serial_rx.read_index = 0;
  28. serial_rx.save_index = 0;
  29. }
  30. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  31. }
  32. return RT_EOK;
  33. }
  34. static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
  35. {
  36. #if _DEBUG_SERIAL==1
  37. printf("in rt_serial_open()\n");
  38. #endif
  39. return RT_EOK;
  40. }
  41. static rt_err_t rt_serial_close(rt_device_t dev)
  42. {
  43. #if _DEBUG_SERIAL==1
  44. printf("in rt_serial_close()\n");
  45. #endif
  46. return RT_EOK;
  47. }
  48. static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  49. {
  50. rt_uint8_t *ptr;
  51. rt_err_t err_code;
  52. ptr = buffer;
  53. err_code = RT_EOK;
  54. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  55. {
  56. /* interrupt mode Rx */
  57. while (size)
  58. {
  59. rt_base_t level;
  60. /* disable interrupt */
  61. level = rt_hw_interrupt_disable();
  62. if (serial_rx.read_index != serial_rx.save_index)
  63. {
  64. /* read a character */
  65. *ptr++ = serial_rx.rx_buffer[serial_rx.read_index];
  66. size--;
  67. /* move to next position */
  68. serial_rx.read_index ++;
  69. if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
  70. serial_rx.read_index = 0;
  71. }
  72. else
  73. {
  74. /* set error code */
  75. err_code = -RT_EEMPTY;
  76. /* enable interrupt */
  77. rt_hw_interrupt_enable(level);
  78. break;
  79. }
  80. /* enable interrupt */
  81. rt_hw_interrupt_enable(level);
  82. }
  83. }
  84. /* set error code */
  85. rt_set_errno(err_code);
  86. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  87. }
  88. static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  89. {
  90. #if _DEBUG_SERIAL==1
  91. printf("in rt_serial_write()\n");
  92. #endif
  93. printf("%s", (char *)buffer);
  94. return size;
  95. }
  96. static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  97. {
  98. RT_ASSERT(dev != RT_NULL);
  99. switch (cmd)
  100. {
  101. case RT_DEVICE_CTRL_SUSPEND:
  102. /* suspend device */
  103. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  104. break;
  105. case RT_DEVICE_CTRL_RESUME:
  106. /* resume device */
  107. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  108. break;
  109. }
  110. return RT_EOK;
  111. }
  112. /*
  113. * serial register
  114. */
  115. static rt_err_t rt_hw_serial_register(rt_device_t device, const char *name, rt_uint32_t flag)
  116. {
  117. RT_ASSERT(device != RT_NULL);
  118. #if _DEBUG_SERIAL==1
  119. printf("in rt_serial_register()\n");
  120. #endif
  121. device->type = RT_Device_Class_Char;
  122. device->rx_indicate = RT_NULL;
  123. device->tx_complete = RT_NULL;
  124. device->init = rt_serial_init;
  125. device->open = rt_serial_open;
  126. device->close = rt_serial_close;
  127. device->read = rt_serial_read;
  128. device->write = rt_serial_write;
  129. device->control = rt_serial_control;
  130. device->user_data = RT_NULL;
  131. /* register a character device */
  132. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  133. }
  134. rt_err_t rt_hw_serial_init(void)
  135. {
  136. return rt_hw_serial_register(&serial_device, RT_CONSOLE_DEVICE_NAME,
  137. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
  138. }