对于新版本的固件V1.11.3,在pixhawk官网可以找到开发环境的搭建,这里把开发环境链接贴出来:https://docs.px4.io/master/zh/dev_setup/dev_env_linux_ubuntu.html
但是新版本的代码过于复杂,有时候想要学习代码可以下载老版本的代码,但是经过实验发现,搭建好的新版本的环境编译老版本的代码经常出错,因此将自己实验过程中出现的一些错误总结下来:
1.下载代码的时候,不要直接git clone 要指定版本信息,如下所示:
git clone -b v1.8.2 https://github.com.cnpmjs.org/PX4/PX4-Autopilot.git
这里我指定了版本信息是v1.8.2,同时可以发现我的网页并没有直接使用github,而是使用的国内的镜像.cnpmjs.org,这样下载起来代码会快10倍左右。
2. 下载好代码,大概两分钟左右,使用指令git submodule update --init --recursive
更新子模块,但是这里的子模块也是使用的github上的资源,下载起来超级慢,两三天都有可能,因此我们修改.gitmodules文件,这是一个隐藏文件,打开PX4-Autopilot文件夹,单击CTRL+H,就可以显示隐藏文件,讲隐藏文件里面的github.com全部修改成github.com.cnpmjs.org,这样就可以换成国内的镜像,如下所示:
[submodule "mavlink/include/mavlink/v2.0"]
path = mavlink/include/mavlink/v2.0
url = https://github.com.cnpmjs.org/mavlink/c_library_v2.git
branch = master
[submodule "src/modules/uavcan/libuavcan"]
path = src/modules/uavcan/libuavcan
url = https://github.com.cnpmjs.org/UAVCAN/libuavcan.git
branch = master
[submodule "msg/tools/genmsg"]
path = msg/tools/genmsg
url = https://github.com.cnpmjs.org/ros/genmsg.git
branch = indigo-devel
[submodule "msg/tools/gencpp"]
path = msg/tools/gencpp
url = https://github.com.cnpmjs.org/ros/gencpp.git
branch = indigo-devel
[submodule "Tools/jMAVSim"]
path = Tools/jMAVSim
url = https://github.com.cnpmjs.org/PX4/jMAVSim.git
branch = master
[submodule "Tools/sitl_gazebo"]
path = Tools/sitl_gazebo
url = https://github.com.cnpmjs.org/PX4/sitl_gazebo.git
branch = master
[submodule "src/lib/matrix"]
path = src/lib/matrix
url = https://github.com.cnpmjs.org/PX4/Matrix.git
branch = master
[submodule "src/lib/DriverFramework"]
path = src/lib/DriverFramework
url = https://github.com.cnpmjs.org/PX4/DriverFramework.git
branch = master
[submodule "src/lib/ecl"]
path = src/lib/ecl
url = https://github.com.cnpmjs.org/PX4/ecl.git
branch = master
[submodule "cmake/cmake_hexagon"]
path = cmake/cmake_hexagon
url = https://github.com.cnpmjs.org/ATLFlight/cmake_hexagon.git
branch = master
[submodule "src/drivers/gps/devices"]
path = src/drivers/gps/devices
url = https://github.com.cnpmjs.org/PX4/GpsDrivers.git
branch = master
[submodule "src/modules/micrortps_bridge/micro-CDR"]
path = src/modules/micrortps_bridge/micro-CDR
url = https://github.com.cnpmjs.org/eProsima/micro-CDR.git
branch = master
[submodule "platforms/nuttx/NuttX/nuttx"]
path = platforms/nuttx/NuttX/nuttx
url = https://github.com.cnpmjs.org/PX4-NuttX/nuttx.git
branch = px4_firmware_nuttx-7.22+
[submodule "platforms/nuttx/NuttX/apps"]
path = platforms/nuttx/NuttX/apps
url = https://github.com.cnpmjs.org/PX4-NuttX/apps.git
branch = px4_firmware_nuttx-7.22+
[submodule "cmake/configs/uavcan_board_ident"]
path = cmake/configs/uavcan_board_ident
url = https://github.com.cnpmjs.org/PX4/uavcan_board_ident.git
branch = master
3.更换以后,这时候会在更新子模块的时候出现一些错误,比如无法克隆等或者长时间没有进展,这个时候只需要按CTRL+Z终止下载,将下载有错误或停止的文件夹删除,之后重新下载即可。
4.下载完成以后,大概需要10分钟时间(非常快了),我们在固件的根目录打开终端,使用指令make px4fmu-v2_default
(1.8版本一下,新版本的指令不是这个,具体看官网)编译。
5.此时出现错误error: expected initializer before '_PARAMS' extern double atan _PARAMS((double)); ^~~~~~~
这种原因可能是因为GCC版本不对的原因,但是我们有解决办法,打开根目录,进入到src->include
中,创建一个新的文件叫_ansi.h
文件,里面填写如下:
/* Provide support for both ANSI and non-ANSI environments. */
/* Some ANSI environments are "broken" in the sense that __STDC__ cannot be
relied upon to have it's intended meaning. Therefore we must use our own
concoction: _HAVE_STDC. Always use _HAVE_STDC instead of __STDC__ in newlib
sources!
To get a strict ANSI C environment, define macro __STRICT_ANSI__. This will
"comment out" the non-ANSI parts of the ANSI header files (non-ANSI header
files aren't affected). */
#ifndef _ANSIDECL_H_
#define _ANSIDECL_H_
#include <newlib.h>
#include <sys/config.h>
/* First try to figure out whether we really are in an ANSI C environment. */
/* FIXME: This probably needs some work. Perhaps sys/config.h can be
prevailed upon to give us a clue. */
#ifdef __STDC__
#define _HAVE_STDC
#endif
#ifdef _HAVE_STDC
#define _PTR void *
#define _AND ,
#define _NOARGS void
#define _CONST const
#define _VOLATILE volatile
#define _SIGNED signed
#define _DOTS , ...
#define _VOID void
#ifdef __CYGWIN__
#define _EXFUN(name, proto) __cdecl name proto
#define _EXPARM(name, proto) (* __cdecl name) proto
#else
#define _EXFUN(name, proto) name proto
#define _EXPARM(name, proto) (* name) proto
#endif
#define _DEFUN(name, arglist, args) name(args)
#define _DEFUN_VOID(name) name(_NOARGS)
#define _CAST_VOID (void)
#ifndef _LONG_DOUBLE
#define _LONG_DOUBLE long double
#endif
#ifndef _PARAMS
#define _PARAMS(paramlist) paramlist
#endif
#else
#define _PTR char *
#define _AND ;
#define _NOARGS
#define _CONST
#define _VOLATILE
#define _SIGNED
#define _DOTS
#define _VOID void
#define _EXFUN(name, proto) name()
#define _DEFUN(name, arglist, args) name arglist args;
#define _DEFUN_VOID(name) name()
#define _CAST_VOID
#define _LONG_DOUBLE double
#ifndef _PARAMS
#define _PARAMS(paramlist) ()
#endif
#endif
/* Support gcc's __attribute__ facility. */
#ifdef __GNUC__
#define _ATTRIBUTE(attrs) __attribute__ (attrs)
#else
#define _ATTRIBUTE(attrs)
#endif
/* ISO C++. */
#ifdef __cplusplus
#if !(defined(_BEGIN_STD_C) && defined(_END_STD_C))
#ifdef _HAVE_STD_CXX
#define _BEGIN_STD_C namespace std { extern "C" {
#define _END_STD_C } }
#else
#define _BEGIN_STD_C extern "C" {
#define _END_STD_C }
#endif
#endif
#else
#define _BEGIN_STD_C
#define _END_STD_C
#endif
#endif /* _ANSIDECL_H_ */
即可。
6.继续编译,此时又会碰到一个错误converting a packed 'flash_entry_header_t' {aka 'struct flash_entry_header_t'} pointer (alignment 1) to a 'uint32_t' {aka 'unsigned int'} pointer (alignment 4) may result in an unaligned pointer value [-Werror=address-of-packed-member]
,我们同样有解决办法,打开根目录,进入到cmake->common
,打开px4_base.cmake
,搜索werror,找到他,把他所在行删除即可,如下图所示:
7.之后就可以编译成功!(其余的一些小错误都可以直接搜到哦,下载之前一定记得系统快照以防万一!!!)