eth_udp_test.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. #include "FreeRTOS_IP.h"
  2. #include "FreeRTOS_Sockets.h"
  3. #include "board.h"
  4. #include <stdio.h>
  5. // 定义目标端口号
  6. #define echoECHO_PORT (8086)
  7. #define configECHO_SERVER_ADDR0 192
  8. #define configECHO_SERVER_ADDR1 168
  9. #define configECHO_SERVER_ADDR2 137
  10. #define configECHO_SERVER_ADDR3 1
  11. static struct freertos_sockaddr xEchoServerAddress;
  12. static Socket_t xSocket_UDP;
  13. static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 2000 );
  14. // 创建UDP套接字
  15. static void UDP_Creat(void)
  16. {
  17. // 将目标端口和IP地址填入结构体
  18. xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
  19. xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0,configECHO_SERVER_ADDR1,configECHO_SERVER_ADDR2,configECHO_SERVER_ADDR3 );
  20. // 创建UDP套接字
  21. xSocket_UDP = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
  22. configASSERT( xSocket_UDP != FREERTOS_INVALID_SOCKET );
  23. // 设置接收超时时间
  24. FreeRTOS_setsockopt( xSocket_UDP, NULL, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, NULL );
  25. }
  26. // UDP发送函数
  27. static void UDP_Send(uint8_t *pSendBuff,uint32_t lBuffLen)
  28. {
  29. // 调用套接字发送函数,将数据发送到套接字
  30. FreeRTOS_sendto(xSocket_UDP,pSendBuff,lBuffLen,0,&xEchoServerAddress,NULL);
  31. }
  32. // UDP接收函数
  33. static int UDP_Recive(uint8_t * buffer,uint32_t lBuffLen)
  34. {
  35. // 调用套接字接收函数,从套接字接受数据
  36. return FreeRTOS_recvfrom(xSocket_UDP,buffer,lBuffLen,0,&xEchoServerAddress,NULL);
  37. }
  38. static void UDP_Close(void)
  39. {
  40. FreeRTOS_closesocket(xSocket_UDP);
  41. }
  42. #if 0
  43. uint8_t senddata[]=" Please send a message, the length is less than 90!";
  44. uint8_t recivedata[100] = {0};
  45. #else
  46. uint8_t senddata[]=" Please send a message, the length is less than 1MB!";
  47. uint8_t recivedata[1024*1024] = {0};
  48. #endif
  49. // UDP实验任务
  50. #if 1
  51. #if !USE_LWIP
  52. void eth_udp_test(void *pvParameters)
  53. {
  54. int i;
  55. uint8_t num = 0;
  56. int rx_size;
  57. printf("---------------- FreeRTOS-Plus-TCP UDP Test Start! ----------------\n");
  58. UDP_Creat();
  59. while(1)
  60. {
  61. if(num == 0) UDP_Send(senddata,sizeof (senddata));
  62. rx_size = UDP_Recive(recivedata,sizeof(recivedata));
  63. if(recivedata[0] != 0)
  64. {
  65. num = 1;
  66. printf("eth udp rece data(len:%d):\n", rx_size);
  67. for (i = 0; i < rx_size; i++) {
  68. printf("%c", recivedata[i]);
  69. }
  70. //printf("%s\n", recivedata);
  71. printf("\nSend back the received data!\n");
  72. UDP_Send(recivedata,sizeof (recivedata));
  73. memset( ( void * ) recivedata, 0x00, sizeof( recivedata ) );
  74. }
  75. vTaskDelay(50 / portTICK_RATE_MS );
  76. }
  77. }
  78. #else
  79. #if 1 // 使用SOCKET接口
  80. #include "sockets.h"
  81. void eth_udp_test(void *pvParameters)
  82. {
  83. int sock = -1;
  84. char recv_data[1524];
  85. struct sockaddr_in udp_addr,seraddr;
  86. int recv_data_len;
  87. socklen_t addrlen;
  88. int i;
  89. printf("-------------- Lwip TCP UDP Test Start! -------------\n");
  90. while (1) {
  91. sock = socket(AF_INET, SOCK_DGRAM, 0);
  92. if (sock < 0)
  93. {
  94. printf("Socket error\n");
  95. goto __exit;
  96. }
  97. udp_addr.sin_family = AF_INET;
  98. udp_addr.sin_addr.s_addr = INADDR_ANY;
  99. udp_addr.sin_port = htons(8088);
  100. memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));
  101. if (bind(sock, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1) {
  102. printf("Unable to bind\n");
  103. goto __exit;
  104. }
  105. while (1) {
  106. recv_data_len=recvfrom(sock, recv_data,
  107. sizeof(recv_data), 0,
  108. (struct sockaddr*)&seraddr,
  109. &addrlen);
  110. /*显示发送端的IP地址*/
  111. printf("\r\nreceive from %s\n",inet_ntoa(seraddr.sin_addr));
  112. /*显示发送端发来的字串*/
  113. for (i = 0; i < recv_data_len; i++) {
  114. printf("%c", recv_data[i]);
  115. }
  116. /*将字串返回给发送端*/
  117. sendto(sock,recv_data,
  118. recv_data_len,0,
  119. (struct sockaddr*)&seraddr,
  120. addrlen);
  121. }
  122. __exit:
  123. if (sock >= 0) closesocket(sock);
  124. if (recv_data) free(recv_data);
  125. }
  126. }
  127. #else // 使用NETCONN接口
  128. #include "tcpip.h"
  129. #include "api.h"
  130. void eth_udp_test(void *pvParameters)
  131. {
  132. err_t err;
  133. static struct netconn *udpconn;
  134. static struct netbuf *sentbuf;
  135. static struct netbuf *recvbuf;
  136. ip_addr_t destipaddr;
  137. struct pbuf *q;
  138. int i;
  139. char *g_lwip_demo_sendbuf = "UDP TX TEST!0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n";
  140. printf("-------------- Lwip TCP UDP Test Start! -------------\n");
  141. /* 第一步:创建udp控制块 */
  142. udpconn = netconn_new(NETCONN_UDP);
  143. /* 定义接收超时时间 */
  144. udpconn->recv_timeout = 10;
  145. if (udpconn != NULL) /* 判断创建控制块释放成功 */
  146. {
  147. /* 第二步:绑定控制块、本地IP和端口 */
  148. err = netconn_bind(udpconn, IP_ADDR_ANY, 8080);
  149. /* 构造目的IP地址 */
  150. IP4_ADDR(&destipaddr, 192, 168, 137, 1);
  151. /* 第三步:连接或者建立对话框 */
  152. netconn_connect(udpconn, &destipaddr, 8086); /* 连接到远端主机 */
  153. if (err == ERR_OK) { /* 绑定完成 */
  154. sentbuf = netbuf_new();
  155. netbuf_alloc(sentbuf, strlen((char *)g_lwip_demo_sendbuf));
  156. memcpy(sentbuf->p->payload, (void *)g_lwip_demo_sendbuf, strlen((char *)g_lwip_demo_sendbuf));
  157. err = netconn_send(udpconn, sentbuf); /* 将netbuf中的数据发送出去 */
  158. if (err != ERR_OK)
  159. {
  160. printf("发送失败\r\n");
  161. netbuf_delete(sentbuf); /* 删除buf */
  162. }
  163. netbuf_delete(sentbuf); /* 删除buf */
  164. while(1) {
  165. netconn_recv(udpconn, &recvbuf);
  166. if (recvbuf != NULL) { /* 接收到数据 */
  167. printf("\nudp rx:\n");
  168. for (q = recvbuf->p; q != NULL; q = q->next) { /* 遍历完整个pbuf链表 */
  169. for (i=0; i<q->len; i++)
  170. printf("%c", ((char *)q->payload)[i]);
  171. }
  172. err = netconn_send(udpconn, recvbuf); /* 将netbuf中的数据发送出去 */
  173. if (err != ERR_OK) {
  174. printf("发送失败\r\n");
  175. }
  176. netbuf_delete(recvbuf); /* 删除buf */
  177. }
  178. }
  179. vTaskDelay(10);
  180. }
  181. else printf("UDP绑定失败\r\n");
  182. }
  183. else printf("UDP连接创建失败\r\n");
  184. }
  185. #endif
  186. #endif
  187. #else
  188. #include "chip.h"
  189. #include "mfcapi.h"
  190. #include "cli.h"
  191. #include "module_test.h"
  192. #define SLICE_QUE_LEN 16
  193. #define SLICE_BUFFER_EN 1 // 启动时,缓存切片数量到SLICE_QUE_LEN,才启动解码
  194. enum {
  195. S_IDLE = 0,
  196. S_RFILE_FINISH,
  197. S_SLICE_FINISH,
  198. S_VDEC_FINISH,
  199. S_PLAY_FINISH,
  200. };
  201. static QueueHandle_t slice_queue;
  202. static QueueHandle_t play_queue;
  203. static QueueHandle_t play_end;
  204. #if SLICE_BUFFER_EN
  205. static int slice_buffer_rdy = 0;
  206. #endif
  207. static int finish_step = S_IDLE;
  208. static uint32_t video_fps = 0;
  209. typedef struct {
  210. char *buf;
  211. uint32_t size;
  212. }buf_info_t;
  213. static void display_task(void *param)
  214. {
  215. OutFrameBuffer outBuffer;
  216. uint32_t cur_tick;
  217. uint32_t last_tick;
  218. uint32_t tim;
  219. uint32_t fcs = 0;
  220. float fps = 0;
  221. float filter_fps = 0;
  222. float fps_low = 0;
  223. float fps_high = 0;
  224. int i;
  225. #if 1
  226. ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
  227. ark_lcd_osd_enable(LCD_UI_LAYER, 0);
  228. ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
  229. ark_lcd_set_osd_sync(LCD_UI_LAYER);
  230. ark_lcd_osd_coeff_enable(LCD_VIDEO_LAYER, 1);
  231. ark_lcd_osd_set_coeff(LCD_VIDEO_LAYER, 0xFF);
  232. ark_lcd_set_osd_format(LCD_VIDEO_LAYER, LCD_OSD_FORAMT_Y_UV420);
  233. ark_lcd_set_osd_possition(LCD_VIDEO_LAYER, 0, 0);
  234. ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
  235. #endif
  236. while(1) {
  237. while (xQueueReceive(play_queue, (void *)(&outBuffer), pdMS_TO_TICKS(10)) != pdTRUE) {
  238. if (finish_step == S_VDEC_FINISH) {
  239. finish_step = S_PLAY_FINISH;
  240. printf("[h264 test] display finish!\n");
  241. vTaskDelete(NULL);
  242. }
  243. }
  244. if (fcs == 0) {
  245. last_tick = xTaskGetTickCount();
  246. fcs = 1;
  247. }
  248. for(i = 0; i < outBuffer.num; i++)
  249. {
  250. #if 1
  251. int outSize = outBuffer.codedWidth * outBuffer.codedHeight * 3 / 2;
  252. ark_lcd_set_osd_size(LCD_VIDEO_LAYER, outBuffer.codedWidth, outBuffer.codedHeight);
  253. ark_lcd_set_osd_yaddr(LCD_VIDEO_LAYER, UNCACHED_VIRT_TO_PHT(outBuffer.buffer[i].pyVirAddress));
  254. ark_lcd_set_osd_uaddr(LCD_VIDEO_LAYER, UNCACHED_VIRT_TO_PHT(outBuffer.buffer[i].pyVirAddress) \
  255. + outBuffer.codedWidth*outBuffer.codedHeight);
  256. ark_lcd_set_osd_vaddr(LCD_VIDEO_LAYER, UNCACHED_VIRT_TO_PHT(outBuffer.buffer[i].pyVirAddress) \
  257. + outBuffer.codedWidth*outBuffer.codedHeight + outBuffer.codedWidth*outBuffer.codedHeight/4);
  258. ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
  259. ark_lcd_wait_for_vsync();
  260. #endif
  261. #if 0
  262. vTaskDelay(pdMS_TO_TICKS(1000/video_fps));
  263. #else
  264. //vTaskDelay(1);
  265. #endif
  266. }
  267. cur_tick = xTaskGetTickCount();
  268. if (cur_tick >= last_tick)
  269. tim = cur_tick - last_tick;
  270. else
  271. tim = (portMAX_DELAY - last_tick) + cur_tick;
  272. last_tick = cur_tick;
  273. fps = (float)1000 / pdMS_TO_TICKS(tim / outBuffer.num);
  274. if (filter_fps < 0) {
  275. filter_fps = fps;
  276. } else {
  277. filter_fps = filter_fps*0.6 + fps*0.4;
  278. if ((fps_low > filter_fps) || (fps_low == 0)) {
  279. fps_low = filter_fps;
  280. }
  281. if ((fps_high < filter_fps) || (fps_high == 0)) {
  282. fps_high = filter_fps;
  283. }
  284. }
  285. printf("c%.1f\tl%.1f\th%.1f\n", filter_fps, fps_low, fps_high);
  286. xQueueSend(play_end, NULL, portMAX_DELAY);
  287. }
  288. }
  289. // 读取切片文件
  290. static void read_file_task(void *param)
  291. {
  292. int i;
  293. int size = -1;
  294. uint32_t fsize = 0;
  295. char *buf = NULL;
  296. char *buf_temp = NULL;
  297. buf_info_t buf_info = {0};
  298. char head_tail[] = {0x12, 0x34, 0x56, 0x78};
  299. char ack[] = {'R', '_', 'O', 'K'};
  300. int fpos = 0;
  301. buf_temp = (char *)pvPortMalloc(ipconfigNETWORK_MTU + (4 - ipconfigNETWORK_MTU % 4));
  302. if (!buf_temp) {
  303. printf("malloc buf_temp fail!\n");
  304. slice_buffer_rdy = 1;
  305. finish_step = S_SLICE_FINISH;
  306. vTaskDelete(NULL);
  307. }
  308. while(1) {
  309. if (buf_info.buf) {
  310. buf = &buf_info.buf[fpos];
  311. } else {
  312. buf = buf_temp;
  313. }
  314. size = UDP_Recive(buf, ipconfigNETWORK_MTU + (4 - ipconfigNETWORK_MTU % 4));
  315. if (size > 0) {
  316. if (size == 12) {
  317. for (i = 0; i < 4; i++) {
  318. if (buf[i] != head_tail[i]) {
  319. break;
  320. }
  321. }
  322. if (i == 4) { // 新的文件
  323. fsize = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | (buf[7] << 0);
  324. video_fps = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | (buf[11] << 0);
  325. fpos = 0;
  326. //printf("new buf!\n");
  327. buf_info.size = fsize;
  328. if (buf_info.buf)
  329. vPortFree((void *)buf_info.buf);
  330. buf_info.buf = (char *)pvPortMalloc(fsize);
  331. dma_inv_range((uint32_t)buf_info.buf, (uint32_t)buf_info.buf + buf_info.size);
  332. if (!buf_info.buf) {
  333. printf("malloc fail!\n");
  334. vPortFree((void *)buf_temp);
  335. slice_buffer_rdy = 1;
  336. finish_step = S_SLICE_FINISH;
  337. vTaskDelete(NULL);
  338. }
  339. } else {
  340. if (buf_info.buf) {
  341. if (buf != &buf_info.buf[fpos])
  342. memcpy(&buf_info.buf[fpos], buf, size);
  343. fpos += size;
  344. }
  345. }
  346. } else {
  347. if (buf_info.buf) {
  348. if (buf != &buf_info.buf[fpos])
  349. memcpy(&buf_info.buf[fpos], buf, size);
  350. fpos += size;
  351. }
  352. }
  353. if (buf_info.buf) {
  354. if (fpos >= buf_info.size) {
  355. if (uxQueueMessagesWaiting(slice_queue) == 0) {
  356. printf("RQE!\n"); // Rx Queue Empty
  357. }
  358. #if SLICE_BUFFER_EN
  359. if (uxQueueMessagesWaiting(slice_queue) == SLICE_QUE_LEN) {
  360. slice_buffer_rdy = 1;
  361. }
  362. #endif
  363. if (xQueueSend(slice_queue, (void *)&buf_info, pdMS_TO_TICKS(2000)) != pdTRUE) {
  364. printf("[h264 test] send buf_info timout !\n");
  365. vPortFree((void *)buf_info.buf);
  366. vPortFree((void *)buf_temp);
  367. slice_buffer_rdy = 1;
  368. finish_step = S_SLICE_FINISH;
  369. vTaskDelete(NULL);
  370. }
  371. buf_info.buf = NULL;
  372. }
  373. }
  374. UDP_Send(ack, sizeof(ack));
  375. }
  376. }
  377. }
  378. static void vdec_task(void *param)
  379. {
  380. MFCHandle *mfc_handle = NULL;
  381. DWLLinearMem_t inBuffer;
  382. OutFrameBuffer outBuffer;
  383. buf_info_t buf_info;
  384. mfc_handle = mfc_init(RAW_STRM_TYPE_H264);
  385. if(!mfc_handle) {
  386. printf("mfc_init failed.\n");
  387. while (finish_step != S_SLICE_FINISH) {
  388. vTaskDelay(pdMS_TO_TICKS(100));
  389. }
  390. finish_step = S_VDEC_FINISH;
  391. vTaskDelete(NULL);
  392. }
  393. while(1) {
  394. #if SLICE_BUFFER_EN
  395. while (!slice_buffer_rdy) {
  396. vTaskDelay(pdMS_TO_TICKS(100));
  397. }
  398. #endif
  399. while (xQueuePeek(slice_queue, (void *)(&buf_info), pdMS_TO_TICKS(10)) != pdTRUE) {
  400. if (finish_step == S_SLICE_FINISH) {
  401. finish_step = S_VDEC_FINISH;
  402. if(mfc_handle) {
  403. mfc_uninit(mfc_handle);
  404. }
  405. printf("[h264 test] vdec finish!\n");
  406. vTaskDelete(NULL);
  407. }
  408. }
  409. CP15_flush_dcache_for_dma((u32)buf_info.buf, (u32)buf_info.buf + buf_info.size);
  410. inBuffer.virtualAddress = (u32 *)buf_info.buf;
  411. inBuffer.busAddress = VIRT_TO_PHY((u32)inBuffer.virtualAddress);
  412. inBuffer.size = buf_info.size;
  413. #if 1
  414. if(mfc_decode(mfc_handle, &inBuffer, &outBuffer) != 0) {
  415. printf("%s() mfc_decode h264 failed.\n", __func__);
  416. } else {
  417. if (outBuffer.num > 0) {
  418. xQueueSend(play_queue, (void *)&outBuffer, portMAX_DELAY);
  419. xQueueReceive(play_end, NULL, portMAX_DELAY);
  420. }
  421. }
  422. #endif
  423. vPortFree((void *)buf_info.buf);
  424. xQueueReceive(slice_queue, (void *)(&buf_info), portMAX_DELAY);
  425. }
  426. }
  427. void eth_udp_test(void *pvParameters)
  428. {
  429. int i;
  430. int rx_size;
  431. MFCHandle *mfc_handle = NULL;
  432. DWLLinearMem_t inBuffer;
  433. OutFrameBuffer outBuffer;
  434. uint8_t str[] = "board udp tx test!\n";
  435. UDP_Creat();
  436. UDP_Send(str,sizeof (str));
  437. finish_step = S_IDLE;
  438. #if SLICE_BUFFER_EN
  439. slice_buffer_rdy = 0;
  440. #endif
  441. slice_queue = xQueueCreate(SLICE_QUE_LEN, sizeof(buf_info_t));
  442. if (!slice_queue) {
  443. printf("Create slice Queue Fail!\n");
  444. return;
  445. }
  446. play_queue = xQueueCreate(1, sizeof(OutFrameBuffer));
  447. if (!play_queue) {
  448. printf("Create Display Queue Fail!\n");
  449. return;
  450. }
  451. play_end = xQueueCreate(1, 0);
  452. if (!play_end) {
  453. printf("Create queue Fail!\n");
  454. return;
  455. }
  456. xTaskCreate(read_file_task, "read_file_task", configMINIMAL_STACK_SIZE * 10, NULL,
  457. configMAX_PRIORITIES - 4, NULL);
  458. xTaskCreate(vdec_task, "vdec_task", configMINIMAL_STACK_SIZE * 10, NULL,
  459. configMAX_PRIORITIES - 5, NULL);
  460. xTaskCreate(display_task, "display_task", configMINIMAL_STACK_SIZE * 10, NULL,
  461. configMAX_PRIORITIES - 5, NULL);
  462. while(1) {
  463. if (finish_step == S_PLAY_FINISH) {
  464. vQueueDelete(slice_queue);
  465. vQueueDelete(play_queue);
  466. printf("[h264 test] finish!\n");
  467. break;
  468. }
  469. vTaskDelay(pdMS_TO_TICKS(100));
  470. }
  471. UDP_Close();
  472. }
  473. #endif