您的当前位置:首页 > 市场 > 正文

世界即时:STM32H5移植zbar记录

  • 2023-05-25 19:32:27 来源:博客园

ZBar是一种流行的二维码扫描和解码工具,它在嵌入式系统中拥有广泛的应用。在嵌入式系统中,我们面临着有限的资源和更严格的性能要求,因此,选择适当的库来完成特定的任务非常重要。 ZBar适用于各种嵌入式平台,包括ARM、x86和MIPS等处理器架构。它可以轻松地整合到各种嵌入式系统中,如智能家居设备、智能手机、平板电脑、远程控制设备、工业控制器等。 ZBar使用C/C++编写,具有高度优化的算法,能够快速准确地读取各种二维码和条形码,包括QR码、Data Matrix码、PDF417码、EAN-13码等等。同时,ZBar还支持自定义解码器,开发者可以根据自己的需求配置扫描器以实现更好的解码效果。 ZBar还具有非常灵活的API,可用于C/C++、Python、Java、Ruby等语言,开发人员可以根据自己的需求灵活选择相应的API。此外,ZBar还支持多种操作系统和平台,包括Linux、Windows、Mac OS X等。 总之,ZBar是一种非常有用的嵌入式二维码和条形码扫描库,它提供了高效的解码算法、可定制的解码器和灵活的API,能够轻松地满足嵌入式设备的扫描和解码需求。


(资料图片仅供参考)

这里感谢之前大佬移植zbar库到stm32,具体链接如下:https://www.cnblogs.com/greyorbit/p/8456814.html

移植步骤也很简单,按照博文把对应文件和头文件路径加入到工程中,然后使用图片数组转成灰度数据,在调用zbar既可以识别。

不过移植后会有一个问题,不能重复调用识别二维码,很容易内存就崩了。为了解决这个问题,让这个zbar库可以真正的用起来,不得不找到问题所在。

这里直观的看就是内存问题,奈何如果从源码直接去查找malloc和free的匹配所需时间太大,只能动态调试查找原因,所以第一步,我移植了rt-thread系统,使用rt的内存管理api。

移植rt-thread很方便,现在stm32代码生成工具cubemx可以直接添加rt-thread库,所以移植rt-thread系统很快。具体如下图:

移植完rt-thread后,就需要把zbar库中用到的malloc、calloc、free等操作函数换成 rt-malloc、rt-calloc、rt-free等,直接用全局搜索和替换。

替换后打开rt的内存调试功能宏定义:在rtdebug.h文件中

更改后既可以看到打印内存申请和释放日志,以下为日志打印内容

malloc size 156allocate memory at 0x2001008c, size: 168malloc size 296allocate memory at 0x20010134, size: 308malloc size 32allocate memory at 0x20010268, size: 44malloc size 48allocate memory at 0x20010294, size: 60malloc size 2856allocate memory at 0x200102d0, size: 2868malloc size 52allocate memory at 0x20010e04, size: 64allocate memory at 0x20010e04, size: 64malloc size 16allocate memory at 0x20010e44, size: 28malloc size 20allocate memory at 0x20011388, size: 32malloc size 60allocate memory at 0x200113a8, size: 72release memory 0x20011388, size: 32malloc size 140allocate memory at 0x200113f0, size: 152release memory 0x200113a8, size: 72malloc size 300allocate memory at 0x20011488, size: 312release memory 0x200113f0, size: 152malloc size 620allocate memory at 0x200115c0, size: 632release memory 0x20011488, size: 312malloc size 1260allocate memory at 0x20011838, size: 1272release memory 0x200115c0, size: 632malloc size 2540allocate memory at 0x20011d30, size: 2552release memory 0x20011838, size: 1272malloc size 20allocate memory at 0x20011388, size: 32malloc size 60allocate memory at 0x200113a8, size: 72release memory 0x20011388, size: 32malloc size 140allocate memory at 0x200113f0, size: 152release memory 0x200113a8, size: 72malloc size 300allocate memory at 0x20011488, size: 312release memory 0x200113f0, size: 152malloc size 620allocate memory at 0x200115c0, size: 632release memory 0x20011488, size: 312malloc size 1260allocate memory at 0x20011838, size: 1272release memory 0x200115c0, size: 632malloc size 2540allocate memory at 0x20012728, size: 2552release memory 0x20011838, size: 1272malloc size 352allocate memory at 0x20011388, size: 364malloc size 352allocate memory at 0x200114f4, size: 364malloc size 88allocate memory at 0x20011660, size: 100release memory 0x20011660, size: 100malloc size 440allocate memory at 0x20011660, size: 452malloc size 440allocate memory at 0x20011824, size: 452malloc size 110, but align to 112allocate memory at 0x200119e8, size: 124release memory 0x200119e8, size: 124malloc size 5792allocate memory at 0x20013120, size: 5804malloc size 80allocate memory at 0x200119e8, size: 92malloc size 20allocate memory at 0x20011a44, size: 32malloc size 32allocate memory at 0x20011a64, size: 44malloc size 5, but align to 8allocate memory at 0x20011a90, size: 24malloc size 8allocate memory at 0x20011aa8, size: 24release memory 0x20011aa8, size: 24release memory 0x20011a90, size: 24release memory 0x20011a64, size: 44release memory 0x20011a44, size: 32release memory 0x20011824, size: 452release memory 0x20011660, size: 452release memory 0x200114f4, size: 364release memory 0x20011388, size: 364malloc size 57600allocate memory at 0x200147cc, size: 57612malloc size 960allocate memory at 0x20011388, size: 972release memory 0x20011388, size: 972malloc size 3, but align to 4allocate memory at 0x20011388, size: 24malloc size 360allocate memory at 0x200113a0, size: 372release memory 0x200113a0, size: 372malloc size 360allocate memory at 0x200113a0, size: 372release memory 0x200113a0, size: 372malloc size 176allocate memory at 0x200113a0, size: 188release memory 0x200113a0, size: 188malloc size 176allocate memory at 0x200113a0, size: 188release memory 0x200113a0, size: 188malloc size 552allocate memory at 0x200113a0, size: 564malloc size 552allocate memory at 0x200115d4, size: 564release memory 0x200113a0, size: 564release memory 0x200115d4, size: 564malloc size 52allocate memory at 0x200113a0, size: 64allocate memory at 0x200113a0, size: 64malloc size 116allocate memory at 0x200113e0, size: 128malloc size 32allocate memory at 0x20011460, size: 44malloc size 32allocate memory at 0x2001148c, size: 44release memory 0x20011460, size: 44release memory 0x2001148c, size: 44malloc size 116allocate memory at 0x20011460, size: 128malloc size 8allocate memory at 0x200114e0, size: 24malloc size 70, but align to 72allocate memory at 0x200114f8, size: 84release memory 0x200113e0, size: 128release memory 0x200113a0, size: 64release memory 0x200114e0, size: 24release memory 0x20011460, size: 128malloc size 12allocate memory at 0x200113a0, size: 24malloc size 15, but align to 16allocate memory at 0x200113b8, size: 28release memory 0x200114f8, size: 84malloc size 48allocate memory at 0x200113d4, size: 60release memory 0x20011388, size: 24malloc size 4allocate memory at 0x20011388, size: 24malloc size 1, but align to 4allocate memory at 0x20011410, size: 24malloc size 31, but align to 32allocate memory at 0x20011428, size: 44malloc size 52allocate memory at 0x20011454, size: 64allocate memory at 0x20011454, size: 64malloc size 8allocate memory at 0x20011494, size: 24malloc size 16allocate memory at 0x200114ac, size: 28release memory 0x20011494, size: 24malloc size 24allocate memory at 0x200114c8, size: 36release memory 0x200114ac, size: 28malloc size 32allocate memory at 0x20011494, size: 52release memory 0x200114c8, size: 36malloc size 16allocate memory at 0x200114c8, size: 28release memory 0x20011428, size: 44release memory 0x20011410, size: 24release memory 0x200113b8, size: 28release memory 0x200113a0, size: 24release memory 0x200113d4, size: 60release memory 0x200147cc, size: 57612release memory 0x200119e8, size: 92release memory 0x20013120, size: 5804n = 1decoded QR-Code symbol "EEWorld STM32H5"len = 15release memory 0x20010e04, size: 64release memory 0x20011494, size: 52release memory 0x200114c8, size: 28release memory 0x20011454, size: 64release memory 0x20010e44, size: 28release memory 0x20010294, size: 60release memory 0x20010268, size: 44release memory 0x20010134, size: 308release memory 0x20011d30, size: 2552release memory 0x20012728, size: 2552release memory 0x200102d0, size: 2868release memory 0x2001008c, size: 16845 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok zbar count;56

通过对申请和释放的对应关系,我们可以分析得出问题所在,zbar库在图片识别后释放了img->data指针,而这个指针是在zbar调用外部申请的空间,是不需要zbar内部释放的,具体代码如下:

int main(void){  /* USER CODE BEGIN 1 */    uint8_t test[]="start test\n";    uint16_t i,j;    int qr_img_width = 240;        uint16_t Color;    uint16_t cnt = 0;        unsigned char *pic_rgb = (unsigned char *)gImage_test;    unsigned char *pic_hd = NULL;unsigned char *pic_data = NULL;        void * ptr_start;  /* USER CODE END 1 */  /* MCU Configuration--------------------------------------------------------*/  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  //HAL_Init();  /* USER CODE BEGIN Init */  /* USER CODE END Init */  /* Configure the system clock */  //SystemClock_Config();  /* USER CODE BEGIN SysInit */  /* USER CODE END SysInit */  /* Initialize all configured peripherals */  MX_GPIO_Init();  MX_ADC1_Init();  MX_ETH_Init();  MX_ICACHE_Init();  MX_LPUART1_UART_Init();  //MX_USART3_UART_Init();  MX_UCPD1_Init();  MX_USB_PCD_Init();  /* USER CODE BEGIN 2 */  pic_data = rt_malloc(qr_img_width*qr_img_width);  if(pic_data == NULL)  {      printf("malloc error\n");      return 0;  }  else  {      printf("pic_data:0x%x\n",pic_data);  }    //memset(pic_data,0,qr_img_width*qr_img_width);     pic_hd = pic_data;    for(i=0;i> 8)*77+((Color&0x7E0)>>3)*150+((Color&0x001F)<<3)*29)/256;            pic_hd++;            pic_rgb++;            pic_rgb++;                 }    }    /* USER CODE END 2 */    /* Infinite loop */  /* USER CODE BEGIN WHILE */    while (1)  {    /* USER CODE END WHILE */    /* USER CODE BEGIN 3 */                  if( Zbar_Test((void* )pic_data,qr_img_width,qr_img_width) == 0 )      {          printf("zbar failed \n");          //rt_free(pic_data);      }      else      {          cnt ++;          printf("zbar ok \n");          //rt_free(pic_data);      }      printf("zbar count;%d\n",cnt);      //list_thread();      rt_thread_mdelay(5000);        }  rt_free(pic_data);  /* USER CODE END 3 */}

即pic_data灰度图片数据是不需要zbar释放的,但是zbar库中做了释放操作,代码如下:

inline void zbar_image_rt_free_data (zbar_image_t *img){    if(!img)        return;    if(img->src) {        /* replace video image w/new copy */        assert(img->refcnt); /* FIXME needs lock */        zbar_image_t *newimg = zbar_image_create();        memcpy(newimg, img, sizeof(zbar_image_t));        /* recycle video image */        newimg->cleanup(newimg);        /* detach old image from src */        img->cleanup = NULL;        img->src = NULL;        img->srcidx = -1;    }    else if(img->cleanup && img->data) {        if(img->cleanup != zbar_image_rt_free_data) {            /* using function address to detect this case is a bad idea;             * windows link libraries add an extra layer of indirection...             * this works around that problem (bug #2796277)             */            zbar_image_cleanup_handler_t *cleanup = img->cleanup;            img->cleanup = zbar_image_rt_free_data;            cleanup(img);        }//传入图片为外部指针,zbar内部不用free此指针//        else//            rt_free((void*)img->data);    }    img->data = NULL;}

这里把这一句屏蔽,则可以解决问题,经过我测试,现在已经连续运行上千次

decoded QR-Code symbol "EEWorld STM32H5"len = 1545 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok zbar count;4290n = 1decoded QR-Code symbol "EEWorld STM32H5"len = 1545 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok zbar count;4291n = 1decoded QR-Code symbol "EEWorld STM32H5"len = 1545 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok zbar count;4292n = 1decoded QR-Code symbol "EEWorld STM32H5"len = 1545 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok zbar count;4293n = 1decoded QR-Code symbol "EEWorld STM32H5"len = 1545 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok zbar count;4294

标签:

推荐阅读

世界即时:STM32H5移植zbar记录

ZBar是一种流行的二维码扫描和解码工具,它在嵌入式系统中拥有广泛的应用。在嵌入式系统中,我们面临着有限

无需首付还能倒拿50万装修款……“负首付”买房靠谱吗?

专家指出,“零首付”购房也好,房贷转经营贷也罢,这只是换汤不换药,本质都是违规套取、使用信贷资金。

“绿丝带”皮肤公益救助行动暨量肤定制项目启动会将于5月26日开启_天天即时看

据《2021中国女性皮肤健康调查报告》显示,只有不到三分之一的女性对自己的皮肤状况感到满意,而7 3%的女性对

【AI智能医疗器械创新合作平台成果巡礼】积极构建智能化医疗器械技术测评体系_全球热文

测评技术研究工作组测评技术研究工作组由中国信息通信研究院牵头组建,并作为组长单位组织开展人工智能医疗

市关工委调研组来丰调研:为少年儿童健康成长营造良好的学习生活环境

5月23日,市关工委常务副主任于学信率调研组来丰调研关心下一代工作,并开展“六一”慰问优秀儿童之家活...

猜您喜欢

【版权及免责声明】凡注明"转载来源"的作品,均转载自其它媒体,转载目的在于传递更多的信息,并不代表本网赞同其观点和对其真实性负责。亚洲商业网倡导尊重与保护知识产权,如发现本站文章存在内容、版权或其它问题,烦请联系。 联系方式:8 86 239 5@qq.com,我们将及时沟通与处理。

宏观