mb.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /******************************************************************************
  2. 版权所有: 文件名称: mb.c
  3. 文件名称: mb.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2022-05-17
  7. 功能说明: 邮箱驱动
  8. 其它说明:
  9. 修改记录:
  10. */
  11. #include "bspconfig.h"
  12. #include "bsp.h"
  13. #include "mb.h"
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <stdint.h>
  17. #include <string.h>
  18. #include <fcntl.h>
  19. #include <unistd.h>
  20. #include <sys/ioctl.h>
  21. #include <sys/mman.h>
  22. #include <pthread.h>
  23. #include <stdbool.h>
  24. #define CO_IOCTL_GET_REG 1
  25. #define CO_IOCTL_SET_REG 2
  26. #define CO_IOCTL_EXECUTE 3
  27. #define CO_IOCTL_GET_DATA 4
  28. #define CO_IOCTL_SET_DATA 5
  29. #define CO_IOCTL_GET_CONFIGS 6
  30. #define CO_IOCTL_SET_PC 7
  31. #ifndef CO_MB_FIFO_SIZE
  32. #define CO_MB_FIFO_SIZE 32 // 经测试,只能这么大的buf
  33. #endif
  34. struct co_io
  35. {
  36. uint8_t meta;
  37. uint16_t metadata;
  38. uint32_t data[CO_MB_FIFO_SIZE - 1];
  39. uint8_t len;
  40. };
  41. struct mb_co
  42. {
  43. char *name;
  44. pthread_t thread_id;
  45. int fd_co;
  46. struct co_io coio;
  47. };
  48. static struct mb_co *pmb;
  49. static inline void dmsg_u8(uint8_t *data, int length, char *str)
  50. {
  51. int i, j;
  52. int tmp;
  53. printf("%s:\n", str);
  54. for (i = 0; i < (length / 16); i++)
  55. {
  56. for (j = 0; j < 16; j++)
  57. printf("%02x ", data[i * 16 + j]);
  58. printf("\n");
  59. }
  60. tmp = (length / 16) * 16;
  61. for (i = 0; i < (length % 16); i++)
  62. printf("%02x ", data[tmp + i]);
  63. if (length % 16)
  64. printf("\n");
  65. }
  66. /******************************************************************************
  67. 函数名称: mb_write
  68. 函数版本: 01.01
  69. 创建作者: sunxi
  70. 创建日期: 2022-05-17
  71. 函数说明: 向邮箱写入数据.
  72. 参数说明:
  73. cmd:命令号
  74. data:写入数据
  75. len:写入数据长度,注意: 如果转入2个uint32_t的数据,那么长度为2,不是8.
  76. 返回值: 成功返回0, 失败返回-1
  77. 修改记录:
  78. !!!!!!!!! 注意: 如果转入2个uint32_t的数据,那么长度为2,不是8.
  79. */
  80. int mb_write(uint16_t cmd, uint32_t *data, uint8_t len)
  81. {
  82. return 0; // noted by ygl: 邮箱功能暂时不实现
  83. int i;
  84. int ret;
  85. struct mb_co *co = NULL;
  86. if (pmb == NULL)
  87. return -1;
  88. if (data == NULL)
  89. return -1;
  90. if (len > (CO_MB_FIFO_SIZE - 1))
  91. return -1;
  92. co = pmb;
  93. for (i = 0; i < len; i++)
  94. co->coio.data[i] = data[i];
  95. /*
  96. meta =0时,metadata无效,对方收不到metadata值。
  97. meta =为非0时,metadata置数,对方也收到metadata值。
  98. */
  99. /* ipc message parameters */
  100. co->coio.meta = 1; // noted by sunxi: 与裸核,约定为1
  101. co->coio.metadata = cmd;
  102. co->coio.len = len;
  103. #if 0
  104. for (i = 0; i < co->coio.len; i++)
  105. printf("%04X ", co->coio.data[i]);
  106. printf("\r\n");
  107. #endif
  108. ret = ioctl(co->fd_co, CO_IOCTL_SET_DATA, &co->coio);
  109. if (ret)
  110. printf("send to %s failed, ret = %d\n", co->name, ret);
  111. return 0;
  112. }
  113. /******************************************************************************
  114. 函数名称: mb_notice_time_update
  115. 函数版本: 01.01
  116. 创建作者: sunxi
  117. 创建日期: 2022-05-17
  118. 函数说明: 用邮箱告知时间更新了
  119. 参数说明:
  120. 返回值: 成功返回0, 失败返回-1
  121. 修改记录:
  122. */
  123. int mb_notice_time_update(void)
  124. {
  125. int ret;
  126. uint32_t data[31];
  127. data[0] = MB_CMD_TIME;
  128. data[1] = MB_CMD_TIME;
  129. ret = mb_write(MB_CMD_TIME, data, 2);
  130. if (ret < 0)
  131. printf("mb_write fail!!! ret= %d\n", ret);
  132. return ret;
  133. }
  134. /******************************************************************************
  135. 函数名称: mb_notice_freqTr_update
  136. 函数版本: 01.01
  137. 创建作者: sunxi
  138. 创建日期: 2022-05-17
  139. 函数说明: 用邮箱告知频率跟踪更新了
  140. 参数说明:
  141. 返回值: 成功返回0, 失败返回-1
  142. 修改记录:
  143. */
  144. int mb_notice_freqTr_update(void)
  145. {
  146. int ret;
  147. uint32_t data[31];
  148. data[0] = MB_CMD_FREQTR;
  149. data[1] = MB_CMD_FREQTR;
  150. ret = mb_write(MB_CMD_FREQTR, data, 2);
  151. if (ret < 0)
  152. printf("mb_write fail!!! ret= %d\n", ret);
  153. return ret;
  154. }
  155. /******************************************************************************
  156. 函数名称: mb_notice_RfV_update
  157. 函数版本: 01.01
  158. 创建作者: sunxi
  159. 创建日期: 2022-05-17
  160. 函数说明: 用邮箱告知AD7616参考电压范围更新了
  161. 参数说明:
  162. no:第n片7616
  163. 返回值: 成功返回0, 失败返回-1
  164. 修改记录:
  165. */
  166. int mb_notice_RfV_update(uint8_t no)
  167. {
  168. int ret;
  169. uint32_t data[31];
  170. data[0] = no;
  171. data[1] = no;
  172. ret = mb_write(MB_CMD_RfV, data, 2);
  173. if (ret < 0)
  174. printf("mb_write fail!!! ret= %d\n", ret);
  175. return ret;
  176. }
  177. static int co_mb_open(struct mb_co *co, char *name)
  178. {
  179. int fd_co;
  180. printf("open co mb dev %s\n", name);
  181. fd_co = open(name, O_RDWR);
  182. if (!fd_co)
  183. {
  184. printf("open co dev failed\n");
  185. return -1;
  186. }
  187. co->name = name;
  188. co->fd_co = fd_co;
  189. return 0;
  190. }
  191. static void *thread_co_test(void *arg)
  192. {
  193. struct mb_co *co = pmb;
  194. // int i;
  195. int ret;
  196. while (1)
  197. {
  198. sleep(1);
  199. #if 0
  200. crc++;
  201. for (i = 0; i < (CO_MB_FIFO_SIZE - 1); i++)
  202. data[i] = i+crc;
  203. ret = mb_write(MB_CMD_TIME, data, 31);
  204. if(ret<0)
  205. printf("send to %s failed, ret = %d\n",co->name, ret);
  206. #endif
  207. ret = mb_notice_time_update();
  208. if (ret < 0)
  209. printf("send to %s failed, ret = %d\n", co->name, ret);
  210. }
  211. printf("thread co exit\r\n");
  212. pthread_exit(NULL);
  213. }
  214. // 测试代码
  215. void mb_test(void)
  216. {
  217. int ret;
  218. if ((ret = pthread_create(&pmb->thread_id, NULL, thread_co_test, pmb)) == 0)
  219. printf("thread co0 create success\r\n");
  220. else
  221. printf("thread co0 create fail ret=%d\r\n", ret);
  222. }
  223. /******************************************************************************
  224. 函数名称: mb_init
  225. 函数版本: 01.01
  226. 创建作者: sunxi
  227. 创建日期: 2022-05-17
  228. 函数说明: mb初始化.
  229. 参数说明:
  230. 返回值: 成功返回0, 失败返回-1
  231. 修改记录:
  232. */
  233. int mb_init(void)
  234. {
  235. // int ret;
  236. pmb = malloc(sizeof(struct mb_co));
  237. memset(pmb, 0, sizeof(struct mb_co));
  238. if (co_mb_open(pmb, "/dev/arv-shmem"))
  239. {
  240. printf("open mb error\r\n");
  241. return -1;
  242. }
  243. // mb_test();//sunxi for test
  244. return 0;
  245. }
  246. /******************************************************************************
  247. 函数名称: mb_exit
  248. 函数版本: 01.01
  249. 创建作者: sunxi
  250. 创建日期: 2022-05-17
  251. 函数说明: mb反初始化.
  252. 参数说明:
  253. 返回值: 总是返回0.
  254. 修改记录:
  255. */
  256. int mb_exit(void)
  257. {
  258. if (pmb)
  259. {
  260. if (pmb->fd_co)
  261. close(pmb->fd_co);
  262. }
  263. return 0;
  264. }