如果你刚自学了c++,准备开始看px4的源码,但翻来覆去找了半天没有找到一个标准的main(){}
究其原因,在nuttx系统里,程序入口不是main(){},所以找不到任何main(){}
如果想让编译器知道我写了一段函数就是主函数,就是程序的入口,该怎么做?
当然是按照px4的标准来写,这样编译器才会知道这就是主函数。

1.__EXPORT int name_main(int argc, char *argv[]);  必须使用__EXPORT对其进行导出
2.int name_main(int argc, char *argv[]);           主函数名必须是<功能名>_main
                                                   必须带参数int argc, char *argv[]

以“px4_simple_app”为例:

一个功能要以文件夹的形式存在,文件夹名称就是功能名称,文件夹中包含程序部分和CMakeLists部分。

未找到vtkTypeMacro的函数定义 未找到main的函数定义_自动驾驶


1.px4_simple_app.c :

程序部分就是功能的具体实现,程序文件的名称不作要求,但主函数名必须为<功能名>_main,如功能为px4_simple_app,主函数相应命名为px4_simple_app_main,主函数必须带参数px4_simple_app_main(int argc, char *argv[]),必须用__EXPORT对主函数进行导出__EXPORT int px4_simple_app_main(int argc, char *argv[]);。导出的目的是将函数对nuttx系统进行注册(函数名输出到链接器Linker),之后,才能对主函数进行定义。

但有的程序在声明函数的时候还在开头包含一个extern "C",这是告诉编译器按c语言规则编译这段函数而不是c++。

包含主程序的文件名称可以是任意的,如:

extern "C" __EXPORT int hello_main(int argc, char *argv[]);
int hello_main(int argc, char *argv[])

包含这段程序的文件名其实叫hello_start.cpp,但功能名也就是文件夹名称必须为hello

PX4_INFOprintf的px4版本。

#include <px4_platform_common/log.h>
__EXPORT int px4_simple_app_main(int argc, char *argv[]);
int px4_simple_app_main(int argc, char *argv[])
{
	PX4_INFO("Hello Sky!");
	return OK;
}

2.CMakeLists.txt

未找到vtkTypeMacro的函数定义 未找到main的函数定义_嵌入式_02


功能px4_simple_app在文件夹examples内

格式:
MODULE 功能父文件夹名称__功能名称:MODULE examples__px4_simple_app MAIN 功能名称:MAIN px4_simple_app SRCS是源文件列表,包含实现功能所需的程序文件,这里只包含一个px4_simple_app.c DEPENDS是依赖库列表

px4_add_module(
	MODULE examples__px4_simple_app
	MAIN px4_simple_app
	SRCS
		px4_simple_app.c
	DEPENDS
	)

所有的格式说明已经搬过来了放在文章末尾。

在nuttx系统中怎么启动这个程序,就得先了解一个概念,nuttx真的是一个操作系统,他甚至有自己的shell,叫nsh
把程序导入到px4的过程不叫烧写,叫上传。上传的文件不叫固件,叫应用,你所做的事就是给nuttx系统安装了一个应用。
按照官网的步骤把上边的的程序上传到px4里边后就自动连接到nsh了(对于sitl使用者,可以直接在源码目录下make px4_sitl gazebo,连接到的shell叫pxh),键入help

nsh> help
  help usage:  help [-v] [<cmd>]
  [           df          kill        mkfifo      ps          sleep       
  ?           echo        losetup     mkrd        pwd         test        
  cat         exec        ls          mh          rm          umount      
  cd          exit        mb          mount       rmdir       unset       
  cp          free        mkdir       mv          set         usleep      
  dd          help        mkfatfs     mw          sh          xd          
Builtin Apps:
  reboot
  perf
  top
  ..
  px4_simple_app
  ..
  sercon
  serdis

help usage列表里是现在可以使用的命令,包含一些常见的linux命令:cd、cp、mv、rm、ls...但这不是重点,重点是下面的Builtin Apps列表。
可以在Builtin Apps列表里找到我们刚编译好的项目px4_simple_app
nsh中输入

px4_simple_app

得到输出显示

Hello Sky!
#=============================================================================
#
#	px4_add_module
#
#	This function builds a static library from a module description.
#
#	Usage:
#		px4_add_module(MODULE <string>
#			MAIN <string>
#			[ STACK_MAIN <string> ]
#			[ STACK_MAX <string> ]
#			[ COMPILE_FLAGS <list> ]
#			[ INCLUDES <list> ]
#			[ DEPENDS <string> ]
#			[ SRCS <list> ]
#			[ MODULE_CONFIG <list> ]
#			[ EXTERNAL ]
#			[ DYNAMIC ]
#			)
#
#	Input:
#		MODULE			: unique name of module
#		MAIN			: entry point
#		STACK			: deprecated use stack main instead
#		STACK_MAIN		: size of stack for main function
#		STACK_MAX		: maximum stack size of any frame
#		COMPILE_FLAGS		: compile flags
#		LINK_FLAGS		: link flags
#		SRCS			: source files
#		MODULE_CONFIG		: yaml config file(s)
#		INCLUDES		: include directories
#		DEPENDS			: targets which this module depends on
#		EXTERNAL		: flag to indicate that this module is out-of-tree
#		DYNAMIC			: don't compile into the px4 binary, but build a separate dynamically loadable module (posix)
#		UNITY_BUILD		: merge all source files and build this module as a single compilation unit
#
#	Output:
#		Static library with name matching MODULE.
#		(Or a shared library when DYNAMIC is specified.)
#
#	Example:
#		px4_add_module(MODULE test
#			SRCS
#				file.cpp
#			STACK_MAIN 1024
#			DEPENDS
#				git_nuttx
#			)
#