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 156
allocate memory at 0x2001008c, size: 168
malloc size 296
allocate memory at 0x20010134, size: 308
malloc size 32
allocate memory at 0x20010268, size: 44
malloc size 48
allocate memory at 0x20010294, size: 60
malloc size 2856
allocate memory at 0x200102d0, size: 2868
malloc size 52
allocate memory at 0x20010e04, size: 64
allocate memory at 0x20010e04, size: 64
malloc size 16
allocate memory at 0x20010e44, size: 28
malloc size 20
allocate memory at 0x20011388, size: 32
malloc size 60
allocate memory at 0x200113a8, size: 72
release memory 0x20011388, size: 32
malloc size 140
allocate memory at 0x200113f0, size: 152
release memory 0x200113a8, size: 72
malloc size 300
allocate memory at 0x20011488, size: 312
release memory 0x200113f0, size: 152
malloc size 620
allocate memory at 0x200115c0, size: 632
release memory 0x20011488, size: 312
malloc size 1260
allocate memory at 0x20011838, size: 1272
release memory 0x200115c0, size: 632
malloc size 2540
allocate memory at 0x20011d30, size: 2552
release memory 0x20011838, size: 1272
malloc size 20
allocate memory at 0x20011388, size: 32
malloc size 60
allocate memory at 0x200113a8, size: 72
release memory 0x20011388, size: 32
malloc size 140
allocate memory at 0x200113f0, size: 152
release memory 0x200113a8, size: 72
malloc size 300
allocate memory at 0x20011488, size: 312
release memory 0x200113f0, size: 152
malloc size 620
allocate memory at 0x200115c0, size: 632
release memory 0x20011488, size: 312
malloc size 1260
allocate memory at 0x20011838, size: 1272
release memory 0x200115c0, size: 632
malloc size 2540
allocate memory at 0x20012728, size: 2552
release memory 0x20011838, size: 1272
malloc size 352
allocate memory at 0x20011388, size: 364
malloc size 352
allocate memory at 0x200114f4, size: 364
malloc size 88
allocate memory at 0x20011660, size: 100
release memory 0x20011660, size: 100
malloc size 440
allocate memory at 0x20011660, size: 452
malloc size 440
allocate memory at 0x20011824, size: 452
malloc size 110, but align to 112
allocate memory at 0x200119e8, size: 124
release memory 0x200119e8, size: 124
malloc size 5792
allocate memory at 0x20013120, size: 5804
malloc size 80
allocate memory at 0x200119e8, size: 92
malloc size 20
allocate memory at 0x20011a44, size: 32
malloc size 32
allocate memory at 0x20011a64, size: 44
malloc size 5, but align to 8
allocate memory at 0x20011a90, size: 24
malloc size 8
allocate memory at 0x20011aa8, size: 24
release memory 0x20011aa8, size: 24
release memory 0x20011a90, size: 24
release memory 0x20011a64, size: 44
release memory 0x20011a44, size: 32
release memory 0x20011824, size: 452
release memory 0x20011660, size: 452
release memory 0x200114f4, size: 364
release memory 0x20011388, size: 364
malloc size 57600
allocate memory at 0x200147cc, size: 57612
malloc size 960
allocate memory at 0x20011388, size: 972
release memory 0x20011388, size: 972
malloc size 3, but align to 4
allocate memory at 0x20011388, size: 24
malloc size 360
allocate memory at 0x200113a0, size: 372
release memory 0x200113a0, size: 372
malloc size 360
allocate memory at 0x200113a0, size: 372
release memory 0x200113a0, size: 372
malloc size 176
allocate memory at 0x200113a0, size: 188
release memory 0x200113a0, size: 188
malloc size 176
allocate memory at 0x200113a0, size: 188
release memory 0x200113a0, size: 188
malloc size 552
allocate memory at 0x200113a0, size: 564
malloc size 552
allocate memory at 0x200115d4, size: 564
release memory 0x200113a0, size: 564
release memory 0x200115d4, size: 564
malloc size 52
allocate memory at 0x200113a0, size: 64
allocate memory at 0x200113a0, size: 64
malloc size 116
allocate memory at 0x200113e0, size: 128
malloc size 32 allocate memory at 0x20011460, size: 44
malloc size 32
allocate memory at 0x2001148c, size: 44
release memory 0x20011460, size: 44
release memory 0x2001148c, size: 44
malloc size 116
allocate memory at 0x20011460, size: 128
malloc size 8
allocate memory at 0x200114e0, size: 24
malloc size 70, but align to 72
allocate memory at 0x200114f8, size: 84
release memory 0x200113e0, size: 128
release memory 0x200113a0, size: 64
release memory 0x200114e0, size: 24
release memory 0x20011460, size: 128
malloc size 12
allocate memory at 0x200113a0, size: 24
malloc size 15, but align to 16
allocate memory at 0x200113b8, size: 28
release memory 0x200114f8, size: 84
malloc size 48
allocate memory at 0x200113d4, size: 60
release memory 0x20011388, size: 24
malloc size 4
allocate memory at 0x20011388, size: 24
malloc size 1, but align to 4
allocate memory at 0x20011410, size: 24
malloc size 31, but align to 32
allocate memory at 0x20011428, size: 44
malloc size 52
allocate memory at 0x20011454, size: 64
allocate memory at 0x20011454, size: 64
malloc size 8
allocate memory at 0x20011494, size: 24
malloc size 16
allocate memory at 0x200114ac, size: 28
release memory 0x20011494, size: 24
malloc size 24
allocate memory at 0x200114c8, size: 36
release memory 0x200114ac, size: 28
malloc size 32
allocate memory at 0x20011494, size: 52
release memory 0x200114c8, size: 36
malloc size 16
allocate memory at 0x200114c8, size: 28
release memory 0x20011428, size: 44
release memory 0x20011410, size: 24
release memory 0x200113b8, size: 28
release memory 0x200113a0, size: 24
release memory 0x200113d4, size: 60
release memory 0x200147cc, size: 57612
release memory 0x200119e8, size: 92
release memory 0x20013120, size: 5804
n = 1 decoded QR-Code symbol "EEWorld STM32H5"
len = 15
release memory 0x20010e04, size: 64
release memory 0x20011494, size: 52
release memory 0x200114c8, size: 28
release memory 0x20011454, size: 64
release memory 0x20010e44, size: 28
release memory 0x20010294, size: 60
release memory 0x20010268, size: 44
release memory 0x20010134, size: 308
release memory 0x20011d30, size: 2552
release memory 0x20012728, size: 2552
release memory 0x200102d0, size: 2868
release memory 0x2001008c, size: 168
45 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<qr_img_width;i++)
{
for(j=0;j<qr_img_width;j++) //将RGB565图片转成灰度
{ Color = (*pic_rgb) | (*(pic_rgb+1)<<8);
*pic_hd = (((Color&0xF800)>> 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 = 15
45 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok
zbar count;4290
n = 1 decoded QR-Code symbol "EEWorld STM32H5"
len = 15
45 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok
zbar count;4291
n = 1 decoded QR-Code symbol "EEWorld STM32H5"
len = 15
45 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok
zbar count;4292
n = 1 decoded QR-Code symbol "EEWorld STM32H5"
len = 15
45 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok
zbar count;4293
n = 1 decoded QR-Code symbol "EEWorld STM32H5"
len = 15
45 45 57 6F 72 6C 64 20 53 54 4D 33 32 48 35 zbar ok
zbar count;4294

 

STM32H5移植zbar记录的更多相关文章

  1. 【linux】linux内核移植错误记录

       欢迎转载,转载时请保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http ...

  2. linux移植问题记录

    问题一 ~/linux/linux-5.2.8$ make s3c2410_defconfig  HOSTCC  scripts/basic/fixdep/bin/sh: 1: scripts/bas ...

  3. 【转】(笔记)CANopen协议【CANFestival】移植方法

    一.背景 CAN组网就必须得要应用层协议,原因就在于 * 便于网络管理与控制 * 确认数据的收发 * 发送大于8个字节的数据块(CAN每帧数据传输大小为8字节) * 为不同节点分配不同的报文标识符 * ...

  4. MIPS平台移植apache 2.2.7

    参考文章: http://wenku.baidu.com/view/94e08a20a5e9856a561260e2.html http://httpd.apache.org/docs/2.4/ins ...

  5. 移植u-boot-2012.04.01到JZ2440

    开发环境:Ubuntu 12.04 开发板:JZ2440  256M NandFlash  64M SDRAM 交叉编译器:arm-linux-gcc-4.3.2 u-boot:u-boot-2012 ...

  6. nRF52832 SDK15.3.0 基于ble_app_uart demo FreeRTOS移植

    参考资料:https://blog.csdn.net/u010860832/article/details/86235993 这里把移植经验记录下来,供有需要的同学参考,有不对的地方也请大家批评指正. ...

  7. perf 移植

    perf 移植 perf工具用于系统性能的调优,程序优化.源码在kenel/tools/perf目录. 我在imx6平台上进行移植.将自己的移植过程记录如下. 参考链接 http://blog.csd ...

  8. Zbar和Z*算法对比

    博客转载自:https://blog.csdn.net/qishandaxue/article/details/45481387 移植zbar和zxing源码到linux平台,zbar移植的是C源码, ...

  9. EntityFramework 优化建议

    Entity Framework目前最新版本是6.1.3,当然Entity Framework 7 目前还是预览版,并不能投入正式生产环境,估计正式版16年第一季度会出来,了解过EF7的部分新特性后, ...

  10. C#实用杂记-EF全性能优化技巧

    原文链接:http://www.makmong.com/947.html#comment-31 EntityFramework 优化建议 2016年1月15日 下午4:54 LEILINKANG   ...

随机推荐

  1. 计算机网络中各种报文、HEADER的读法

    计算机里到处都是格式,规范.比如<操作系统真象还原>里提到的"魔数" 直接出现的一个数字,只要其意义不明确,感觉很诡异,就称之为魔数. 拿elf文件头举例 ELF He ...

  2. Redis 故障排查

    系统性学习,移步IT-BLOG 要进行 Redis 的故障定位,一般通过分析 Redis 日志.应用日志和 Redis 的监控信息来定位相关问题. 一.Redis 日志设置 [1]日志文件:Redis ...

  3. H5 visibilityChange事件 --- 监听页面的显示或者隐藏 新开一个webview

    mounted() { document.addEventListener('visibilityChange', 事件处理函数) }, destoryed() { document.removeEv ...

  4. VUE2.x原理之Object.defineProperty()

    Object.defineProperty()语法说明 Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性 Object.defineP ...

  5. JS中我们为什么要new个实例而不直接执行

    正常情况:<script> function sayHello() { alert("hello") } sayHello();直接调用他 </script> ...

  6. 关于Docker compose值IP与域名的映射 之 extra_host

    公司的所有项目都是采用Docker容器化部署,最近有一个项目需要使用定时任务调用第三方Api,正式web环境服务器的网络与第三方网络是通畅的,但是当将代码发布到正式环境,调用接口却显示 System. ...

  7. Flutter 下载篇 - 叁 | 网络库切换实践与思考

    前言 本文是关于使用flutter_download_manager下载功能的实践和探索.我们将基于flutter_download_manager的功能扩展,改造成自己想要的样子.在阅读本文之前,建 ...

  8. MATLAB计算变异函数并绘制经验半方差图

      本文介绍基于MATLAB求取空间数据的变异函数,并绘制经验半方差图的方法.   由于本文所用的数据并不是我的,因此遗憾不能将数据一并展示给大家:但是依据本篇博客的思想与对代码的详细解释,大家用自己 ...

  9. [IDE]IntelliJ IDEA 不能识别 Java 项目 [转]

    本文转载自 IntelliJ IDEA 不能识别 Java 项目 - 博客园/SmartJuneThx 解决方法 非maven项目 在 src 目录上点右键,选择 Mark Directory As ...

  10. Django笔记十九之manager用法介绍

    本文首发于微信公众号:Hunter后端 原文链接:Django笔记十九之manager用法介绍 首先介绍一下 manager 的使用场景,比如我们有一些表级别的,需要重复使用的功能,都可以使用 man ...