当前位置:首页 > 芯闻号 > 充电吧
[导读]摘要:        首先TI当年出的这个linux gateway是用于智能家居的,用于适配AM335x,同时加速开发进度的,但是不是所有人都用AM335x平台,还有用MTK、展讯等其他平台,所以这

摘要:        首先TI当年出的这个linux gateway是用于智能家居的,用于适配AM335x,同时加速开发进度的,但是不是所有人都用AM335x平台,还有用MTK、展讯等其他平台,所以这里面很多代码要做移植修改。

        在2016.12月之前,TI针对Z-stack for linux gateway的源代码只做部分开放,链接地址:http://www.ti.com.cn/tool/cn/z-stack-archive地址下载到的安装包名字叫做Z-Stack_Linux_Gateway_1_0_1_installer.run ,在多次和TI沟通协调下,TI刚刚决定开放全部源代码,不再需要SLA协议,所以同样的下载地址,下载到的安装包名字已经为Z-Stack_Linux_Gateway-1_0_1-src-linux-installer.run        使用非源代码安装包 Z-Stack_Linux_Gateway_1_0_1_installer.run安装后路径为/opt/Z-Stack_Linux_Gateway-1.0.1        使用源代码安装包 Z-Stack_Linux_Gateway-1_0_1-src-linux-installer.run安装后路径为/opt/Z-Stack_Linux_Gateway-1.0.1-src


1、首先在TI网站下载到的Z-Stack_Linux_Gateway-1_0_1-src-linux-installer.run


2、在ubuntu下安装以后,注意一定要安装在默认目录下,否则可能会有权限问题导致部分代码安装不上,默认目录为/opt/

3、目录结构大概如下:


4、之前TI E2E论坛上有人在问Precompiled_arm目录下的压缩包里面的那些程序是怎么编译出来的,没找到相应的源代码呢?因为当时没有开放全部源码!

5、其实Z-stack安装包里面自带的这些Precompiled_arm是编译好的arm程序是针对TI自己的Beaglebone平台的,也就是AM335x linux平台,但是如果想用在其他平台比如MTK、高通等,需要自己针对自身平台做移植编译;

6、在Source目录下,包含了所有的源代码,只要对build_all脚本和Source/script目录下的package_builder_bbb稍作修改,就可以编译出自己平台需要的二进制程序了,修改的地方还不少,比如编译器的指定,交叉工具链lib库的路径指定,等等;

7、注意所有的Makefile里面gcc编译事项,TI针对AM335x的默认都是-mcpu=cortex-a8 -march=armv7-a,你要根据你的平台CPU架构和指令集选择合适的参数,否则编译出来的程序可能在目标板上运行之后提示illegal instruction,或者提示./bin/bash... not found等等错误,比如我们平台是-mcpu=arm926ej-s -march=armv5te,所以要做相应修改,注意所有程序都是动态链接的,意味着如果你的/lib目录下没有相应的动态库,那么程序也不能成功运行,注意用arm-linux-gnueabi-readelf工具测试一下到底依赖哪些动态库;
8、安装包自带的编译好的protobuf-c库,也是针对armv7编译出来的,通过arm-linux-gnueabi-readelf libprotobuf-c.so.0查看,如果平台不是AM335x armv7,也要重新编译对应的protobufc库的,否则部分程序也是无法运行的,具体方法参考本文其他博文:在ubuntu14.04编译protobuf-c for arm版本 ,编译最终生成相关的libprotobuf-c动态库,也要全部拷贝到Z-Stack_Linux_Gateway-1.0.1-src/Source/protobuf-c-arm/lib目录下并重新执行./build_all,记得删除之前的老版本
9、package_builder_bbb它里面写了一堆冗余的脚本,最后部分的内容几乎没什么用,删掉就好了,只要确保前面的脚本都能执行到,最终生成可执行文件,然后把各种配置文件拷贝到指定的目录就好了,最后编译出来的文件如下:


server目录内容,都是动态链接,大小和安装包里面预编译出来的差不多:


10、关于移植工作,hal_gpio.c是针对AM335x平台,是通过User层直接读写文件的方式读写GPIO的,所以要配置NPI文件NPI_Gateway.cfg,注意源码中cfg名字和实际文件有出入,请统一命名,否则找不到配置文件的,还有根据硬件使用的是SPI还是UART,还是I2C,要做相应的修改的

11、另外AM335x很可能使用了level shifter,也就是电平转换,因为AM335x的GPIO电压是1.8V,CC253x的GPIO电压是3.3V,明显不能直接连接,中间一定加了自家的带方向控制的电平转换芯片,因为分析了hal_gpio.c源码,里面很多操作还有level_shifter的东西,很多平台直接就是3.3V的,没必要进行电平转换,所以这部分代码没用,注释掉即可

12、另外最新的zigbee3.0协议里面,ZNP部分已经取消了SPI的相关支持,文档里面取消了,但是源码里面还有,很有疑问。想必是SPI本来就是主从通信模式,结果这样的模式不符合gateway的要求,毕竟ZNP有些执行结果要通知Host,但是又没法主动发起通讯,所以就有了SRDY和MRDY这两根线,这样反而让通讯控制变得复杂了,TI肯定是意识到了这一点,所以索性就去掉了相关支持,改为同一支持UART了,这样就不需要SRDY和MRDY两根线了。

更新:2017-05
应网友要求,故附加一段Ota server的Makefile,拿去和原版的Makefile对照一下就知道怎么修改了。

# Makefile for Linux OTA Server Application

# Check to see if environment variables have been set
ifndef PROTOINC	
$(info Need to export the PROTOINC variable with the path to protobuf-c include directory)
ERROR_FLAG = 1
endif

ifndef PROTOLIB
$(info Need to export the PROTOLIB variable with the path to protobuf-c lib directory)
ERROR_FLAG = 1
endif

ifndef TCLIB
$(info Need to export the TCLIB variable with the path to the ti-sdk toolchain lib directory)
ERROR_FLAG = 1
endif

ifeq ($(ERROR_FLAG), 1)
$(error Stopping)
endif

# ARM Protobuf directories - Fill these in with the name of your protobuf-c directory
PROTOC_INC_DIR = $(PROTOINC)
PROTOC_LIB_PATH = -L$(PROTOLIB)

# Compilation tools - make sure to change the directory if its not called ti-sdk-am... 
ARM_LIB_PATH = -L$(TCLIB)
CC_arm = arm-linux-gnueabi-gcc
CC_arago = arm-arago-linux-gnueabi-gcc
CC_x86 = gcc

# Variables for path locations
COMPONENTS = ../../../../Components
PROJECTS = ../../../../Projects

# Compilation outputl
OBJS = out

# Temporary output for lib generation
TEMP = temp

# Library to use
LIBS_x86= -lpthread -lprotobuf-c
LIBS_arm= -lpthread -lprotobuf-c

# Inlcude paths
INCLUDES = -I $(PROJECTS)/zstack/linux/otaserver 
	-I $(PROJECTS)/zstack/linux/zstackpb 
	-I $(PROJECTS)/zstack/linux/otaserver 
	-I $(PROJECTS)/zstack/linux/srvwrapper 
    	-I $(PROJECTS)/zstack/linux/serverpb 
	-I $(PROJECTS)/zstack/linux/nwkmgr 
	-I $(PROJECTS)/zstack/linux/sdb 
        -I $(PROJECTS)/zstack/linux/source 
	-I $(PROJECTS)/zstack/linux/linux_osal/include 
	-I $(PROJECTS)/zstack/linux/hal 
	-I $(PROJECTS)/zstack/OTA/Source 
	-I $(COMPONENTS)/stack/zcl 
        -I $(COMPONENTS)/hal/include 
#	-I $(PROJECTS)/zstack/linux/zmac

# Predefine
DEFINES = -DZCL_STANDALONE 
	-DZG_SECURE_ENABLED 
	-DMAX_BINDING_CLUSTER_IDS 
	-DOTA_SERVER 
	-DHAL_OTA_BOOT_CODE 
	-DZCL_READ 
	-DOTA_HA 
	-DSERVER_NAME=OTASRVR 
	-DNPI_UNIX 
#	-D__APP_UI__ 

# Compilation Option
COMPILO_FLAGS_x86 = " -g -Wall $(INCLUDES) $(DEFINES) -include hal_types.h -include AF.h -include zcl.h -include zcl_ota.h "
COMPILO_FLAGS_arm = " -Wall $(INCLUDES) $(DEFINES) -include hal_types.h -include AF.h -include zcl.h -include zcl_ota.h -mcpu=arm926ej-s -march=armv5te -I $(PROTOC_INC_DIR) -Wl,-rpath,/usr/arm-linux-gnueabi/lib"

# List of object file to compile
APP_OBJS= 
	$(OBJS)/zstack.pb-c.o 
	$(OBJS)/zcl_general.o 
	$(OBJS)/zcl.o 
	$(OBJS)/zcl_ota.o 
	$(OBJS)/api_client.o 
	$(OBJS)/api_server.o 
	$(OBJS)/main.o 
	$(OBJS)/zcl_otaserver_lnx.o 
	$(OBJS)/OtaServer.o 
	$(OBJS)/OtaServer_db.o 
	$(OBJS)/SimpleDB.o 
	$(OBJS)/SimpleDBTxt.o 
	$(OBJS)/configparser.o 
	$(OBJS)/ota_common.o 
	$(OBJS)/otasrvr.o 
	$(OBJS)/otasrvr.pb-c.o 
	$(OBJS)/server.pb-c.o 
	$(OBJS)/trace.o 
	$(OBJS)/gatewayp2p.o 
	$(OBJS)/zcl_port.o

.PHONY: all clean lib create_output arch-all-x86 arch-all-arm clean_obj clean_obj2

all: create_output clean_obj arch-all-x86 clean_obj2 arch-all-arm

create_output:
	@echo "********************************************************" 
	@echo "Check existance of output folder" 
	-if test ! -d $(OBJS); then mkdir $(OBJS); fi

arch-all-x86: 
	@echo "********************************************************" 
	@echo "COMPILING APP FOR x86" 
	export ARCH=x86
	@$(MAKE) COMPILO=$(CC_x86) COMPILO_FLAGS=$(COMPILO_FLAGS_x86) exec_app_x86

arch-all-arm: 
	@echo "********************************************************" 
	@echo "COMPILING APP FOR ARM" 
	export ARCH=arm
	@$(MAKE) COMPILO=$(CC_arm) COMPILO_FLAGS=$(COMPILO_FLAGS_arm) exec_app_arm

arch-all-arago:
	@echo "********************************************************" 
	@echo "COMPILING APP FOR ARM" 
	export ARCH=arm
	@$(MAKE) COMPILO=$(CC_arago) COMPILO_FLAGS=$(COMPILO_FLAGS_arm) exec_app_arago

exec_app_x86: $(OBJS)/OTA_SRVR_x86

exec_app_arm: $(OBJS)/OTA_SRVR_arm

exec_app_arago: $(OBJS)/OTA_SRVR_arago

clean_obj:
	@echo "********************************************************" 
	@echo "Cleaning Existing object" 
	-if test -d $(OBJS); then rm -f $(OBJS)/*.o; fi

clean_obj2:
	@echo "********************************************************" 
	@echo "Cleaning Existing object" 
	-if test -d $(OBJS); then rm -f $(OBJS)/*.o; fi

clean:
	@echo "********************************************************" 
	@echo "Cleaning all" 
	-if test -d $(OBJS); then rm -rf $(OBJS); fi

$(OBJS)/OTA_SRVR_arm: $(APP_OBJS)
	@echo "Building target" $@ "..."
	@$(COMPILO) -o $@ $(APP_OBJS) $(COMPILO_FLAGS) $(ARM_LIB_PATH) $(PROTOC_LIB_PATH) $(LIBS_arm) 
	@if [ -n "$(EXTRACT_FILES)" ]; then echo $(MAKEFILE_LIST) | $(EXTRACT_FILES) >> project_file_list.txt; fi
	@if [ -n "$(EXTRACT_FILES)" ]; then sort -u -V project_file_list.txt | grep -v /usr/ >actual_specific_project_file_list.txt; fi
	@if [ -n "$(EXTRACT_FILES)" ]; then sort -u -V project_file_list.txt | grep /usr/ >actual_standard_project_file_list.txt; fi
	@echo "********************************************************" 

$(OBJS)/OTA_SRVR_arago: $(APP_OBJS)
	@echo "Building target" $@ "..."
	@$(COMPILO) -o $@ $(APP_OBJS) $(COMPILO_FLAGS) $(ARM_LIB_PATH) $(PROTOC_LIB_PATH) $(LIBS_arm) 
	@if [ -n "$(EXTRACT_FILES)" ]; then echo $(MAKEFILE_LIST) | $(EXTRACT_FILES) >> project_file_list.txt; fi
	@if [ -n "$(EXTRACT_FILES)" ]; then sort -u -V project_file_list.txt | grep -v /usr/ >actual_specific_project_file_list.txt; fi
	@if [ -n "$(EXTRACT_FILES)" ]; then sort -u -V project_file_list.txt | grep /usr/ >actual_standard_project_file_list.txt; fi
	@echo "********************************************************" 


$(OBJS)/OTA_SRVR_x86: $(APP_OBJS)
	@echo "Building target" $@ "..."
	@$(COMPILO) -o $@ $(APP_OBJS) $(COMPILO_FLAGS) $(LIBS_x86)
	@if [ -n "$(EXTRACT_FILES)" ]; then echo $(MAKEFILE_LIST) | $(EXTRACT_FILES) >> project_file_list.txt; fi
	@if [ -n "$(EXTRACT_FILES)" ]; then sort -u -V project_file_list.txt | grep -v /usr/ >actual_specific_project_file_list.txt; fi
	@if [ -n "$(EXTRACT_FILES)" ]; then sort -u -V project_file_list.txt | grep /usr/ >actual_standard_project_file_list.txt; fi
	@echo "********************************************************" 

# Start of Object file creation
$(OBJS)/zstack.pb-c.o: ../zstackpb/zstack.pb-c.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/zcl_general.o: $(COMPONENTS)/stack/zcl/zcl_general.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/zcl.o: $(COMPONENTS)/stack/zcl/zcl.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/zcl_ota.o: ./zcl_ota.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/api_client.o: ../srvwrapper/api_client.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/api_server.o: ../srvwrapper/api_server.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/main.o: ../srvwrapper/main.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/configparser.o: ../srvwrapper/configparser.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/OSAL.o: ../linux_osal/common/OSAL.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/OSAL_Memory.o: ../linux_osal/common/OSAL_Memory.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/OtaServer_db.o: OtaServer_db.c 
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $< 
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/OtaServer.o: OtaServer.c 
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $< 
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/zcl_otaserver_lnx.o: zcl_otaserver_lnx.c 
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $< 
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/zcl_port.o: zcl_port.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/ota_common.o: ota_common.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/otasrvr.o: otasrvr.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/otasrvr.pb-c.o: otasrvr.pb-c.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/server.pb-c.o: ../serverpb/server.pb-c.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<		
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/gatewayp2p.o: ../serverpb/gatewayp2p.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/trace.o: ../srvwrapper/trace.c 
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	
$(OBJS)/SimpleDB.o: ../sdb/SimpleDB.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

$(OBJS)/SimpleDBTxt.o: ../sdb/SimpleDBTxt.c
	@echo "Compiling" $< "..."
	@$(COMPILO) -c -o $@ $(COMPILO_FLAGS) $<
	@if [ -n "$(EXTRACT_FILES)" ]; then $(COMPILO) -M $< $(COMPILO_FLAGS) | $(EXTRACT_FILES) >> project_file_list.txt; fi

2018.4重新修订鉴于后来对整个zigbee linux gateway源代码的分析,得出,其实基于这个做zigbee的开发还是有很多问题,诸如程序不稳定,偶尔死机的问题,以及移植过程中遇到的一些其他编译问题,诸如组件protobuf-c的编译,后面要生成相应的.c和.h文件的时候,缺少*.proto文件,也是个问题,TI这部分公开的时候,的确有欠缺,所以导致一些文件缺失。

建议还是基于znp-host-framework,项目地址:

git clone git://git.ti.com/znp-host-framework/znp-host-framework.git

可以参考一下之前在TI e2e上:https://e2echina.ti.com/question_answer/wireless_connectivity/zigbee/f/104/t/137270


一些小问题如下:

1、这个版本里面实现的OTA功能,针对CC2538这种Ping-Pong的方式进行升级,并不能很好的解决两次对同一个版本进行升级,导致芯片锁住。

2、诸如单播发送指令的时候,丢包问题,并不能很好的解决实现丢包重发,只能在丢包的时候,进行单播route request发个路由请求,后面就加入retray列表什么都不管了。

3、gateway和别的service之间通过socket通讯,同时利用protobuf-c的通讯,虽然看似简单,但是整个代码过于复杂了,以至于出了bug之后无从下手,很难定位出问题出在哪里。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭