前两篇文章已经实现ZBar在Windows平台下的编译和使用,本文将介绍如何把ZBar移植到STM32F429,IDE使用MDK。

1. MDK工程设置

(1)不勾选Use MicroLIB ,使用ISO C。
如MDK 帮助文档关于MicroLIB的介绍,故在硬件资源允许的情况还是优先使用ISO C。

(2)勾选C99 Mode,因为ZBar源码是基于C99的

(3)不勾选Use Memory Layout From Target Dialog,使用自定义Scatter File

2.工程目录结构

3. ZBar源码修改地方

由于MDK使用的编译器不是GCC,故不能支持一些特殊GCC语法和相应的C库函数。
(1) error.c和error.h文件中strdup函数报错。
处理方法:屏蔽该函数相关代码或者自己实现strdup函数
(2) 屏蔽img_scanner.c文件中的

.....
//#include <unistd.h>
//#include <time.h> /* clock_gettime */
//#include <sys/time.h> /* gettimeofday */
....
// struct timeval abstime;
// gettimeofday(&abstime, NULL);
// iscn->time = (abstime.tv_sec * 1000) + ((abstime.tv_usec / 500) + 1) / 2;
.....

(3) GCC默认void*为char*,MDK的编译器对void指针的加减操作当作错误处理
处理方法:把void指针强制转换为char指针

4. 系统存储空间分配

对于STM32来说ZBar对Heap消耗较大,跟解析的二维码图片大小有关,将系统未使用的内存 全部分配给Heap。
Scatter file 如下

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
ER_IROM1 0x08000000 0x00100000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
} RW_IRAM_DATA 0x20000000 0x00030000 { ; RW data
.ANY (+RW +ZI)
} ARM_LIB_STACK 0x20030000 EMPTY -(0x20030000 - ImageLimit(RW_IRAM_DATA)) ; Stack region growing down
{ } RW_ERAM 0xD0000000 0x00800000 { ;Extern SDRAM
main.o(+RW +ZI)
} ARM_LIB_HEAP + EMPTY (0xD0800000 - ImageLimit(RW_ERAM)) ; Heap region growing up
{ }
}

5. 修改默认的启动文件startup_stm32f429_439xx.s

(1) Stack和Heap已经在Scatter文件中指定,故屏蔽startup_stm32f429_439xx.s中Stack和Heap的相关代码。

;Stack_Size      EQU     0x00000400

                ;AREA    STACK, NOINIT, READWRITE, ALIGN=
;Stack_Mem SPACE Stack_Size
;__initial_sp ;; <h> Heap Configuration
;; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:>
;; </h> ;Heap_Size EQU 0x00000200 ;AREA HEAP, NOINIT, READWRITE, ALIGN=
;__heap_base
;Heap_Mem SPACE Heap_Size
;__heap_limit ...... ;IF :DEF:__MICROLIB ;EXPORT __initial_sp
;EXPORT __heap_base
;EXPORT __heap_limit ;ELSE ;IMPORT __use_two_region_memory
;EXPORT __user_initial_stackheap ;__user_initial_stackheap ;LDR R0, = Heap_Mem
;LDR R1, =(Stack_Mem + Stack_Size)
;LDR R2, = (Heap_Mem + Heap_Size)
;LDR R3, = Stack_Mem
;BX LR ;ALIGN ;ENDIF

(2) 把Scatter文件指定的Stack基地址赋给向量表的首地址

.....
IMPORT |Image$$ARM_LIB_STACK$$Base|
__Vectors DCD |Image$$ARM_LIB_STACK$$Base|;__initial_sp ; Top of Stack
.....

(3) 因为Heap分配在外部SDRAM中,故在进入__main前需初始化SDRAM

....
IMPORT SystemInit
IMPORT SDRAM_Init
IMPORT __main LDR R0, =SystemInit
BLX R0
LDR R0, =SDRAM_Init
BLX R0
LDR R0, =__main
BX R0
ENDP
....

6.测试代码

  之前Windows平台下的测试例程是直接读取PNG格式的二维码,在STM32F429平台下没有移植文件系统和PNG解码库,为了简单起见,直接把待

测试的二维码图片转换为二值化数组,然后把该该数组传给ZBar。

#include "type_define.h"
#include "usart.h"
#include "sdram.h"
#include "zbar.h"
#include "image.h"
//280X280的二维码图片灰度值数组
const uint8_t image_data_buf[] = {
.......
};
int Zbar_Test(void* raw, int width, int height)
{
zbar_image_scanner_t *scanner = NULL;
/* create a reader */
scanner = zbar_image_scanner_create(); /* configure the reader */
zbar_image_scanner_set_config(scanner, , ZBAR_CFG_ENABLE, ); /* obtain image data */
//int width = 0, height = 0;
//void *raw = NULL;
//get_data("barcode.png", &width, &height, &raw); /* wrap image data */
zbar_image_t *image = zbar_image_create();
zbar_image_set_format(image, *(int*)"Y800");
zbar_image_set_size(image, width, height);
zbar_image_set_data(image, raw, width * height, zbar_image_free_data); /* scan the image for barcodes */
int n = zbar_scan_image(scanner, image);
printf("n = %d\r\n", n);
/* extract results */
const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
for(; symbol; symbol = zbar_symbol_next(symbol)) {
/* do something useful with results */
zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);
const char *data = zbar_symbol_get_data(symbol);
printf("decoded %s symbol \"%s\"\r\n",
zbar_get_symbol_name(typ), data);
printf("len = %d\r\n",strlen(data));
for(int k=; k<strlen(data); k++)
{
printf("%X ", (uint8_t)data[k]);
}
} /* clean up */
zbar_image_destroy(image);
zbar_image_scanner_destroy(scanner); return();
} int main(void)
{
Usart_Init();
printf("Hello CJS\r\n ");
Zbar_Test((void* )image_data_buf,,);
while()
{ }
  return ;
}

7.运行结果

编译下载到STM32F429后,运行结果如下

到此,ZBar已经能正常在STM32F429上运行了,但有点小问题,如上图,会检测到decoded I2/5 symbol "",原因未知。

工程传送门:http://www.openedv.com/forum.php?mod=viewthread&tid=266510&page=1#pid828789

二维码开源库ZBar-MDK STM32F429移植的更多相关文章

  1. 二维码开源库zbar、zxing使用心得

    首先说明我的测试场景是“识别打印在纸上的二维码”,在扫描结果中寻找二维码并进行识别,而不是直接让摄像头对着二维码扫描. zbar和zxing用的都是自己从github上clone的c++源码/接口编译 ...

  2. 二维码开源库ZBar-吐槽篇

    前不久在网上看到一篇文章<QR-Decoder-OV5640 二维码识别> ,是某开发板的教程.记得对应的开发板以前购买过,当初只是为了看OV5640的JPG的输出效果,结果由于公司奇葩的 ...

  3. 二维码开源库ZBar-实现中文解码

    中文乱码 上篇<ZBar-windows下编译和使用>已经成功解析了条形码,但目标是二维码,经测试二维码中文会出现乱码.下图二维码的内容是"http123测试456", ...

  4. 二维码开源库ZBar-windows下编译和使用

    源码 下载最新Zbar源码(http://zbar.sourceforge.net/),网站的WIKI是空白的,所以只能在源码包里找使用说明了,很遗憾Windows下怎么编译没说明,只是说明了Wind ...

  5. C++二维码相关库编译

    一.瞎想 坐在地铁上闲来无聊,突然想到了二维码,顺手就百度了下相关的资料,目前C++二维码相关的库不多,也就zbar(开源中国上下了半天也没下载下来).zxing,不过这两个库据说都是解析二维码的,不 ...

  6. 个性二维码开源专题<替换元素点>

    基础方法:ChangeFillShape //修改填充形状 ChangeFillShape(...) // 摘要: // 修改填充形状 // // 参数: // g: // 图形画板 // // Fo ...

  7. 个性二维码开源专题<替换定位点>

    基础方法: ChangeFillShape //修改填充形状 ChangeFillShape(...) // 摘要: // 修改填充形状 // // 参数: // g: // 图形画板 // // F ...

  8. 个性二维码开源专题<液化/圆角/效果>

    基础方法: ChangeFillShape //修改填充形状 ChangeFillShape(...) // 摘要: // 修改填充形状 // // 参数: // g: // 图形画板 // // F ...

  9. Android二维码开源项目zxing用例简化和生成二维码、条形码

    上一篇讲到:Android二维码开源项目zxing编译,编译出来后有一个自带的測试程序:CaptureActivity比較复杂,我仅仅要是把一些不用的东西去掉,用看起来更方便,二维码和条形码的流行性自 ...

随机推荐

  1. 使用 Gacutil.exe 将.Net程序集添加到GAC的方法

    使用gacutil.exe工具安装:gacutil -i "要注册的dll文件全路径" "gacutil.exe”工具为.NET自带工具 ,需要注意的是:这个工具在.NE ...

  2. Runtime之NSCoding的自动归档、接档

    为什么要有Runtime的NSCoding的自动归档.接档 大家所熟知的方法 //归档方法 - (void)encodeWithCoder:(NSCoder *)aCoder { //当学生被归档,学 ...

  3. 【转载备忘】PowerDesigner16.5基本使用

    这两天都在设计数据库,使用了powerdesigner进行设计的,然后摸索了好久,本来打算写一篇文章来记述一下的,写了一半,突然发现网上早就有比我写的好的文章了,所有删了之前写的,直接贴出来那个文章的 ...

  4. 【开发技术】eclipse中格式化代码快捷键Ctrl+Shift+F失效的解决办法

    要格式化代码的时候,右键-source-format能够起效,但ctrl+shift+f不好使了. 原来是和“简繁体快捷键”冲突了.输入法中的这个快捷键我们一般不用,小勾勾去掉就成了. eclipse ...

  5. Codeforces 437 D. The Child and Zoo 并查集

    题目链接:D. The Child and Zoo 题意: 题意比较难懂,是指给出n个点并给出这些点的权值,再给出m条边.每条边的权值为该条路连接的两个区中权值较小的一个.如果两个区没有直接连接,那么 ...

  6. TCP socket 多线程 并发服务器(发送)与客户端(接收)

    实现功能:Ubuntu上通过多线程实现服务器并发给客户端发送文件,携带包头,根据包头信息命名新文件.适用于短连接. 问题小结: 01. 调用嵌套在结构体中的结构体char 数组成员时,需要动态分配内存 ...

  7. python_协程方式操作数据库

    # !/usr/bin/python3 # -*- coding: utf-8 -*- import requests import gevent import pymysql from gevent ...

  8. python_爬校花图片

    如何用python爬取校花图片并保存到本地来? 1. 获取什么数据? 校花名字  name 校花所在学校 school 校花图片的url   img_ulr 2.如何获取? 打开网页http://ww ...

  9. Linux实践篇--自动删除n天前日志

    原文出处:http://www.cnblogs.com/peida/archive/2013/03/25/2980121.html linux是一个很能自动产生文件的系统,日志.邮件.备份等.虽然现在 ...

  10. Event Sourcing pattern

    Event Sourcing pattern Instead of storing just the current state of the data in a domain, use an app ...