| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535 |
- #include "FreeRTOS_IP.h"
- #include "FreeRTOS_Sockets.h"
- #include "board.h"
- #include <stdio.h>
- // 定义目标端口号
- #define echoECHO_PORT (8086)
- #define configECHO_SERVER_ADDR0 192
- #define configECHO_SERVER_ADDR1 168
- #define configECHO_SERVER_ADDR2 137
- #define configECHO_SERVER_ADDR3 1
- static struct freertos_sockaddr xEchoServerAddress;
- static Socket_t xSocket_UDP;
- static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 2000 );
- // 创建UDP套接字
- static void UDP_Creat(void)
- {
- // 将目标端口和IP地址填入结构体
- xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
- xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0,configECHO_SERVER_ADDR1,configECHO_SERVER_ADDR2,configECHO_SERVER_ADDR3 );
- // 创建UDP套接字
- xSocket_UDP = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
- configASSERT( xSocket_UDP != FREERTOS_INVALID_SOCKET );
- // 设置接收超时时间
- FreeRTOS_setsockopt( xSocket_UDP, NULL, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, NULL );
- }
- // UDP发送函数
- static void UDP_Send(uint8_t *pSendBuff,uint32_t lBuffLen)
- {
- // 调用套接字发送函数,将数据发送到套接字
- FreeRTOS_sendto(xSocket_UDP,pSendBuff,lBuffLen,0,&xEchoServerAddress,NULL);
- }
- // UDP接收函数
- static int UDP_Recive(uint8_t * buffer,uint32_t lBuffLen)
- {
- // 调用套接字接收函数,从套接字接受数据
- return FreeRTOS_recvfrom(xSocket_UDP,buffer,lBuffLen,0,&xEchoServerAddress,NULL);
- }
- static void UDP_Close(void)
- {
- FreeRTOS_closesocket(xSocket_UDP);
- }
- #if 0
- uint8_t senddata[]=" Please send a message, the length is less than 90!";
- uint8_t recivedata[100] = {0};
- #else
- uint8_t senddata[]=" Please send a message, the length is less than 1MB!";
- uint8_t recivedata[1024*1024] = {0};
- #endif
- // UDP实验任务
- #if 1
- #if !USE_LWIP
- void eth_udp_test(void *pvParameters)
- {
- int i;
- uint8_t num = 0;
- int rx_size;
- printf("---------------- FreeRTOS-Plus-TCP UDP Test Start! ----------------\n");
- UDP_Creat();
- while(1)
- {
- if(num == 0) UDP_Send(senddata,sizeof (senddata));
- rx_size = UDP_Recive(recivedata,sizeof(recivedata));
- if(recivedata[0] != 0)
- {
- num = 1;
- printf("eth udp rece data(len:%d):\n", rx_size);
- for (i = 0; i < rx_size; i++) {
- printf("%c", recivedata[i]);
- }
- //printf("%s\n", recivedata);
- printf("\nSend back the received data!\n");
- UDP_Send(recivedata,sizeof (recivedata));
- memset( ( void * ) recivedata, 0x00, sizeof( recivedata ) );
- }
- vTaskDelay(50 / portTICK_RATE_MS );
- }
- }
- #else
- #if 1 // 使用SOCKET接口
- #include "sockets.h"
- void eth_udp_test(void *pvParameters)
- {
- int sock = -1;
- char recv_data[1524];
- struct sockaddr_in udp_addr,seraddr;
- int recv_data_len;
- socklen_t addrlen;
- int i;
- printf("-------------- Lwip TCP UDP Test Start! -------------\n");
- while (1) {
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock < 0)
- {
- printf("Socket error\n");
- goto __exit;
- }
- udp_addr.sin_family = AF_INET;
- udp_addr.sin_addr.s_addr = INADDR_ANY;
- udp_addr.sin_port = htons(8088);
- memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));
- if (bind(sock, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1) {
- printf("Unable to bind\n");
- goto __exit;
- }
- while (1) {
- recv_data_len=recvfrom(sock, recv_data,
- sizeof(recv_data), 0,
- (struct sockaddr*)&seraddr,
- &addrlen);
- /*显示发送端的IP地址*/
- printf("\r\nreceive from %s\n",inet_ntoa(seraddr.sin_addr));
- /*显示发送端发来的字串*/
- for (i = 0; i < recv_data_len; i++) {
- printf("%c", recv_data[i]);
- }
- /*将字串返回给发送端*/
- sendto(sock,recv_data,
- recv_data_len,0,
- (struct sockaddr*)&seraddr,
- addrlen);
- }
- __exit:
- if (sock >= 0) closesocket(sock);
- if (recv_data) free(recv_data);
- }
- }
- #else // 使用NETCONN接口
- #include "tcpip.h"
- #include "api.h"
- void eth_udp_test(void *pvParameters)
- {
- err_t err;
- static struct netconn *udpconn;
- static struct netbuf *sentbuf;
- static struct netbuf *recvbuf;
- ip_addr_t destipaddr;
- struct pbuf *q;
- int i;
- char *g_lwip_demo_sendbuf = "UDP TX TEST!0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n";
- printf("-------------- Lwip TCP UDP Test Start! -------------\n");
- /* 第一步:创建udp控制块 */
- udpconn = netconn_new(NETCONN_UDP);
- /* 定义接收超时时间 */
- udpconn->recv_timeout = 10;
- if (udpconn != NULL) /* 判断创建控制块释放成功 */
- {
- /* 第二步:绑定控制块、本地IP和端口 */
- err = netconn_bind(udpconn, IP_ADDR_ANY, 8080);
- /* 构造目的IP地址 */
- IP4_ADDR(&destipaddr, 192, 168, 137, 1);
- /* 第三步:连接或者建立对话框 */
- netconn_connect(udpconn, &destipaddr, 8086); /* 连接到远端主机 */
- if (err == ERR_OK) { /* 绑定完成 */
- sentbuf = netbuf_new();
- netbuf_alloc(sentbuf, strlen((char *)g_lwip_demo_sendbuf));
- memcpy(sentbuf->p->payload, (void *)g_lwip_demo_sendbuf, strlen((char *)g_lwip_demo_sendbuf));
- err = netconn_send(udpconn, sentbuf); /* 将netbuf中的数据发送出去 */
- if (err != ERR_OK)
- {
- printf("发送失败\r\n");
- netbuf_delete(sentbuf); /* 删除buf */
- }
- netbuf_delete(sentbuf); /* 删除buf */
- while(1) {
- netconn_recv(udpconn, &recvbuf);
- if (recvbuf != NULL) { /* 接收到数据 */
- printf("\nudp rx:\n");
- for (q = recvbuf->p; q != NULL; q = q->next) { /* 遍历完整个pbuf链表 */
- for (i=0; i<q->len; i++)
- printf("%c", ((char *)q->payload)[i]);
- }
- err = netconn_send(udpconn, recvbuf); /* 将netbuf中的数据发送出去 */
- if (err != ERR_OK) {
- printf("发送失败\r\n");
- }
- netbuf_delete(recvbuf); /* 删除buf */
- }
- }
- vTaskDelay(10);
- }
- else printf("UDP绑定失败\r\n");
- }
- else printf("UDP连接创建失败\r\n");
- }
- #endif
- #endif
- #else
- #include "chip.h"
- #include "mfcapi.h"
- #include "cli.h"
- #include "module_test.h"
- #define SLICE_QUE_LEN 16
- #define SLICE_BUFFER_EN 1 // 启动时,缓存切片数量到SLICE_QUE_LEN,才启动解码
- enum {
- S_IDLE = 0,
- S_RFILE_FINISH,
- S_SLICE_FINISH,
- S_VDEC_FINISH,
- S_PLAY_FINISH,
- };
- static QueueHandle_t slice_queue;
- static QueueHandle_t play_queue;
- static QueueHandle_t play_end;
- #if SLICE_BUFFER_EN
- static int slice_buffer_rdy = 0;
- #endif
- static int finish_step = S_IDLE;
- static uint32_t video_fps = 0;
- typedef struct {
- char *buf;
- uint32_t size;
- }buf_info_t;
- static void display_task(void *param)
- {
- OutFrameBuffer outBuffer;
- uint32_t cur_tick;
- uint32_t last_tick;
- uint32_t tim;
- uint32_t fcs = 0;
- float fps = 0;
- float filter_fps = 0;
- float fps_low = 0;
- float fps_high = 0;
- int i;
- #if 1
- ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
- ark_lcd_osd_enable(LCD_UI_LAYER, 0);
- ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
- ark_lcd_set_osd_sync(LCD_UI_LAYER);
- ark_lcd_osd_coeff_enable(LCD_VIDEO_LAYER, 1);
- ark_lcd_osd_set_coeff(LCD_VIDEO_LAYER, 0xFF);
- ark_lcd_set_osd_format(LCD_VIDEO_LAYER, LCD_OSD_FORAMT_Y_UV420);
- ark_lcd_set_osd_possition(LCD_VIDEO_LAYER, 0, 0);
- ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
- #endif
- while(1) {
- while (xQueueReceive(play_queue, (void *)(&outBuffer), pdMS_TO_TICKS(10)) != pdTRUE) {
- if (finish_step == S_VDEC_FINISH) {
- finish_step = S_PLAY_FINISH;
- printf("[h264 test] display finish!\n");
- vTaskDelete(NULL);
- }
- }
- if (fcs == 0) {
- last_tick = xTaskGetTickCount();
- fcs = 1;
- }
- for(i = 0; i < outBuffer.num; i++)
- {
- #if 1
- int outSize = outBuffer.codedWidth * outBuffer.codedHeight * 3 / 2;
- ark_lcd_set_osd_size(LCD_VIDEO_LAYER, outBuffer.codedWidth, outBuffer.codedHeight);
- ark_lcd_set_osd_yaddr(LCD_VIDEO_LAYER, UNCACHED_VIRT_TO_PHT(outBuffer.buffer[i].pyVirAddress));
- ark_lcd_set_osd_uaddr(LCD_VIDEO_LAYER, UNCACHED_VIRT_TO_PHT(outBuffer.buffer[i].pyVirAddress) \
- + outBuffer.codedWidth*outBuffer.codedHeight);
- ark_lcd_set_osd_vaddr(LCD_VIDEO_LAYER, UNCACHED_VIRT_TO_PHT(outBuffer.buffer[i].pyVirAddress) \
- + outBuffer.codedWidth*outBuffer.codedHeight + outBuffer.codedWidth*outBuffer.codedHeight/4);
- ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
- ark_lcd_wait_for_vsync();
- #endif
- #if 0
- vTaskDelay(pdMS_TO_TICKS(1000/video_fps));
- #else
- //vTaskDelay(1);
- #endif
- }
- cur_tick = xTaskGetTickCount();
- if (cur_tick >= last_tick)
- tim = cur_tick - last_tick;
- else
- tim = (portMAX_DELAY - last_tick) + cur_tick;
- last_tick = cur_tick;
- fps = (float)1000 / pdMS_TO_TICKS(tim / outBuffer.num);
- if (filter_fps < 0) {
- filter_fps = fps;
- } else {
- filter_fps = filter_fps*0.6 + fps*0.4;
- if ((fps_low > filter_fps) || (fps_low == 0)) {
- fps_low = filter_fps;
- }
- if ((fps_high < filter_fps) || (fps_high == 0)) {
- fps_high = filter_fps;
- }
- }
- printf("c%.1f\tl%.1f\th%.1f\n", filter_fps, fps_low, fps_high);
- xQueueSend(play_end, NULL, portMAX_DELAY);
- }
- }
- // 读取切片文件
- static void read_file_task(void *param)
- {
- int i;
- int size = -1;
- uint32_t fsize = 0;
- char *buf = NULL;
- char *buf_temp = NULL;
- buf_info_t buf_info = {0};
- char head_tail[] = {0x12, 0x34, 0x56, 0x78};
- char ack[] = {'R', '_', 'O', 'K'};
- int fpos = 0;
- buf_temp = (char *)pvPortMalloc(ipconfigNETWORK_MTU + (4 - ipconfigNETWORK_MTU % 4));
- if (!buf_temp) {
- printf("malloc buf_temp fail!\n");
- slice_buffer_rdy = 1;
- finish_step = S_SLICE_FINISH;
- vTaskDelete(NULL);
- }
- while(1) {
- if (buf_info.buf) {
- buf = &buf_info.buf[fpos];
- } else {
- buf = buf_temp;
- }
- size = UDP_Recive(buf, ipconfigNETWORK_MTU + (4 - ipconfigNETWORK_MTU % 4));
- if (size > 0) {
- if (size == 12) {
- for (i = 0; i < 4; i++) {
- if (buf[i] != head_tail[i]) {
- break;
- }
- }
- if (i == 4) { // 新的文件
- fsize = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | (buf[7] << 0);
- video_fps = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | (buf[11] << 0);
- fpos = 0;
- //printf("new buf!\n");
- buf_info.size = fsize;
- if (buf_info.buf)
- vPortFree((void *)buf_info.buf);
- buf_info.buf = (char *)pvPortMalloc(fsize);
- dma_inv_range((uint32_t)buf_info.buf, (uint32_t)buf_info.buf + buf_info.size);
- if (!buf_info.buf) {
- printf("malloc fail!\n");
- vPortFree((void *)buf_temp);
- slice_buffer_rdy = 1;
- finish_step = S_SLICE_FINISH;
- vTaskDelete(NULL);
- }
- } else {
- if (buf_info.buf) {
- if (buf != &buf_info.buf[fpos])
- memcpy(&buf_info.buf[fpos], buf, size);
- fpos += size;
- }
- }
- } else {
- if (buf_info.buf) {
- if (buf != &buf_info.buf[fpos])
- memcpy(&buf_info.buf[fpos], buf, size);
- fpos += size;
- }
- }
- if (buf_info.buf) {
- if (fpos >= buf_info.size) {
- if (uxQueueMessagesWaiting(slice_queue) == 0) {
- printf("RQE!\n"); // Rx Queue Empty
- }
- #if SLICE_BUFFER_EN
- if (uxQueueMessagesWaiting(slice_queue) == SLICE_QUE_LEN) {
- slice_buffer_rdy = 1;
- }
- #endif
- if (xQueueSend(slice_queue, (void *)&buf_info, pdMS_TO_TICKS(2000)) != pdTRUE) {
- printf("[h264 test] send buf_info timout !\n");
- vPortFree((void *)buf_info.buf);
- vPortFree((void *)buf_temp);
- slice_buffer_rdy = 1;
- finish_step = S_SLICE_FINISH;
- vTaskDelete(NULL);
- }
- buf_info.buf = NULL;
- }
- }
- UDP_Send(ack, sizeof(ack));
- }
- }
- }
- static void vdec_task(void *param)
- {
- MFCHandle *mfc_handle = NULL;
- DWLLinearMem_t inBuffer;
- OutFrameBuffer outBuffer;
- buf_info_t buf_info;
- mfc_handle = mfc_init(RAW_STRM_TYPE_H264);
- if(!mfc_handle) {
- printf("mfc_init failed.\n");
- while (finish_step != S_SLICE_FINISH) {
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- finish_step = S_VDEC_FINISH;
- vTaskDelete(NULL);
- }
- while(1) {
- #if SLICE_BUFFER_EN
- while (!slice_buffer_rdy) {
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- #endif
- while (xQueuePeek(slice_queue, (void *)(&buf_info), pdMS_TO_TICKS(10)) != pdTRUE) {
- if (finish_step == S_SLICE_FINISH) {
- finish_step = S_VDEC_FINISH;
- if(mfc_handle) {
- mfc_uninit(mfc_handle);
- }
- printf("[h264 test] vdec finish!\n");
- vTaskDelete(NULL);
- }
- }
- CP15_flush_dcache_for_dma((u32)buf_info.buf, (u32)buf_info.buf + buf_info.size);
- inBuffer.virtualAddress = (u32 *)buf_info.buf;
- inBuffer.busAddress = VIRT_TO_PHY((u32)inBuffer.virtualAddress);
- inBuffer.size = buf_info.size;
- #if 1
- if(mfc_decode(mfc_handle, &inBuffer, &outBuffer) != 0) {
- printf("%s() mfc_decode h264 failed.\n", __func__);
- } else {
- if (outBuffer.num > 0) {
- xQueueSend(play_queue, (void *)&outBuffer, portMAX_DELAY);
- xQueueReceive(play_end, NULL, portMAX_DELAY);
- }
- }
- #endif
- vPortFree((void *)buf_info.buf);
- xQueueReceive(slice_queue, (void *)(&buf_info), portMAX_DELAY);
- }
- }
- void eth_udp_test(void *pvParameters)
- {
- int i;
- int rx_size;
- MFCHandle *mfc_handle = NULL;
- DWLLinearMem_t inBuffer;
- OutFrameBuffer outBuffer;
- uint8_t str[] = "board udp tx test!\n";
- UDP_Creat();
- UDP_Send(str,sizeof (str));
- finish_step = S_IDLE;
- #if SLICE_BUFFER_EN
- slice_buffer_rdy = 0;
- #endif
- slice_queue = xQueueCreate(SLICE_QUE_LEN, sizeof(buf_info_t));
- if (!slice_queue) {
- printf("Create slice Queue Fail!\n");
- return;
- }
- play_queue = xQueueCreate(1, sizeof(OutFrameBuffer));
- if (!play_queue) {
- printf("Create Display Queue Fail!\n");
- return;
- }
- play_end = xQueueCreate(1, 0);
- if (!play_end) {
- printf("Create queue Fail!\n");
- return;
- }
- xTaskCreate(read_file_task, "read_file_task", configMINIMAL_STACK_SIZE * 10, NULL,
- configMAX_PRIORITIES - 4, NULL);
- xTaskCreate(vdec_task, "vdec_task", configMINIMAL_STACK_SIZE * 10, NULL,
- configMAX_PRIORITIES - 5, NULL);
- xTaskCreate(display_task, "display_task", configMINIMAL_STACK_SIZE * 10, NULL,
- configMAX_PRIORITIES - 5, NULL);
- while(1) {
- if (finish_step == S_PLAY_FINISH) {
- vQueueDelete(slice_queue);
- vQueueDelete(play_queue);
- printf("[h264 test] finish!\n");
- break;
- }
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- UDP_Close();
- }
- #endif
|