前兩篇文章已經實現ZBar在Windows平臺下的編譯和使用,本文將介紹如何把ZBar移植到STM32F429,IDE使用MDK。php
(1)不勾選Use MicroLIB ,使用ISO C。
如MDK 幫助文檔關於MicroLIB的介紹,故在硬件資源容許的狀況仍是優先使用ISO C。數組
(2)勾選C99 Mode,由於ZBar源碼是基於C99的函數
(3)不勾選Use Memory Layout From Target Dialog,使用自定義Scatter File測試
因爲MDK使用的編譯器不是GCC,故不能支持一些特殊GCC語法和相應的C庫函數。
(1) error.c和error.h文件中strdup函數報錯。
處理方法:屏蔽該函數相關代碼或者本身實現strdup函數
(2) 屏蔽img_scanner.c文件中的ui
..... //#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指針
spa
對於STM32來講ZBar對Heap消耗較大,跟解析的二維碼圖片大小有關,將系統未使用的內存 所有分配給Heap。
Scatter file 以下3d
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 +0 EMPTY (0xD0800000 - ImageLimit(RW_ERAM)) ; Heap region growing up { } }
(1) Stack和Heap已經在Scatter文件中指定,故屏蔽startup_stm32f429_439xx.s中Stack和Heap的相關代碼。指針
;Stack_Size EQU 0x00000400 ;AREA STACK, NOINIT, READWRITE, ALIGN=3 ;Stack_Mem SPACE Stack_Size ;__initial_sp ;; <h> Heap Configuration ;; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> ;; </h> ;Heap_Size EQU 0x00000200 ;AREA HEAP, NOINIT, READWRITE, ALIGN=3 ;__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基地址賦給向量表的首地址code
..... IMPORT |Image$$ARM_LIB_STACK$$Base| __Vectors DCD |Image$$ARM_LIB_STACK$$Base|;__initial_sp ; Top of Stack .....
(3) 由於Heap分配在外部SDRAM中,故在進入__main前需初始化SDRAMorm
.... IMPORT SystemInit IMPORT SDRAM_Init IMPORT __main LDR R0, =SystemInit BLX R0 LDR R0, =SDRAM_Init BLX R0 LDR R0, =__main BX R0 ENDP ....
以前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, 0, ZBAR_CFG_ENABLE, 1); /* 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=0; k<strlen(data); k++) { printf("%X ", (uint8_t)data[k]); } } /* clean up */ zbar_image_destroy(image); zbar_image_scanner_destroy(scanner); return(0); } int main(void) { Usart_Init(); printf("Hello CJS\r\n "); Zbar_Test((void* )image_data_buf,280,280); while(1) { } return 0; }
編譯下載到STM32F429後,運行結果以下
到此,ZBar已經能正常在STM32F429上運行了,但有點小問題,如上圖,會檢測到decoded I2/5 symbol "",緣由未知。
工程傳送門:http://www.openedv.com/forum.php?mod=viewthread&tid=266510&page=1#pid828789