log_file.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * File : log_file.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2013, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * Bernard the first version
  23. * 2013-06-26 Grissiom refactor
  24. */
  25. #include <rtthread.h>
  26. #include <log_trace.h>
  27. #ifdef RT_USING_DFS
  28. #include <dfs_posix.h>
  29. struct file_device
  30. {
  31. struct rt_device parent;
  32. int fd;
  33. char *filename;
  34. };
  35. /* file device for log trace */
  36. static struct file_device _file_device;
  37. /* common device interface */
  38. static rt_err_t fdevice_open(rt_device_t dev, rt_uint16_t oflag)
  39. {
  40. int fd;
  41. struct file_device *fdev = (struct file_device *)dev;
  42. if (fdev->fd >= 0)
  43. return -RT_EBUSY;
  44. /* test and open */
  45. fd = open(fdev->filename, O_RDONLY, 0);
  46. if (fd >= 0)
  47. {
  48. close(fd);
  49. fd = open(fdev->filename, O_WRONLY | O_APPEND, 0);
  50. }
  51. else
  52. {
  53. /* file not exists */
  54. fd = open(fdev->filename, O_WRONLY | O_CREAT, 0);
  55. }
  56. fdev->fd = fd;
  57. return RT_EOK;
  58. }
  59. static rt_err_t fdevice_close(rt_device_t dev)
  60. {
  61. rt_err_t result;
  62. struct file_device *fdev = (struct file_device *)dev;
  63. if (fdev->fd < 0)
  64. return -RT_EBUSY;
  65. result = close(fdev->fd);
  66. if (result == 0)
  67. {
  68. fdev->fd = -1;
  69. }
  70. return result;
  71. }
  72. static rt_size_t fdevice_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  73. {
  74. struct file_device *fdev = (struct file_device *)dev;
  75. if (fdev->fd < 0)
  76. return 0;
  77. return write(fdev->fd, buffer, size);
  78. }
  79. static rt_err_t fdevice_control(rt_device_t dev, int cmd, void *arg)
  80. {
  81. struct file_device *fdev = (struct file_device *)dev;
  82. if (fdev->fd < 0)
  83. return 0;
  84. switch (cmd)
  85. {
  86. case LOG_TRACE_CTRL_FLUSH:
  87. if (fsync(fdev->fd) != 0)
  88. return RT_ERROR;
  89. break;
  90. default:
  91. break;
  92. }
  93. return RT_EOK;
  94. }
  95. #ifdef RT_USING_DEVICE_OPS
  96. const static struct rt_device_ops log_trace_ops =
  97. {
  98. RT_NULL,
  99. fdevice_open,
  100. fdevice_close,
  101. RT_NULL,
  102. fdevice_write,
  103. fdevice_control
  104. };
  105. #endif
  106. void log_trace_file_init(const char *filename)
  107. {
  108. rt_device_t device;
  109. device = rt_device_find("logfile");
  110. if (device == RT_NULL)
  111. {
  112. rt_memset(&_file_device, 0x00, sizeof(_file_device));
  113. _file_device.parent.type = RT_Device_Class_Char;
  114. #ifdef RT_USING_DEVICE_OPS
  115. _file_device.parent.ops = &log_trace_ops;
  116. #else
  117. _file_device.parent.init = RT_NULL;
  118. _file_device.parent.open = fdevice_open;
  119. _file_device.parent.close = fdevice_close;
  120. _file_device.parent.write = fdevice_write;
  121. _file_device.parent.control = fdevice_control;
  122. #endif
  123. rt_device_register(&_file_device.parent, "logfile", O_RDWR);
  124. }
  125. _file_device.filename = rt_strdup(filename);
  126. _file_device.fd = -1;
  127. }
  128. void log_trace_set_file(const char *filename)
  129. {
  130. log_trace_file_init(filename);
  131. log_trace_set_device("logfile");
  132. }
  133. #ifdef RT_USING_FINSH
  134. #include <finsh.h>
  135. FINSH_FUNCTION_EXPORT_ALIAS(log_trace_set_file, log_file, set output filename of log trace);
  136. #endif
  137. #endif /* RT_USING_DFS */