STM32H5移植zbar记录

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文件中

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

+ View Code

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

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库中做了释放操作,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

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;

}

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野生的狒狒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值