dmalock.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* Copyright Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <rtthread.h>
  16. #include "dmalock.h"
  17. struct dmac_host
  18. {
  19. struct rt_semaphore sem;
  20. struct rt_mutex mutex;
  21. uint8_t channel_used[DMAC_CHANNEL_COUNT];
  22. char *channel_name[DMAC_CHANNEL_COUNT];
  23. };
  24. static struct dmac_host _dmac_host;
  25. void dmalock_init(void)
  26. {
  27. rt_sem_init(&_dmac_host.sem, "dma_sem", DMAC_CHANNEL_COUNT, RT_IPC_FLAG_FIFO);
  28. rt_mutex_init(&_dmac_host.mutex, "dma_mutex", RT_IPC_FLAG_PRIO);
  29. for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
  30. {
  31. _dmac_host.channel_used[i] = 0;
  32. _dmac_host.channel_name[i] = NULL;
  33. }
  34. }
  35. int _dmalock_sync_take(dmac_channel_number_t *chn, int timeout_ms, const char *name)
  36. {
  37. rt_err_t result;
  38. *chn = DMAC_CHANNEL_MAX;
  39. result = rt_sem_take(&_dmac_host.sem, timeout_ms);
  40. if (result == RT_EOK)
  41. {
  42. rt_mutex_take(&_dmac_host.mutex, RT_WAITING_FOREVER);
  43. for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
  44. {
  45. if (_dmac_host.channel_used[i] == 0)
  46. {
  47. _dmac_host.channel_used[i] = 1;
  48. _dmac_host.channel_name[i] = name;
  49. *chn = i;
  50. break;
  51. }
  52. }
  53. rt_mutex_release(&_dmac_host.mutex);
  54. }
  55. return result;
  56. }
  57. void dmalock_release(dmac_channel_number_t chn)
  58. {
  59. if (chn >= DMAC_CHANNEL_MAX)
  60. return;
  61. _dmac_host.channel_name[chn] = NULL;
  62. _dmac_host.channel_used[chn] = 0;
  63. rt_sem_release(&_dmac_host.sem);
  64. }
  65. static void dma_ch_info(int argc, char **argv)
  66. {
  67. uint32_t cnt = 0;
  68. for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
  69. {
  70. if (_dmac_host.channel_used[i] != 0)
  71. {
  72. rt_kprintf("dma_ch%d is using by func [%s]\n", i, _dmac_host.channel_name[i]);
  73. cnt++;
  74. }
  75. }
  76. if(cnt == 0)
  77. rt_kprintf(" no dma_ch is using.\n");
  78. }
  79. MSH_CMD_EXPORT(dma_ch_info, list dma channel informationn.);