log_file.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. void log_trace_file_init(const char *filename)
  80. {
  81. rt_device_t device;
  82. device = rt_device_find("logfile");
  83. if (device == RT_NULL)
  84. {
  85. rt_memset(&_file_device, 0x00, sizeof(_file_device));
  86. _file_device.parent.type = RT_Device_Class_Char;
  87. _file_device.parent.init = RT_NULL;
  88. _file_device.parent.open = fdevice_open;
  89. _file_device.parent.close = fdevice_close;
  90. _file_device.parent.write = fdevice_write;
  91. rt_device_register(&_file_device.parent, "logfile", O_RDWR);
  92. }
  93. _file_device.filename = rt_strdup(filename);
  94. _file_device.fd = -1;
  95. }
  96. void log_trace_set_file(const char *filename)
  97. {
  98. log_trace_file_init(filename);
  99. log_trace_set_device("logfile");
  100. }
  101. #ifdef RT_USING_FINSH
  102. #include <finsh.h>
  103. FINSH_FUNCTION_EXPORT_ALIAS(log_trace_set_file, log_file, set output filename of log trace);
  104. #endif
  105. #endif /* RT_USING_DFS */