DSP

DSP- 6678--------- 多核DSP图像处理(2)主核程序之tsk_master_fun

2019-07-13 10:47发布

一、cfg文件配置 var tskMainThread = Task.create("&StartNetworkTask"); /*创建TCP进程*/ tskMainThread.stackSize = 0x2000; tskMainThread.priority = 0x5; tskMainThread.instance.name = "StartNetworkTask"; 创建TCP进程  用于从上位机发送和接收图像。将在下一节中介绍 二、main函数     2.1 网络初始化     GbE_init();     2.2 IPC开启     status = Ipc_start(); if (status < 0) { System_abort("Ipc_start failed "); }     2.3 创建heapBuf     HeapBufMP_Params_init(&heapBufParams); heapBufParams.regionId = 0; heapBufParams.name = IMAGE_PROCESSING_HEAP_NAME;//name用于open函数指定打开 heapBufParams.numBlocks = number_of_cores; heapBufParams.blockSize = sizeof(process_message_t); heapHandle = HeapBufMP_create(&heapBufParams); if (heapHandle == NULL) { System_abort("HeapBufMP_create failed " ); }     /* Register this heap with MessageQ */     status = MessageQ_registerHeap((IHeap_Handle)heapHandle, IMAGE_PROCESSING_HEAPID);     if(status != MessageQ_S_SUCCESS)     {     System_abort("Main: MessageQ_registerHeap failed " );     } System_abort("Main: MessageQ_registerHeap failed " );     }     2.4 初始化一些参数             1 给8个核的msg指针分配空间
            2 给8个核MessageQ_alloc             3 初始化slave_queue_name     2.5 创建 接收和发送的mailbox           /*=================================================================================== * 邮箱接收的数据: 边缘检测,数据指针和长度,核个数 *=================================================================================== */ master_mbox_receive = Mailbox_create (sizeof(mbox_process_msg_t), 1, 0, 0); //返回值Mailbox_Handle     if(!master_mbox_receive)     {     System_printf("main: Mailbox creation failed for master_mbox_receive ");     } /*=================================================================================== * 邮箱发送传递的数据: 数据指针和长度,处理时间,处理结果 *=================================================================================== */     master_mbox_send = Mailbox_create (sizeof(mbox_response_msg_t), 1, 0, 0); //返回值Mailbox_Handle     if(!master_mbox_send)     {      System_printf("main: Mailbox creation failed for master_mbox_send ");     }     2.6 创建第二个进程  tsk_master_func     /* Create a unique 'master' Task if on proc 0 */ Task_Params_init(¶ms); params.stackSize = 0x2000; params.priority = 7; Task_create(tsk_master_func, ¶ms, NULL);    本节主要进行该进程的介绍      2.7 BIOS_start( ) 三、tsk_master_func进程 3.1 等上位机传递来的mailbox /*等邮箱消息 上位机通过TCP会发送图片给DSP DSP收到之后会产生 Mailbox_post 这里的Mailbox_pend就是在等待这个Mailbox_post */ if (Mailbox_pend(master_mbox_receive, &process_msg, BIOS_WAIT_FOREVER) == FALSE) { System_printf("main: Mailbox_pend returns error "); return; } 3.2 图像处理调度过程  mc_process_bmp <1> 读取图片像素 if (bmp_read_header(p_input_image, &bmp_header) < 0) //读取图片信息,填充bmp_header { printf("Error in reading header "); ret_val = -1; goto close_n_exit; } pixel_size = bmp_header.dib.bits_per_pixel / 8; //每一个像素的字节数 pixel_size = BPP/8 row_width = bmp_header.dib.image_width * pixel_size; //行宽(单位为字节) if (bmp_header.dib.number_of_colors) { /* Color table present */ color_table_size = ROUNDUP(sizeof(bmp_color_table_t) * bmp_header.dib.number_of_colors, MAX_CACHE_LINE); p_color_table = (bmp_color_table_t *)Memory_alloc(0, color_table_size, MAX_CACHE_LINE, NULL); if(!p_color_table) { printf("Can't allocate memory for color table "); ret_val = -1; goto close_n_exit; } if (bmp_read_colormap(p_input_image, &bmp_header, p_color_table) < 0) { printf("Error in reading color map "); ret_val = -1; goto close_n_exit; } Cache_wb(p_color_table, color_table_size, Cache_Type_ALL, FALSE); } /* Read the pixels */ pixel_array_rgb_size = ROUNDUP(bmp_header.dib.image_height * row_width, MAX_CACHE_LINE); //整个图片的大小 (单位 字节) pixel_array_rgb = (uint8_t *) Memory_alloc(0, pixel_array_rgb_size, MAX_CACHE_LINE, NULL); //该指针指向的地址存储整个图片的像素 if (!pixel_array_rgb) { printf("Can't allocate memory for pixel_array_rgb "); ret_val = -1; goto close_n_exit; } /*=================================================================================================== * 读取BMP图像信息 从 p_input_image提取出头部信息 存放在pixel_array_rgb中 * rgb[n]指向pixel_array_rgb rgb *=================================================================================================== */ //将p_input_image.data ==> pixel_array_rgb中 if (bmp_read_image (p_input_image, &bmp_header, pixel_array_rgb) < 0) { printf("Error in reading pixel image "); ret_val = -1; goto close_n_exit; } Cache_wb(pixel_array_rgb, (bmp_header.dib.image_height * row_width), Cache_Type_ALL, FALSE);   p_input_image为输入的bmp图像,首先提取出bmp的头部信息,存储在bmp_header处,pixel_array_rgb为提取出的图像。   <2> messageQ_create( master )     h_receive_queue = MessageQ_create(MASTER_QUEUE_NAME, NULL); if (h_receive_queue == NULL) { printf("MessageQ_create failed " ); ret_val = -1; goto close_n_exit; } 这里创建的messageQ是用来接收从核发送过来的数据的。 <3> messageQ_open( slave ) 打开slave核创建的messageQ     for (j = 0; j < number_of_cores; j++) { do { i = MessageQ_open(slave_queue_name[j], &queue_id[j]); } while (i < 0); }   <4> 给每一个核分配相应的图片像素      rgb[i]指向每个核要处理图像数据的第一个像素  height[i]代表每一个核处理的高度,由于要进行sobel运算,因此每个核之间有重复的部分 slice_height = bmp_header.dib.image_height / number_of_cores;// H/8 rgb[0] = &(pixel_array_rgb[0]); height[0] = slice_height + guard_height; //第一个height只能重复下面的一行 for (i = 1; i < number_of_cores; i++) {     rgb[i] = pixel_array_rgb + ((i * slice_height * row_width) - (row_width * guard_height)); //指针指向每个核分配的像素的首地址     height[i] = slice_height + (2 * guard_height); //每个核单独处理的高度+上下重复的两行 } height[number_of_cores - 1] = slice_height + guard_height; //最后一个height只能重复上面的一行 <5> 对存储sobel数据的区域进行分配空间   对p_queue_msg->info.scratch_buf[0]进行分配空间 for (i = 0; i < number_of_cores; i++)     {         edge_size[i] = ROUNDUP((height[i] * row_width), MAX_CACHE_LINE);  //每一个核需要占用的空间的大小         edge[i] = (uint8_t *) Memory_alloc(0, edge_size[i], MAX_CACHE_LINE, NULL); //最后的边缘检测结果         if (!edge[i])         {             printf("mc_process_bmp: Memory_alloc failed for edge[%d] ", i);     ret_val = -1;     goto close_n_exit;         }         /* Allocate scratch buffers for slave processors */         p_queue_msg[i]->info.scratch_buf[0] =              (uint8_t *) Memory_alloc(0, ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE), MAX_CACHE_LINE, NULL);         if(!p_queue_msg[i]->info.scratch_buf[0])         {             printf("mc_process_bmp: Memory_alloc failed for scratch_buf[%d][0] ", i);     ret_val = -1;     goto close_n_exit;         }         p_queue_msg[i]->info.scratch_buf_len[0] = ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE);         if ((p_color_table) || (bmp_header.dib.bits_per_pixel != 8))         {             p_queue_msg[i]->info.scratch_buf[1] =                  (uint8_t *) Memory_alloc(0, ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE), MAX_CACHE_LINE, NULL);             if(!p_queue_msg[i]->info.scratch_buf[1])             {                 printf("mc_process_bmp: Memory_alloc failed for scratch_buf[%d][1] ", i);         ret_val = -1;         goto close_n_exit;             }             p_queue_msg[i]->info.scratch_buf_len[1] = ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE);         }     } ret_val = -1;     goto close_n_exit;         }         /* Allocate scratch buffers for slave processors */         p_queue_msg[i]->info.scratch_buf[0] =              (uint8_t *) Memory_alloc(0, ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE), MAX_CACHE_LINE, NULL);         if(!p_queue_msg[i]->info.scratch_buf[0])         {             printf("mc_process_bmp: Memory_alloc failed for scratch_buf[%d][0] ", i);     ret_val = -1;     goto close_n_exit;         }         p_queue_msg[i]->info.scratch_buf_len[0] = ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE);         if ((p_color_table) || (bmp_header.dib.bits_per_pixel != 8))         {             p_queue_msg[i]->info.scratch_buf[1] =                  (uint8_t *) Memory_alloc(0, ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE), MAX_CACHE_LINE, NULL);             if(!p_queue_msg[i]->info.scratch_buf[1])             {                 printf("mc_process_bmp: Memory_alloc failed for scratch_buf[%d][1] ", i);         ret_val = -1;         goto close_n_exit;             }             p_queue_msg[i]->info.scratch_buf_len[1] = ROUNDUP(bmp_header.dib.image_width * height[i], MAX_CACHE_LINE);         }     } 这里必须进行分配空间 因为msg的信息中需要传递这些数据的指针。 <6> 构建messageQ的msg结构体   <7> 将messageQ放入队列   发送messageQ( slave )     for (i = number_of_cores-1; i >= 0; i-- )     { p_msg = p_queue_msg[i]; p_msg->core_id = i; p_msg->info.processing_type = edge_detection; p_msg->info.bitspp = bmp_header.dib.bits_per_pixel; p_msg->info.p_color_table = (color_table_t*) p_color_table; p_msg->info.width = bmp_header.dib.image_width; p_msg->info.height = height[i]; p_msg->info.rgb_in = rgb[i]; p_msg->info.out = edge[i]; p_msg->info.flag = 0; MessageQ_setMsgId(p_msg, ++msgId); //将message插入队列 MessageQ_setReplyQueue(h_receive_queue, (MessageQ_Msg)p_msg); //MessageQ_open /* send the message to the remote processor */ if (MessageQ_put(queue_id[i], (MessageQ_Msg)p_msg) < 0) { printf("MessageQ_put had a failure error ");     ret_val = -1;     goto close_n_exit; }     } 这里的发送  对应的是第三步的打开slave messageQ <8> 等待8个核的处理结果  messageQ_get(master)     for (i = 0; i < number_of_cores; i++) { if (MessageQ_get(h_receive_queue, (MessageQ_Msg *)&p_msg, MessageQ_FOREVER) < 0) { printf("This should not happen since timeout is forever "); ret_val = -1; } else if (p_msg->info.flag != 0) { printf("Process image error received from core %d ", i); ret_val = -1; } } <9>融合图像,输出 处理完的结果通过messageQ传递给主核,传递过来的是sobel的地址参数。 pixel_array_edge_size = bmp_header.dib.image_width * bmp_header.dib.image_height;     pixel_array_edge = (uint8_t *) Memory_alloc(0, pixel_array_edge_size, 0, NULL);     if (!pixel_array_edge) { printf("Can't allocate memory for pixel_array_edge "); ret_val = -1; goto close_n_exit; }     memcpy(&(pixel_array_edge[0]), &(edge[0][0]), slice_height * bmp_header.dib.image_width); if (number_of_cores > 1) { for (i = 1; i < number_of_cores; i++) { Cache_inv(edge[i], (p_msg->info.height * p_msg->info.width), Cache_Type_ALL, FALSE); memcpy(pixel_array_edge + (i * slice_height * bmp_header.dib.image_width), edge[i] + (bmp_header.dib.image_width * guard_height), slice_height * bmp_header.dib.image_width); } } p_output_image->length = bmp_get_gray_bmpfile_size(bmp_header.dib.image_width, bmp_header.dib.image_height); p_output_image->data = (uint8_t *) Memory_alloc(0, p_output_image->length, 0, NULL); if (!p_output_image->data) { p_output_image->length = 0; printf("Can't allocate memory for output bmp image "); ret_val = -1; goto close_n_exit; }     /* Create (Gray Scale) Image */     if (bmp_write_gray_bmpfile (p_output_image, pixel_array_edge, bmp_header.dib.image_width, bmp_header.dib.image_height) < 0)     { printf("Error in bmp_write_gray_bmpfile "); ret_val = -1; goto close_n_exit;     } 融合各个核的处理结果
1  edge => pixel_array_edge
2  pixel_array_edge => p_output_image
3     填充p_output_image结构体   3.3 Mailbox_post( ) 数据处理完毕之后  post邮箱   接到post信号之后TCP向上位机传送数据 if (Mailbox_post(master_mbox_send, &response_msg, BIOS_WAIT_FOREVER) == FALSE) { System_printf("main: Mailbox_post returns error "); return; } 程序下载地址 https://download.csdn.net/download/yunge812/10517028   ======================================================================= 最近新开的公众号,文章正在一篇篇的更新, 公众号名称:玩转电子世界 各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。 跟着阳光非宅男,一步步走进电子的世界。 关注之后回复  资料下载  关键词可以获得免费海量视频学习资料下载~~! 已共享的学习视频资料,共享资料正在不断更新中。。。 =======================================================================