洛杉矶住哪里好哪里有电脑维修

网站已改版,请使用新地址访问:
sitl_ping.project 在opnet中利用系统在环接口实现半实物仿真 Communication-Mobile 通讯/手机编程 238万源代码下载-
&文件名称: sitl_ping.project
& & & & &&]
&&所属分类:
&&开发工具: C-C++
&&文件大小: 352 KB
&&上传时间:
&&下载次数: 1
&&提 供 者:
&详细说明:在opnet中利用系统在环接口实现半实物仿真-Opnet use of the system in the Central-loop simulation interface in
文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):
&&sitl_ping.project&&.................\sitl_ping-sitl_ping_hostednetwork-DES-1.desinfo&&.................\sitl_ping-sitl_ping_hostednetwork-DES-1.ef&&.................\sitl_ping-sitl_ping_hostednetwork-DES-1.olf.dir&&.................\...............................................\-.21.ot&&.................\...............................................\log_info&&.................\sitl_ping-sitl_ping_hostednetwork-DES-1.ot&&.................\sitl_ping-sitl_ping_hostednetwork-DES-1.ov&&.................\sitl_ping-sitl_ping_hostednetwork.cml&&.................\sitl_ping-sitl_ping_hostednetwork.nt.m&&.................\sitl_ping-sitl_ping_hostednetwork.seq&&.................\sitl_ping-sitl_ping_rm_gtwy-DES-1.desinfo&&.................\sitl_ping-sitl_ping_rm_gtwy-DES-1.ef&&.................\sitl_ping-sitl_ping_rm_gtwy-DES-1.olf.dir&&.................\.........................................\-.09.ot&&.................\.........................................\log_info&&.................\sitl_ping-sitl_ping_rm_gtwy-DES-1.ot&&.................\sitl_ping-sitl_ping_rm_gtwy-DES-1.ov&&.................\sitl_ping-sitl_ping_rm_gtwy.cml&&.................\sitl_ping-sitl_ping_rm_gtwy.nt.m&&.................\sitl_ping-sitl_ping_rm_gtwy.seq&&.................\sitl_ping-sitl_ping_vm_gtwy-DES-1.desinfo&&.................\sitl_ping-sitl_ping_vm_gtwy-DES-1.ef&&.................\sitl_ping-sitl_ping_vm_gtwy-DES-1.olf.dir&&.................\.........................................\-.59.ot&&.................\.........................................\log_info&&.................\sitl_ping-sitl_ping_vm_gtwy-DES-1.ot&&.................\sitl_ping-sitl_ping_vm_gtwy-DES-1.ov&&.................\sitl_ping-sitl_ping_vm_gtwy.nt.m&&.................\sitl_ping-sitl_ping_vm_gtwy.seq&&.................\sitl_ping-sitl_ping_vm_gtwy_tdma-DES-1.olf.dir&&.................\..............................................\-.59.ot&&.................\..............................................\log_info&&.................\sitl_ping-sitl_ping_vm_gtwy_tdma-DES-1.ot&&.................\sitl_ping-sitl_ping_vm_gtwy_tdma.cml&&.................\sitl_ping-sitl_ping_vm_gtwy_tdma.nt.m&&.................\sitl_ping-sitl_ping_vm_gtwy_tdma.seq&&.................\sitl_ping-sitl_ping_wlan_wizard-DES-1.desinfo&&.................\sitl_ping-sitl_ping_wlan_wizard-DES-1.ef&&.................\sitl_ping-sitl_ping_wlan_wizard-DES-1.olf.dir&&.................\.............................................\-.31.ot&&.................\.............................................\log_info&&.................\sitl_ping-sitl_ping_wlan_wizard-DES-1.ot&&.................\sitl_ping-sitl_ping_wlan_wizard-DES-1.ov&&.................\sitl_ping-sitl_ping_wlan_wizard.cml&&.................\sitl_ping-sitl_ping_wlan_wizard.nt.m&&.................\sitl_ping-sitl_ping_wlan_wizard.seq&&.................\sitl_ping.prj
&输入关键字,在本站238万海量源码库中尽情搜索:主要城市:
职位分类:
已选条件:
自动控制工程师/技术员
学历要求:大专|工作经验:无工作|公司性质:民营公司|公司规模:少于50人
岗位职责1、负责楼宇自控项目系统方案设计、以及相关楼宇系统软件的编写2、负责工程项目技术支持、系统安装调试3、配合投标技术标书的制作任职要求1、自动化、电气、机电一体化、计算机等专业毕业,大专以上学历2、熟悉西门子相关产品;熟悉应用Autocad制图软件进行制图3、具有1年以上工作经验和完全独立的工作能力,有深化设计、出图、组态、编程的实战能力(优秀应届毕业生亦可)4、具备良好的业务交流能力和工作协调能力;工作态度积极,认真负责,具有团队精神5、能接受出差,服从项目安排并配合加班
学历要求:硕士|工作经验:|公司性质:外资(非欧美)|公司规模:150-500人
工作范围:半导体封装设备运动动态分析,控制算法研究与实现岗位要求:1、自动控制/自动化/应用数学/控制类相关专业硕士以上学历2、有参与自动控制方面的课题研究经验3、在以下一个或多个领域具有实际工作经验与知识将得到优先考虑:
了解掌握伺服控制,鲁棒控制,与自适应控制
掌握机电系统动力学分析知识
学历要求:|工作经验:|公司性质:民营公司|公司规模:150-500人
岗位职责:1、负责公司现有产品的技术优化和新产品的开发工作;2、负责新项目的机械设计部分并完成规范的机械图纸;3、负责及时指导解决生产过程中出现的技术问题,保证生产正常进行;4、编写与工作相关的工程文档,如机加工图纸、成本核算表、验收标准、说明书等。岗位要求:1、机械等相关专业优先;2、熟悉产品机械方面设计开发流程,熟悉液体传输及管路设计,有生产线设计经验者优先考虑;3、熟练运用Solidworks、AutoCAD等制图软件及办公软件;4、工作积极主动,有责任心,具有良好的团队合作精神。工作时间:朝九晚五
学历要求:大专|工作经验:3-4年|公司性质:民营公司|公司规模:少于50人
职位要求:1..有非标电气自动化设备及生产线的设计以及调试经验;独立解决问题的能力。2.熟悉西门子等PLC编程软件及SKADA软件(如WINCC、组态王等)的操作和组态。3.熟悉常用电气控制元件(如:电气驱动控制器、气动原件、接近传感器等)。3.熟练使用CAD/Eplan制图软件。4.能吃苦,具有较强的责任心、良好团队协作能力、沟通能力;善于学习,具有优秀的执行力和分析解决问题能力。岗位职责:1.负责电气自动化生产线设备的改造和开发设计,提供持续技术改进意见;2.负责产品电气设计:包括电气图纸绘制、电气部件选型等;3.参加现场试验并处理电气故障,提出产品改进措施;4.解决电气设备运行中的技术问题。
学历要求:本科|工作经验:无工作|公司性质:民营公司|公司规模:少于50人
岗位职责:1、负责公司代理产品的售前技术支持2、负责公司代理产品的售后服务3、负责公司最终用户信息的收集整理4、协助销售和商务解决合同涉及的技术问题岗位要求:1、沟通协调能力佳 2、电气类、机械类、石油化工类专业毕业 3、有相关行业的技术支持、销售等工作经验者优先 4、此岗位接受应届毕业生福利待遇:享有带薪年假、公司年度旅游、全勤奖、商业保险、年度奖金等如有意向,请通过51JOB在线投递简历,邮件主题注明姓名、学校、专业、应聘职位、期望薪资如有疑问,请联系王小姐 028- 转806
学历要求:|工作经验:|公司性质:民营公司|公司规模:500-1000人
岗位职责:1.负责变频器的调试及售后工作;2.配合销售部门与客户技术交流;3.负责定期为销售人员的技术培训;4.上级领导交办的其他工作。任职要求:1.大专及以上学历,工业自动化及相关专业;2.了解变频器或PLC及工控自动化相关技术;3.有自动化集成方案工作经验者优先。上班时间:朝九晚五
学历要求:|工作经验:|公司性质:民营公司|公司规模:人
任职要求:1、电子、电气或相关专业,大专及以上学历2、无经验可实习,应届生优先,3、有较强的责任心,良好团队协作能力、沟通能力、谦虚踏实。岗位职责:1、负责PLC编程。2、组织自动化机器的安装、调试、维修、保养。3、自动控制工程设计4、参加现场试验并处理电气故障,提出改进措施工作时间:朝九晚五 周末双休 法定假日
学历要求:本科|工作经验:3-4年|公司性质:民营公司|公司规模:少于50人
岗位职责 1、负责洁净暖通空调恒温恒湿控制、污水处理自动控制、楼宇自控(BA)系统强、弱电图纸深化设计;2、负责软件程序编辑,现场调试;3、负责竣工资料编辑;4、技术部经理需有较强的组织协调能力、5年以上行业工作经验。任职资格 1、全日制大学以上学历、能适应出差工作;2、2年以上PLC或DDC暖通空调自动控制、污水处理自动控制经验;3、独立完成500点以上(西门子、罗克韦尔、三菱)PLC自动控制系统经验;4、独立完成1000点以上(西门子、江森、霍尼韦尔、施耐德楼控)楼宇自控(BA)系统经验;5、有 SIEMENS PLC
或 APOGEE DDC 调试经验优先;
学历要求:大专|工作经验:2年|公司性质:民营公司|公司规模:少于50人
1、负责水务行业自动化、SCADA系统方案设计,电气原理图设计,对温度、压力、流量、液位实现自动化控制等;2、负责各种测量仪表和自动控制系统、电气仪表备件的选型及管理;3、负责PLC编程、调试、上位机组态;4、指导现场仪表、电缆、气源管线等的铺设和安装,控制回路的信号测试;1、大学专科以上学历,机电、电气、自动化相关专业,熟悉常见工控仪表的使用、熟悉常见物理量(如温度、压力、流量等)的控制方法;2、两年以上工控工作经验,有水处理行业从业经验优先;3、学习能力强,至少熟练掌握一种品牌PLC编程、工控机组态、触摸屏组态,会使用AB(罗克韦尔)Logix5000系列工控产品者优先;4、英语读写良好,能查阅英文手册、使用英文版编程、组态软件;5、有一定高级语言基础,会使用VB或VBA优先
工作时间:上5休2
学历要求:|工作经验:|公司性质:民营公司|公司规模:50-150人
职位要求:1、20-30岁之间,男女不限;2、全日制大专及以上学历,经验不限;3、对互联网行业感兴趣;4、较强的沟通能力与优良的逻辑思维能力;福利待遇:1、正式入职后均薪6K,五险一金入职即交,外加项目提成;2、国家法定节假日带薪休假,年底十三薪以及各项奖金,周末双休无加班;3、晋升渠道通畅,一年有四次加薪晋升机会;4、朝九晚六,周末双休,无加班;联系方式:何小姐
学历要求:本科|工作经验:2年|公司性质:民营公司|公司规模:少于50人
职位描述 1、电气或自动控制相关专业本科以上学历 2、诚信敬业,擅长沟通,具有良好的学习能力,有良好的责任心、敬业精神以及团队合作精神 。 3、有2年以上项目经验,能独立完成大中型自动化系统的设计、编程、调试,精通PLC/DCS/电气设计软件EPLAN和变频、仪表等设备的应用。 4、具有良好英语阅读能力;至少可借助工具书查阅英文资料 5、能熟练应用常用办公应用软件 6、能承受较大工作压力,能适应出差
学历要求:大专|工作经验:|公司性质:民营公司|公司规模:150-500人
岗位职责:1、根据测试用例执行软件测试,书写和提交测试缺陷;2、根据项目要求修改和补充测试用例,及公司管理层安排的其它工作;3、记录BUG并且及时反馈研发人员修复,测试功能是否完善;职位要求:1、专科及以上学历,计算机、软件、测试、网络、信息、通信、 电子、数学、信管、设计、物联网、自动化等相关专业优先考虑,其它跨专业优秀者亦可考虑,同时欢迎优秀应届毕业生报投;2、有意向长期在计算机行业发展,了解软件测试的理论、方法与工具者优先;3、具备较强的学习能力,思路清晰,善于思考,具有良好的分析和解决问题的能力; 4、有良好的沟通表达能力,具备较强的自我驱动能力,有强烈的团队协作能力;舒适的办公环境,和谐愉快的工作氛围,热情友好的团队。加入我们,我们将为你提供:1、提供多方向畅通的职业发展通道和无天花的职业发展空间,尽可能挖掘每个人的潜质;2、提供前沿的行业和技能等方面的培训,让你有更大的上升空间;3、亲民领导:所有管理层领导都非常NICE,人性化管理;4、职业量身:总经理将在开放日与您一对一定制职业发展规划;5、人际关系:我们这里人际关系简单,只对事,不对人,杜绝办公室政治。你以为这样就完了吗?继续往下看,千万不要、不要、不要停:1、具有竞争力的薪酬体系、一年两次调岗调薪考核、丰厚年终奖等你来拿;2、丰富的日常员工小福利(1)法定节假日、婚假、产假、带薪年假等,必须人性化;(2)下午茶供、现磨咖啡、零食供应,常备小药箱,楼下合作健身房敞开用;(3)“各类公司活动”:年会旅游嗨翻天,周年庆、户外活动、节日趴体、每月员工生日会,劳逸结合才有干劲儿;3、畅通的员工建议/意见/投诉通道,合理即有奖,就怕你憋着。我们的目标是:把公司建设成家一样幸福的地方。团队中,有来大企业工作过的不老腊肉们,也有刚毕业的青涩小鲜肉。我们年轻,喜爱运动,充满激情,我们想成为一家伟大的公司,并为之奋斗努力,如果你也和我们怀揣梦想,欢迎各位走过路过的小伙伴们随时加入我们,一起闯出个美好未来!
学历要求:本科|工作经验:3-4年|公司性质:民营公司|公司规模:少于50人
学历要求:|工作经验:2年|公司性质:国企|公司规模:150-500人
1、熟悉自动控制设备的操作和维修;2、熟悉PLC编程,制定自控方案;3、负责生产线设备日常维护保养及本部门的其他事项。职位要求:1、自动控制等相关专业,中技及以上学历;2、两年以上相关工作经验;3、有医药企业工作经验者优先;4、身体健康,无传染病。
学历要求:|工作经验:|公司性质:民营公司|公司规模:150-500人
公司主要是做网站网页开发,安卓手机APP开发及游戏开发的,目前招收部分储备干部(软件开发方向)岗位要求:1.对计算机感兴趣,有意从事美工、设计类工作2.具有良好的审美能力,有自己的见解3.会基本的办公软件操作,了解各类平面设计软件(无经验,条件优秀,前期有同事带)4.有良好的沟通能力,工作细致,能承受工作压力,踏实肯干,富有团队精神福利待遇:1、富有竞争力的薪酬水平和其他福利津贴;2、健全的五险一金;3、给予完善的绩效考核,年终奖金及定期调薪;4、完善的培养体系和晋升机制;上班时间; 09:00-18:00 5天8小时
学历要求:|工作经验:|公司性质:民营公司|公司规模:50-150人
岗位职责:1、使用microwin、博图等自动化软件编写设备PLC及触摸屏控制程序;2、低压电器件选型并编制控制系统BOM清单;3、使用CAD设计电气原理图、控制柜、元器件平面布置图等;4、编写设备控制要求、控制流程、操作手册、产品手册等技术文件,修改设备工艺流程图;任职要求:1、计算机、自控设计、机电、机械设备等专业毕业,大专及以上学历;2、能够根据工艺要求进行设备电气设计:如电气CAD图纸绘制、电气硬件选型等;3、熟练运用西门子和AB、倍福、施耐德、欧姆龙、三菱系列PLC中的一种,能够熟练使用SCL,ST编程预言者优先;4、熟练运用昆仑通态触摸屏、WICC,组态王、intoch等组态中的一种;
学历要求:大专|工作经验:2年|公司性质:民营公司|公司规模:50-150人
岗位职责:1、负责设备的安装及调试工作;2、负责完成电器柜制作、电器路线的布线、走线工作;3、负责设备的售后服务,并与客服保持沟通,对客户进行产品使用、保养方面的培训工作;4、负责车间用电设备的维护和保养;任职要求:1.大专及以上学历,电气工程及其自动化等相关专业, 两年以上工作经验;2、熟悉西门子、施耐德plc应用优先考虑;3、熟悉电器柜制作、布线、走线、用电的相关规范;4、熟悉伺服、变频器的应用优先考虑;5、了解 IEC 61131-3五种编程方法中的其中两种;6、能吃苦耐劳,头脑灵活,能适应出差(1个月)
学历要求:大专|工作经验:无工作|公司性质:民营公司|公司规模:50-150人
职位描述:1、了解客户需求,负责自动化工程项目的方案设计、电气图设计、程序编写、现场安装、调试、验收等工作;2、负责项目如程序流程图,接口变量表、电气维护手册、产品使用手册等产品技术文档资料编写;3、负责自动化工程项目的维护、故障处理及协助售后工程师解决现场设备问题;4、根据公司要求,完成电气图设计,现场电气施工规划、线缆敷设,接线等工作;职位要求:1、大专及以上学历,机电一体化、电气自动化等相关专业;2、.熟悉工控行业,了解自动化系统工程,熟悉西门子PLC或三菱PLC等应用;4、熟练掌握自动控制硬件设计与软件开发工作原理及其相关开发工具;,能独立完成电路图的绘制、现场系统布线设计、现场布线指导、控制系统调试及售后服务等工作;5.熟悉常用元器件性能及选型;6.掌握电控柜接线,现场施工布线技能;有较强的实际动手能力和灵活的思维,善于解决现场实际问题;7.服从上级主管领导工作安排,完成上级临时交付的工作任务,积极配合项目经理开展项目工作;8.能够适应长期/短期驻外工作,具有团结协作精神;
学历要求:本科|工作经验:3-4年|公司性质:民营公司|公司规模:500-1000人
1.在仪表技术和管理业务方面有一定经验;2.能融洽处理项目各级单位各种关系3.工作主动、沟通能力强4.全面负责仪表施工管理各项工作;5.指导和组织各专业任务单技工进行施工6.有化工炼油项目施工管理经验者优先,要求长期驻项目
学历要求:大专|工作经验:|公司性质:民营公司|公司规模:少于50人
岗位要求:1、年毕业生,专科及以上学历,计算机、软件、测试、网络、信息、通信、电子、数学、信管、设计、物联网、自动化等相关专业优先考虑,其它专业优秀毕业生亦可考虑;2、沟通能力佳,有团队意识;3、热爱计算机软件开发行业,认可企业的品牌文化;4、善于学习和总结分析,有良好的工作态度和团队合作精神。    岗位职责:1、协助linux系统(发行版、自主系统)定制开发;2、协助linux程序开发及内核定制维护;3、编写相关开发文档与项目文档;4、根据项目要求进行现场开发维护;加入我们,我们还为你提供:1、易于个人发展的职级梯级体系;2、具有竞争力的薪酬体系、定时考核调薪升级、丰厚年终奖;3、丰富的福利(1)法定节日、婚假、丧假、产假陪产假、带薪年假、带薪病假等;(2)现磨咖啡、零食无限供应、常备小药箱,兵乓球桌、健身沙袋;员工体检(3)“各类体育竞技赛”:羽毛球、乒乓球、篮球、拔河等;(4)“各类公司活动”:周年庆、运动会、节日趴体、每月员工生日会。4、员工意见尊重畅通的员工建议/意见/投诉通道,合理即有奖。更多福利建设中……我们的目标是:把公司建设成家一样幸福的地方。团队中,有来自阿里、腾讯、联想等工作过的伙伴,也有刚毕业的青涩鲜肉,我们年轻,喜爱运动,充满激情,我们想成为一家伟大的公司,并为之奋斗努力,如果你也和我们怀揣梦想,欢迎各位路过的小伙伴们随时加入我们哦,我们一起闯出个未来!
-中高端人才求职平台
年薪:30-80万
招聘职位:
后端开发,前端开发,移动端开发,测试,产品/设计/运营
年薪:40-150万
招聘职位:
财务审计,合规与风险控制,后台运营,投行,销售
年薪:40-60万
招聘职位:
房地产开发,建筑工程,规划设计,商业,市场营销
年薪:20-40万
招聘职位:
汽车新能源,软件与汽车电子,生产制造,质量管理,供应链管理
最热行业招聘
未经51job同意,不得转载本网站之所有招聘信息及作品 | 无忧工作网版权所有&PX4编译脚本-乐山
穷则独善其身,达则兼善天下。
四轴论坛:thetravels.top。刚刚开通,希望大家多多支持
PX4编译脚本
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& --------&转载请注明出处
-------- .冷月追风
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&-------- email:&参考网站:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&编译环境:xubuntu&&& 在这里我不特别区分 APM, ArduCopter, pixhawk, PX4, PIX。&&& 实际上 pixhawk可以在 Windows, Linux, MAC上编译。这里选择 xubuntu作为开发环境为个人意愿,个人比较钟情与 Linux中简单而高效的命令行。有人做过测试,MAC编译代码只需几分钟,但是我毕竟没有 MAC也就只好退而求其次。&&& 但其实我编译源码使用的也只是虚拟机而已。但即便是虚拟机也比在 Windows编译要高效得多。1. 编译源码&&& 源码编译参考 APM网站&&即可,根据自己的系统选择相应的编译教程。我用的是 Linux系统,因此参考&&进行编译。&&& 现将其编译过程简单摘录如下:
Quick startFor Ubuntu, follow these steps to build the code. For other distributions, see the advanced instructions below.1&SetupInstall git:&&&&sudo apt-get&-qq&-y install gitClone the source:&&&&git clone /diydrones/ardupilot.gitRun the install-prereqs-ubuntu.sh script:&&&&ardupilot/Tools/scripts/install-prereqs-ubuntu.sh&-yReload the path (log-out and log-in to make permanent):&&&&.&~/.profile2&BuildBuild&for&ArduCopter:&&&&cd ardupilot/ArduCopter&&&&make configure&&&&make px4-v2Build&for&ArduPlane:&&&&cd ardupilot/ArduPlane&&&&make configure&&&&make px4-v2
2. 脚本分析&&&&我们始终需要记住一件事,那就是我们在哪个目录编译,以及我们的编译命令。编译目录为: ardupilot/ArduCopter,编译命令我们用的是 “make px4”,但我们也可以改变命令编译我们需要的。&&& 下面是我们的 Makefile:
include&../mk/apm.mk
实际上这是调用了外部的 mk文件来进行编译,内容为:
# find the mk/&directory, which is where&this&makefile fragment# lives. (patsubst strips the trailing slash.)SYSTYPE&&&:=&$(shell uname)ifneq ($(findstring CYGWIN, $(SYSTYPE)),)&&&MK_DIR&:=&$(shell cygpath&-m ../mk)else&&MK_DIR&:=&$(patsubst&%/,%,$(dir $(lastword $(MAKEFILE_LIST))))endifinclude&$(MK_DIR)/environ.mk#&short-circuit build&for&the configure targetifeq ($(MAKECMDGOALS),configure)include&$(MK_DIR)/configure.mkelse# common makefile componentsinclude&$(MK_DIR)/targets.mkinclude&$(MK_DIR)/sketch_sources.mkifneq ($(MAKECMDGOALS),clean)# board specific includesifeq ($(HAL_BOARD),HAL_BOARD_APM1)include&$(MK_DIR)/board_avr.mkendififeq ($(HAL_BOARD),HAL_BOARD_APM2)include&$(MK_DIR)/board_avr.mkendififeq ($(HAL_BOARD),HAL_BOARD_AVR_SITL)include&$(MK_DIR)/board_native.mkendififeq ($(HAL_BOARD),HAL_BOARD_LINUX)include&$(MK_DIR)/board_linux.mkendififeq ($(HAL_BOARD),HAL_BOARD_PX4)include&$(MK_DIR)/board_px4.mkendififeq ($(HAL_BOARD),HAL_BOARD_VRBRAIN)include&$(MK_DIR)/board_vrbrain.mkendififeq ($(HAL_BOARD),HAL_BOARD_FLYMAPLE)include&$(MK_DIR)/board_flymaple.mkendifendifendif
这个时候可能我们会很迷惑, $(HAL_BOARD)的值到底是多少?&&& 但其实我们在执行 “make px4”命令编译的时候会有一行信息:
HAL_BOARD=HAL_BOARD_PX4 HAL_BOARD_SUBTYPE=&TOOLCHAIN=NATIVE EXTRAFLAGS=-DGIT_VERSION=&b6d361a3&&-DNUTTX_GIT_VERSION=&eba6b56f&&-DPX4_GIT_VERSION=&cf208916&
这行信息非常清楚地告诉了我们用的是 “$(MK_DIR)/board_px4.mk”文件。但这个 mk文件内容其实也不多:
TOOLCHAIN&=&NATIVEinclude&$(MK_DIR)/find_tools.mkinclude&$(MK_DIR)/px4_targets.mk
所以最终将是有 “$(MK_DIR)/px4_targets.mk”中的脚本进行编译:
px4-v1:&showflags $(PX4_ROOT)/Archives/px4fmu-v1.export $(SKETCHCPP) module_mk px4-io-v1&$(RULEHDR)&$(v) rm&-f $(PX4_ROOT)/makefiles/$(PX4_V1_CONFIG_FILE)&$(v) cp $(PWD)/$(PX4_V1_CONFIG_FILE) $(PX4_ROOT)/makefiles/&$(v) $(PX4_MAKE) px4fmu-v1_APM&$(v)&/bin/rm&-f $(SKETCH)-v1.px4&$(v) cp $(PX4_ROOT)/Images/px4fmu-v1_APM.px4 $(SKETCH)-v1.px4&$(v) echo&&PX4 $(SKETCH) Firmware is in $(SKETCH)-v1.px4&px4-v2:&showflags $(PX4_ROOT)/Archives/px4fmu-v2.export $(SKETCHCPP) module_mk px4-io-v2&$(RULEHDR)&$(v) rm&-f $(PX4_ROOT)/makefiles/$(PX4_V2_CONFIG_FILE)&$(v) cp $(PWD)/$(PX4_V2_CONFIG_FILE) $(PX4_ROOT)/makefiles/&$(PX4_MAKE) px4fmu-v2_APM&$(v)&/bin/rm&-f $(SKETCH)-v2.px4&$(v) cp $(PX4_ROOT)/Images/px4fmu-v2_APM.px4 $(SKETCH)-v2.px4&$(v) echo&&PX4 $(SKETCH) Firmware is in $(SKETCH)-v2.px4&px4:&px4-v1 px4-v2px4-io-v1: $(PX4_ROOT)/Archives/px4io-v1.export&$(v) make -C $(PX4_ROOT) px4io-v1_default&$(v) /bin/rm -f px4io-v1.bin&$(v) cp $(PX4_ROOT)/Images/px4io-v1_default.bin px4io-v1.bin&$(v) cp $(PX4_ROOT)/Build/px4io-v1_default.build/firmware.elf px4io-v1.elf&$(v) mkdir -p $(MK_DIR)/PX4/ROMFS/px4io/&$(v) rm -f $(MK_DIR)/PX4/ROMFS/px4io/px4io.bin&$(v) cp px4io-v1.bin $(MK_DIR)/PX4/ROMFS/px4io/px4io.bin&$(v) mkdir -p $(MK_DIR)/PX4/ROMFS/bootloader/&$(v) rm -f $(MK_DIR)/PX4/ROMFS/bootloader/fmu_bl.bin&$(v) cp $(SKETCHBOOK)/mk/PX4/bootloader/px4fmu_bl.bin $(MK_DIR)/PX4/ROMFS/bootloader/fmu_bl.bin&$(v) echo &PX4IOv1 Firmware is in px4io-v1.bin&px4-io-v2: $(PX4_ROOT)/Archives/px4io-v2.export&$(v) make -C $(PX4_ROOT) px4io-v2_default&$(v) /bin/rm -f px4io-v2.bin&$(v) cp $(PX4_ROOT)/Build/px4io-v2_default.build/firmware.bin px4io-v2.bin&$(v) cp $(PX4_ROOT)/Images/px4io-v2_default.bin px4io-v2.bin&$(v) cp $(PX4_ROOT)/Build/px4io-v2_default.build/firmware.elf px4io-v2.elf&$(v) mkdir -p $(MK_DIR)/PX4/ROMFS/px4io/&$(v) rm -f $(MK_DIR)/PX4/ROMFS/px4io/px4io.bin&$(v) cp px4io-v2.bin $(MK_DIR)/PX4/ROMFS/px4io/px4io.bin&$(v) mkdir -p $(MK_DIR)/PX4/ROMFS/bootloader/&$(v) rm -f $(MK_DIR)/PX4/ROMFS/bootloader/fmu_bl.bin&$(v) cp $(SKETCHBOOK)/mk/PX4/bootloader/px4fmuv2_bl.bin $(MK_DIR)/PX4/ROMFS/bootloader/fmu_bl.bin&$(v) echo &PX4IOv2 Firmware is in px4io-v2.bin&
当然这只是其中的部分内容。告诉我们 px4是怎样的一个目标。V1,V2是两个不同的版本,这里我就不分别进行分析了,主要以我所使用的 V2来分析。3. px4-io-v2&&& 为了帮助分析,我增加了下面的目标:
px4-io-v3:&$(PX4_ROOT)/Archives/px4io-v2.export&echo&&$(v) make -C $(PX4_ROOT) px4io-v2_default&&$(v) make&-C $(PX4_ROOT) px4io-v2_default&$(v)&/bin/rm&-f px4io-v2.bin
得到下面这样一串信息:
echo&&@ make -C /home/bitcraze/apm/PX4Firmware px4io-v2_default&@ make&-C&/home/bitcraze/apm/PX4Firmware px4io-v2_default
这样我就知道了下面 make所在的目录,知道了目录就可以找到 Makefile,就可以继续往下分析。&&& 但到了 “PX4Firmware”目录,打开 Makefile却找不到 “px4io-v2_default”这样一个目标。说明目标被处理过了。于是我只好去看编译输出信息了:
make[1]:&Entering directory `/home/bitcraze/apm/PX4Firmware'%%%%%%%% Building px4io-v2_default in /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/%%%%
这里需要说明的是我的源码是编译过的。&&& 通过这串信息,我匹配到了这样一个目标:
$(FIRMWARES):&$(BUILD_DIR)%.build/firmware.px4:&$(ECHO)&&hello& $(FIRMWARES)&@$(ECHO)&%%%%&@$(ECHO)&%%%%&Building $(config) in $(work_dir)&@$(ECHO)&%%%%&$(Q) $(MKDIR)&-p $(work_dir)&$(ECHO)&&hello2&&$(PX4_MK_DIR)&$(Q) $(MAKE)&-r&-C $(work_dir) \&&-f $(PX4_MK_DIR)firmware.mk \&&CONFIG=$(config) \&&WORK_DIR=$(work_dir) \&&$(FIRMWARE_GOAL)
“hello”是我后来加的。通过 hello我就确定了 “$(FIRMWARES)”实际上就是我们编译的 “px4io-v2_default”。但这究竟是怎么回事呢?不妨先看看我们加了 hello之后的输出:
echo&&hello&&/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v1_APM.build/firmware.px4&/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v1_default.build/firmware.px4/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v2_APM.build/firmware.px4&/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v2_default.build/firmware.px4/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v2_test.build/firmware.px4&/home/bitcraze/apm/PX4Firmware/Build/px4io-v1_default.build/firmware.px4/home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.px4hello&/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v1_APM.build/firmware.px4&/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v1_default.build/firmware.px4/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v2_APM.build/firmware.px4&/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v2_default.build/firmware.px4/home/bitcraze/apm/PX4Firmware/Build/px4fmu-v2_test.build/firmware.px4&/home/bitcraze/apm/PX4Firmware/Build/px4io-v1_default.build/firmware.px4/home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.px4
&在 Makefile中有这样一段内容:
FIRMWARES&&&=&$(foreach config,$(KNOWN_CONFIGS),$(BUILD_DIR)$(config).build/firmware.px4)
因为就是最后我们实际上编译的是 “/home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.px4”目标。&&& 而通过 hello2那一串信息我知道下一个 mk是 “/home/bitcraze/apm/PX4Firmware/makefiles/firmware.mk ”。但我们这里看到并没有指定编译哪个目标,也就是说编译第一个目标,通常是 all。
## Set a&default&target so that included makefiles or errors here don't&# cause confusion.## XXX We could do something cute here with $(DEFAULT_GOAL) if it's not one#&&&&&of the maintenance targets and set CONFIG based on it.#all:&&firmware.PHONY:&&&firmwarefirmware:&&$(PRODUCT_BUNDLE)## Built product rules#$(PRODUCT_BUNDLE):&$(PRODUCT_BIN)&@$(ECHO)&%%&Generating $@&$(Q) $(MKFW)&--prototype $(IMAGE_DIR)/$(BOARD).prototype \&&--git_identity $(PX4_BASE) \&&--image $&&&&$@$(PRODUCT_BIN):&&$(PRODUCT_ELF)&$(call SYM_TO_BIN,$&,$@)$(PRODUCT_ELF):&&$(OBJS) $(MODULE_OBJS) $(LIBRARY_LIBS) $(GLOBAL_DEPS) $(LINK_DEPS) $(MODULE_MKFILES)&$(call LINK,$@,$(OBJS) $(MODULE_OBJS) $(LIBRARY_LIBS))
&&& 这一段 Makefile我是自己整理了顺序的。这段 Makefile大致告诉了我们最终我们的程序是怎么编译出来的。那么现在剩下的就是这些 “OBJS”是怎么编译的问题了。通常都是有对应的源文件编译出来的。4. 目标编译&&& 这里所说的目标编译就是 “$(PRODUCT_ELF)”所依赖的这些目标。我们先来看看 “$(OBJS)”。
## Object files we will generate from sources#OBJS&&&:=&$(foreach src,$(SRCS),$(WORK_DIR)$(src).o)## SRCS&-&&OBJS rules#$(OBJS):&&$(GLOBAL_DEPS)$(filter&%.c.o,$(OBJS)):&$(WORK_DIR)%.c.o:&%.c $(GLOBAL_DEPS)&$(call COMPILE,$&,$@)$(filter&%.cpp.o,$(OBJS)):&$(WORK_DIR)%.cpp.o:&%.cpp $(GLOBAL_DEPS)&$(call COMPILEXX,$&,$@)$(filter&%.S.o,$(OBJS)):&$(WORK_DIR)%.S.o:&%.S $(GLOBAL_DEPS)&$(call ASSEMBLE,$&,$@)
&这个时候如果我们试图去查看 “$(OBJS)”或是 “$(SRCS)”的值或许会得到一个让自己觉得莫名其妙的结果: “/home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build//home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/empty.c.o”, 而且你去查看文件 “empty.c”的内容你会看到内容为:
/* this is an empty file */
这可能让人有点费解。为什么会这样呢?如果我们去阅读 Makefile我们就会发现:
BUILTIN_CSRC&& = $(WORK_DIR)builtin_commands.c# command definitions from modules (may be empty at Makefile parsing time...)MODULE_COMMANDS&& = $(subst COMMAND.,,$(notdir $(wildcard $(WORK_DIR)builtin_commands/COMMAND.*)))# We must have at least one pre-defined&builtin command in order to generate# any of&this.#ifneq ($(BUILTIN_COMMANDS),)# (BUILTIN_PROTO,&cmdspec&,&outputfile&)define&BUILTIN_PROTO&$(ECHO)&'extern int $(word 4,$1)(int argc, char *argv[]);'&&&&$2;endef# (BUILTIN_DEF,&cmdspec&,&outputfile&)define&BUILTIN_DEF&$(ECHO)&'&&&&{&$(word 1,$1)&, $(word 2,$1), $(word 3,$1), $(word 4,$1)},'&&&&$2;endef# Don't generate until modules have updated their command files$(BUILTIN_CSRC): $(GLOBAL_DEPS) $(MODULE_OBJS) $(MODULE_MKFILES) $(BUILTIN_COMMAND_FILES)# @$(ECHO) &CMDS:&&&&$@&&$(ECHO) &CMDS:&&&&$@&&$(Q) $(ECHO) '/* builtin command list - automatically generated, do not edit */' & $@&$(Q) $(ECHO) '#include&&nuttx/config.h&' && $@&$(Q) $(ECHO) '#include&&nuttx/binfmt/builtin.h&' && $@&$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@))&$(Q) $(foreach spec,$(MODULE_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@))&$(Q) $(ECHO) 'const&struct&builtin_s g_builtins[]&=&{' && $@&$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@))&$(Q) $(foreach spec,$(MODULE_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@))&$(Q) $(ECHO) '&&&&{NULL,&0,&0, NULL}' && $@&$(Q) $(ECHO) '};' && $@&$(Q) $(ECHO) 'const&int&g_builtin_count&=&$(words $(BUILTIN_COMMANDS) $(MODULE_COMMANDS));' && $@SRCS&&&+= $(BUILTIN_CSRC)EXTRA_CLEANS&&+= $(BUILTIN_CSRC)endif################################################################################# Default SRCS generation################################################################################## If there are no SRCS, in that case, generate an empty# source file.#ifeq ($(SRCS),)EMPTY_SRC&&&= $(WORK_DIR)empty.c$(EMPTY_SRC):&$(Q) $(ECHO) '/* this is an empty file */' & $@SRCS&&&+= $(EMPTY_SRC)endif
&这样我们就知道,如果 “$(SRCS)”值为空,就会往文件 “empty.c”中写入“/* this is an empty file */”,并且给 “SRCS”赋值为 “$(WORK_DIR)empty.c”。这样我们就知道 “$(BUILTIN_COMMANDS)”值必须也为空,这样就跟我们观察到的现象是一致的。&&& 通过搜索我们发现,
bitcraze@bitcraze-vm:~/apm/ardupilot/ArduCopter$ grep&-nr BUILTIN_COMMANDS ../../../../PX4Firmware/makefiles/config_px4fmu-v1_APM.mk:81:BUILTIN_COMMANDS&:=&\../../PX4Firmware/makefiles/config_px4fmu-v2_APM.mk:80:BUILTIN_COMMANDS&:=&\../../PX4Firmware/makefiles/config_px4fmu-v2_test.mk:62:BUILTIN_COMMANDS&:=&\../../PX4Firmware/makefiles/config_px4fmu-v1_default.mk:156:BUILTIN_COMMANDS&:=&\../../PX4Firmware/makefiles/config_px4fmu-v2_default.mk:164:BUILTIN_COMMANDS&:=&\../../PX4Firmware/makefiles/README.txt:59:&ROMFS_ROOT to build a ROMFS and BUILTIN_COMMANDS to&include&non-module../../PX4Firmware/makefiles/firmware.mk:57:# BUILTIN_COMMANDS../../PX4Firmware/makefiles/firmware.mk:393:# The configuration supplies builtin command information in the BUILTIN_COMMANDS../../PX4Firmware/makefiles/firmware.mk:409:ifneq ($(BUILTIN_COMMANDS),)../../PX4Firmware/makefiles/firmware.mk:428:&$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@))../../PX4Firmware/makefiles/firmware.mk:431:&$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@))../../PX4Firmware/makefiles/firmware.mk:435:&$(Q) $(ECHO)&'const int g_builtin_count = $(words $(BUILTIN_COMMANDS) $(MODULE_COMMANDS));'&&&&$@../../linux/PX4Firmware/makefiles/config_px4fmu-v1_APM.mk:81:BUILTIN_COMMANDS&:=&\../../linux/PX4Firmware/makefiles/config_px4fmu-v2_APM.mk:80:BUILTIN_COMMANDS&:=&\../../linux/PX4Firmware/makefiles/config_px4fmu-v2_test.mk:62:BUILTIN_COMMANDS&:=&\../../linux/PX4Firmware/makefiles/config_px4fmu-v1_default.mk:156:BUILTIN_COMMANDS&:=&\../../linux/PX4Firmware/makefiles/config_px4fmu-v2_default.mk:164:BUILTIN_COMMANDS&:=&\../../linux/PX4Firmware/makefiles/README.txt:59:&ROMFS_ROOT to build a ROMFS and BUILTIN_COMMANDS to&include&non-module../../linux/PX4Firmware/makefiles/firmware.mk:57:# BUILTIN_COMMANDS../../linux/PX4Firmware/makefiles/firmware.mk:393:# The configuration supplies builtin command information in the BUILTIN_COMMANDS../../linux/PX4Firmware/makefiles/firmware.mk:409:ifneq ($(BUILTIN_COMMANDS),)../../linux/PX4Firmware/makefiles/firmware.mk:427:&$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@))../../linux/PX4Firmware/makefiles/firmware.mk:430:&$(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@))../../linux/PX4Firmware/makefiles/firmware.mk:434:&$(Q) $(ECHO)&'const int g_builtin_count = $(words $(BUILTIN_COMMANDS) $(MODULE_COMMANDS));'&&&&$@../../linux/ardupilot/mk/VRBRAIN/config_vrbrain-v51_APM.mk:167:BUILTIN_COMMANDS&:=&\../../linux/ardupilot/mk/VRBRAIN/config_vrbrain-v45_APM.mk:167:BUILTIN_COMMANDS&:=&\../../linux/ardupilot/mk/VRBRAIN/config_vrubrain-v51_APM.mk:167:BUILTIN_COMMANDS&:=&\../../linux/ardupilot/mk/PX4/config_px4fmu-v1_APM.mk:81:BUILTIN_COMMANDS&:=&\../../linux/ardupilot/mk/PX4/config_px4fmu-v2_APM.mk:80:BUILTIN_COMMANDS&:=&\../../ardupilot/mk/VRBRAIN/config_vrbrain-v51_APM.mk:167:BUILTIN_COMMANDS&:=&\../../ardupilot/mk/VRBRAIN/config_vrbrain-v45_APM.mk:167:BUILTIN_COMMANDS&:=&\../../ardupilot/mk/VRBRAIN/config_vrubrain-v51_APM.mk:167:BUILTIN_COMMANDS&:=&\../../ardupilot/mk/PX4/config_px4fmu-v1_APM.mk:81:BUILTIN_COMMANDS&:=&\../../ardupilot/mk/PX4/config_px4fmu-v2_APM.mk:80:BUILTIN_COMMANDS&:=&\bitcraze@bitcraze-vm:~/apm/ardupilot/ArduCopter$
那么我们就知道 IO板编译的时候不会去创建 “$(BUILTIN_CSRC)”目标,这个目标会生成一个源文件,就是&builtin_commands.c。我们不妨到核心板的相应目录下去查看下该文件的内容:
bitcraze@bitcraze-vm:~/apm/ardupilot/ArduCopter$ cat ../../PX4Firmware/Build/px4fmu-v2_APM.build/builtin_commands.c&/* builtin command list - automatically generated, do not edit */#include&&nuttx/config.h&#include&&nuttx/binfmt/builtin.h&extern&int&sercon_main(int&argc,&char&*argv[]);extern&int&serdis_main(int&argc,&char&*argv[]);extern&int&ArduPilot_main(int&argc,&char&*argv[]);extern&int&adc_main(int&argc,&char&*argv[]);extern&int&auth_main(int&argc,&char&*argv[]);extern&int&bl_update_main(int&argc,&char&*argv[]);extern&int&blinkm_main(int&argc,&char&*argv[]);extern&int&boardinfo_main(int&argc,&char&*argv[]);extern&int&ets_airspeed_main(int&argc,&char&*argv[]);extern&int&fmu_main(int&argc,&char&*argv[]);extern&int&gps_main(int&argc,&char&*argv[]);extern&int&hil_main(int&argc,&char&*argv[]);extern&int&hmc5883_main(int&argc,&char&*argv[]);extern&int&l3gd20_main(int&argc,&char&*argv[]);extern&int&ll40ls_main(int&argc,&char&*argv[]);extern&int&lsm303d_main(int&argc,&char&*argv[]);extern&int&mb12xx_main(int&argc,&char&*argv[]);extern&int&meas_airspeed_main(int&argc,&char&*argv[]);extern&int&mixer_main(int&argc,&char&*argv[]);extern&int&mkblctrl_main(int&argc,&char&*argv[]);extern&int&mpu6000_main(int&argc,&char&*argv[]);extern&int&ms5611_main(int&argc,&char&*argv[]);extern&int&mtd_main(int&argc,&char&*argv[]);extern&int&nshterm_main(int&argc,&char&*argv[]);extern&int&perf_main(int&argc,&char&*argv[]);extern&int&pwm_main(int&argc,&char&*argv[]);extern&int&px4io_main(int&argc,&char&*argv[]);extern&int&reboot_main(int&argc,&char&*argv[]);extern&int&rgbled_main(int&argc,&char&*argv[]);extern&int&tests_main(int&argc,&char&*argv[]);extern&int&tone_alarm_main(int&argc,&char&*argv[]);extern&int&top_main(int&argc,&char&*argv[]);extern&int&uorb_main(int&argc,&char&*argv[]);const&struct&builtin_s g_builtins[]&=&{&&&&{&sercon&, SCHED_PRIORITY_DEFAULT,&2048, sercon_main},&&&&{&serdis&, SCHED_PRIORITY_DEFAULT,&2048, serdis_main},&&&&{&ArduPilot&, SCHED_PRIORITY_DEFAULT,&4096, ArduPilot_main},&&&&{&adc&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, adc_main},&&&&{&auth&, SCHED_PRIORITY_DEFAULT,&64000, auth_main},&&&&{&bl_update&, SCHED_PRIORITY_DEFAULT,&4096, bl_update_main},&&&&{&blinkm&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, blinkm_main},&&&&{&boardinfo&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, boardinfo_main},&&&&{&ets_airspeed&, SCHED_PRIORITY_DEFAULT,&2048, ets_airspeed_main},&&&&{&fmu&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, fmu_main},&&&&{&gps&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, gps_main},&&&&{&hil&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, hil_main},&&&&{&hmc5883&, SCHED_PRIORITY_DEFAULT,&4096, hmc5883_main},&&&&{&l3gd20&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, l3gd20_main},&&&&{&ll40ls&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, ll40ls_main},&&&&{&lsm303d&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, lsm303d_main},&&&&{&mb12xx&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, mb12xx_main},&&&&{&meas_airspeed&, SCHED_PRIORITY_DEFAULT,&2048, meas_airspeed_main},&&&&{&mixer&, SCHED_PRIORITY_DEFAULT,&4096, mixer_main},&&&&{&mkblctrl&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, mkblctrl_main},&&&&{&mpu6000&, SCHED_PRIORITY_DEFAULT,&4096, mpu6000_main},&&&&{&ms5611&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, ms5611_main},&&&&{&mtd&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, mtd_main},&&&&{&nshterm&, SCHED_PRIORITY_DEFAULT,&3000, nshterm_main},&&&&{&perf&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, perf_main},&&&&{&pwm&, SCHED_PRIORITY_DEFAULT,&4096, pwm_main},&&&&{&px4io&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, px4io_main},&&&&{&reboot&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, reboot_main},&&&&{&rgbled&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, rgbled_main},&&&&{&tests&, SCHED_PRIORITY_DEFAULT,&12000, tests_main},&&&&{&tone_alarm&, SCHED_PRIORITY_DEFAULT, CONFIG_PTHREAD_STACK_DEFAULT, tone_alarm_main},&&&&{&top&, SCHED_PRIORITY_DEFAULT,&3000, top_main},&&&&{&uorb&, SCHED_PRIORITY_DEFAULT,&4096, uorb_main},&&&&{NULL,&0,&0, NULL}};const&int&g_builtin_count&=&33;bitcraze@bitcraze-vm:~/apm/ardupilot/ArduCopter$
&我们看到头文件用的是&nuttx的,源文件里有一个数组,放的全是入口函数。显然这是给 nuttx系统用的。那么这些入口函数也就来自 nuttx系统。而且我们可以进一步确定,这些入口是应用程序的,而非驱动的。&&& 看到这里我就在想,从这段 Makefile中我们是不是可以认为 IO板是以裸机的方式在运行?我认为应该是可以的。&&& 如果我们继续修改 Makefile进行调试,我们会发现:
define&LINK&@$(ECHO)&&LINK:&&&&$1&&@$(MKDIR)&-p $(dir $1)&$(ECHO)&&LINK1&# $(Q) $(LD) $(LDFLAGS)&-Map $1.map&-o $1&--start-group $2&$(LIBS) $(EXTRA_LIBS) $(LIBGCC)&--end-group&$(LD) $(LDFLAGS)&-Map $1.map&-o $1&--start-group $2&$(LIBS) $(EXTRA_LIBS) $(LIBGCC)&--end-group&$(ECHO)&&LINK2&endef# Convert $1&from a linked object to a raw binary in $2#define&SYM_TO_BIN&@$(ECHO)&&BIN:&&&&&$2&# @$(MKDIR)&-p $(dir $2)# $(Q) $(OBJCOPY)&-O binary $1&$2&$(MKDIR)&-p $(dir $2)&$(OBJCOPY)&-O binary $1&$2endef
LINK:&&& /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.elfLINK1arm-none-eabi-ld --warn-common --gc-sections& -T/home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/nuttx-export/build/ld.script -L/home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/nuttx-export/libs -Map /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.elf.map -o /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.elf --start-group /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build//home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/empty.c.o /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build//home/bitcraze/apm/PX4Firmware/src/drivers/boards/px4io-v2/module.pre.o /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build//home/bitcraze/apm/PX4Firmware/src/drivers/stm32/module.pre.o /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build//home/bitcraze/apm/PX4Firmware/src/modules/px4iofirmware/module.pre.o& -lapps&-lnuttx&/home/bitcraze/bin/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/armv7-m/libm.a /home/bitcraze/bin/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7-m/libgcc.a --end-groupLINK2BIN:&&&& /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.binmkdir -p /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/arm-none-eabi-objcopy -O binary /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.elf /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.bin%% Generating /home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build/firmware.px4make[2]: Leaving directory `/home/bitcraze/apm/PX4Firmware/Build/px4io-v2_default.build'%% Copying /home/bitcraze/apm/PX4Firmware/Images/px4io-v2_default.px4make[1]: Leaving directory `/home/bitcraze/apm/PX4Firmware'
这样我们就可以大概知道编译我们的 elf文件用到了那些源码。其中用到了几个库,最显眼的应该是&nuttx这个库,因为这个库很清楚地告诉了我我们的 IO板是跑系统的,而不是裸机运行。所以现在我有个疑问就是:“为什么运行在 Nuttx系统却不提供应用程序入口”?我想这也只有到源码中去寻找答案了。由于这里我们主要讨论的是 Makefile,暂时就不去深究了。&&& 另外一个是&apps库,剩下的两个都是编译器的库,对于编译器的库,我是直接掠过的。我们的这两个库是由&$(LIBS)指定的,都源自 Nuttx系统。那么他们是怎么来的呢?我们继续到 Makefile中去寻找答案。
################################################################################# NuttX libraries and paths################################################################################include&$(PX4_MK_DIR)/nuttx.mk
&这还是&firmware.mk中的内容,引用了外部的 mk文件 nuttx.mk。其中有这样一段内容:
## Use the linker script from the NuttX export#LDSCRIPT&&+=&$(NUTTX_EXPORT_DIR)build/ld.script## Add directories from the NuttX export to the relevant search paths#INCLUDE_DIRS&&+=&$(NUTTX_EXPORT_DIR)include&\&&&&&&$(NUTTX_EXPORT_DIR)arch/chip \&&&&&&$(NUTTX_EXPORT_DIR)arch/commonLIB_DIRS&&+=&$(NUTTX_EXPORT_DIR)libsLIBS&&&+=&-lapps&-lnuttxNUTTX_LIBS&&&=&$(NUTTX_EXPORT_DIR)libs/libapps.a \&&&&&&$(NUTTX_EXPORT_DIR)libs/libnuttx.aLINK_DEPS&&+=&$(NUTTX_LIBS)$(NUTTX_CONFIG_HEADER):&$(NUTTX_ARCHIVE)&@$(ECHO)&%%&Unpacking $(NUTTX_ARCHIVE)&$(Q) $(UNZIP_CMD)&-q&-o&-d $(WORK_DIR) $(NUTTX_ARCHIVE)&$(Q) $(TOUCH) $@&$(LDSCRIPT):&$(NUTTX_CONFIG_HEADER)&$(NUTTX_LIBS):&$(NUTTX_CONFIG_HEADER)
&但是当我尝试去获取这两个库编译的细节的时候却失败了,具体原因不明。
5. px4-v2&&& 现在我们来看下 px4-v2的编译。&&& 核心板与 IO板在编译上存在一定的相似性。这里我们同样也可以构造一个目标 px4-v3来进行测试。
px4-v3:&showflags $(PX4_ROOT)/Archives/px4fmu-v2.export $(SKETCHCPP) module_mk&$(RULEHDR)&$(v) rm&-f $(PX4_ROOT)/makefiles/$(PX4_V2_CONFIG_FILE)&$(v) cp $(PWD)/$(PX4_V2_CONFIG_FILE) $(PX4_ROOT)/makefiles/&$(PX4_MAKE) px4fmu-v2_APM&$(v)&/bin/rm&-f $(SKETCH)-v2.px4&$(v) cp $(PX4_ROOT)/Images/px4fmu-v2_APM.px4 $(SKETCH)-v2.px4&$(v) echo&&PX4 $(SKETCH) Firmware is in $(SKETCH)-v2.px4&&&showflags:&@echo&&HAL_BOARD=$(HAL_BOARD) HAL_BOARD_SUBTYPE=$(HAL_BOARD_SUBTYPE) TOOLCHAIN=$(TOOLCHAIN) EXTRAFLAGS=$(EXTRAFLAGS)&$(PX4_ROOT)/Archives/px4fmu-v2.export:&$(v) $(PX4_MAKE_ARCHIVES).PHONY:&module_mk## Build the sketch.cpp file$(SKETCHCPP): showflags $(SKETCHCPP_SRC)&@echo &building $(SKETCHCPP)&&$(RULEHDR)&$(v)$(AWK) -v mode=header '$(SKETCH_SPLITTER)'&& $(SKETCHCPP_SRC) &&&&$(v)echo &#line 1 \&autogenerated\&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&$(v)$(AWK)&&&&&&&&&&&&&&& '$(SKETCH_PROTOTYPER)' $(SKETCHCPP_SRC) &&&&$(v)$(AWK) -v mode=body&& '$(SKETCH_SPLITTER)'&& $(SKETCHCPP_SRC) &&&&$(v)cmp $@&&& /dev/null 2&&1 || mv&&$@&$(v)rm -f&module_mk:&$(RULEHDR)&$(v) echo&&# Auto-generated file - do not edit&&&&$(SKETCHBOOK)/module.mk.new&$(v) echo&&MODULE_COMMAND = ArduPilot&&&&&$(SKETCHBOOK)/module.mk.new&$(v) echo&&SRCS = Build.$(SKETCH)/$(SKETCH).cpp $(SKETCHLIBSRCSRELATIVE)&&&&&$(SKETCHBOOK)/module.mk.new&$(v) echo&&MODULE_STACKSIZE = 4096&&&&&$(SKETCHBOOK)/module.mk.new&$(v) cmp $(SKETCHBOOK)/module.mk $(SKETCHBOOK)/module.mk.new&2&/dev/null&||&mv $(SKETCHBOOK)/module.mk.new&$(SKETCHBOOK)/module.mk&$(v) rm&-f $(SKETCHBOOK)/module.mk.new
其中,我们裁掉了对 IO板的依赖。&&& 那么这几个一来都分别做了哪些事情呢?第一个最明显,打印了编译的相关信息。其它的我们都需要经过一些测试。通过测试我们知道 “$(PX4_ROOT)/Archives/px4fmu-v2.export”是用来编译 Nuttx系统的,编译命令为 “make -C /home/bitcraze/apm/PX4Firmware NUTTX_SRC=/home/bitcraze/apm/PX4NuttX/nuttx/ archives MAXOPTIMIZATION=&-Os&”,也就是编译 archives目标; “$(SKETCHCPP)”用于生成源文件 “ardupilot/Build.ArduCopter/ArduCopter.cpp”,这部分 Makefile在 sketch_sources.mk文件中。是在 apm.mk中 include进来的。 “module_mk”则是用来生成 “ardupilot/module.mk”文件。该文件定义了三个变量:MODULE_COMMAND, SRCS, MODULE_STACKSIZE。从字面上看分别是模块命令、源文件和模块的堆栈大小。关于这几个变量的作用,我们后面会看到。&&& 当所有的这些依赖都被满足,便通过 “$(PX4_MAKE) px4fmu-v2_APM”命令进行编译。
PX4_MAKE&=&$(v) GIT_SUBMODULES_ARE_EVIL=1&make&-C $(SKETCHBOOK)&-f $(PX4_ROOT)/Makefile EXTRADEFINES=&$(SKETCHFLAGS) $(WARNFLAGS) &'$(EXTRAFLAGS)'&APM_MODULE_DIR=$(SKETCHBOOK) SKETCHBOOK=$(SKETCHBOOK) PX4_ROOT=$(PX4_ROOT) NUTTX_SRC=$(NUTTX_SRC) MAXOPTIMIZATION=&-Os&
&该命令展开之后很长,主要是头文件很多。将头文件去掉,剩下的命令为:
GIT_SUBMODULES_ARE_EVIL=1&make&-C&/home/bitcraze/apm/ardupilot&-f&/home/bitcraze/apm/PX4Firmware/Makefile&-DARDUPILOT_BUILD&-DCONFIG_HAL_BOARD=HAL_BOARD_PX4&-DSKETCHNAME=\&ArduCopter\&&-DSKETCH_MAIN=ArduPilot_main&-DAPM_BUILD_DIRECTORY=APM_BUILD_ArduCopter&-Wno-psabi&-Wno-packed&-Wno-error=double-promotion&-Wno-error=unused-variable&-Wno-error=unused-but-set-variable&-Wno-error=reorder&-DGIT_VERSION=&\&b6d361a3\&&&-DNUTTX_GIT_VERSION=&\&eba6b56f\&&&-DPX4_GIT_VERSION=&\&cf208916\&&APM_MODULE_DIR=/home/bitcraze/apm/ardupilot SKETCHBOOK=/home/bitcraze/apm/ardupilot PX4_ROOT=/home/bitcraze/apm/PX4Firmware NUTTX_SRC=/home/bitcraze/apm/PX4NuttX/nuttx/MAXOPTIMIZATION=-Os
可以看到,命令依然很长。这里我们编译使用的头文件是 “PX4Firmware/Makefile”,编译目标为默认 all目标。但是
## Built products#DESIRED_FIRMWARES&&&=&$(foreach config,$(CONFIGS),$(IMAGE_DIR)$(config).px4)STAGED_FIRMWARES&&=&$(foreach config,$(KNOWN_CONFIGS),$(IMAGE_DIR)$(config).px4)FIRMWARES&&&=&$(foreach config,$(KNOWN_CONFIGS),$(BUILD_DIR)$(config).build/firmware.px4)all:&&&$(DESIRED_FIRMWARES)
&“$(DESIRED_FIRMWARES)”的值为: “PX4Firmware/Images/px4fmu-v2_APM.px4”。过程不清楚,但可以确定的是最后还是匹配了 “$(FIRMWARES)”这个目标。于是下面有顺理成章地回到了 “firmware.mk”。 “firmware.mk”前面我们已经简单分析过期编译流程了。跟 IO板相比主要有两个不同,一是此时 “$(BUILTIN_COMMANDS)”值不为空,也就是会生成 builtin_commands.c文件;二是 “$(MODULE_OBJS)”值不一样,其值包含了 PX4的各种模块,如传感器, PWM。模块多了编译的东西自然也就多了。这些模块在核心板看来就是命令。
## Transitional support&-&add commands from the NuttX export archive.## In general, these should move to modules over time.## Each entry here is&&command&.&priority&.&stacksize&.&entrypoint&&but we use a helper macro# to make the table a bit more readable.#define&_B&$(strip $1).$(or $(strip $2),SCHED_PRIORITY_DEFAULT).$(or $(strip $3),CONFIG_PTHREAD_STACK_DEFAULT).$(strip $4)endef#&&&&&&&&&&&&&&&&&&command&&&&&&&&&&&&&&&&&priority&&&&&&&&&&&&&&&&&&&stack&&entrypointBUILTIN_COMMANDS&:=&\&$(call _B, sercon,&&&&&&&&&&&&&&&&&,&&&&&&&&&&&&&&&&&&&&&&&&&&2048,&&sercon_main&&&&&&&&&&&&&&&&) \&$(call _B, serdis,&&&&&&&&&&&&&&&&&,&&&&&&&&&&&&&&&&&&&&&&&&&&2048,&&serdis_main&&&&&&&&&&&&&&&&)
我们可以通过研究这段 Makefile去了解 “$(BUILTIN_COMMANDS)”的值是怎么来的,只是我现在可没这功夫去研究它。因为这段 Makefile在 IO板中根本就不存在,其值也就为空了。那么下面我们来看看 “$(MODULE_OBJS)”是怎么编译的。&&& “$(MODULE_OBJS)”是 “$(PRODUCT_ELF)”的依赖,所以当 “$(PRODUCT_ELF)”需要编译的时候, “$(MODULE_OBJS)”也会被编译。
# make a list of module makefiles and check that we found them allMODULE_MKFILES&&:=&$(foreach module,$(MODULES),$(call MODULE_SEARCH,$(module)))MISSING_MODULES&&:=&$(subst MISSING_,,$(filter MISSING_%,$(MODULE_MKFILES)))ifneq ($(MISSING_MODULES),)$(error Can't find module(s): $(MISSING_MODULES))endif# Make a list of the object files we expect to build from modules# Note that this path will typically contain a double-slash at the WORK_DIR this must be# preserved as it is used below to get the absolute path for the module.mk file correct.#MODULE_OBJS&&:= $(foreach path,$(dir $(MODULE_MKFILES)),$(WORK_DIR)$(path)module.pre.o)# rules to build module objects.PHONY: $(MODULE_OBJS)$(MODULE_OBJS):&&relpath = $(patsubst $(WORK_DIR)%,%,$@)$(MODULE_OBJS):&&mkfile = $(patsubst %module.pre.o,%module.mk,$(relpath))$(MODULE_OBJS):&&workdir = $(@D)$(MODULE_OBJS):&&$(GLOBAL_DEPS) $(NUTTX_CONFIG_HEADER)&$(Q) $(MKDIR) -p $(workdir)&$(Q) $(MAKE) -r -f $(PX4_MK_DIR)module.mk \&&-C $(workdir) \&&MODULE_WORK_DIR=$(workdir) \&&MODULE_OBJ=$@ \&&MODULE_MK=$(mkfile) \&&MODULE_NAME=$(lastword $(subst /, ,$(workdir))) \&&module
通过注释我们知道这段 Makefile是用来编译 module的。对 “MODULE_OBJS”进行跟踪,我们发现数据最终源自 “$(MODULES)”,那么这又是一个什么变量,它的值又是什么呢?&&& 这就是 “PX4Firmware/makefiles/”目录下那些 “config”开头的 mk文件。例如 IO板 “config_px4io-v2_default.mk”内容如下:
## Makefile&for&the px4iov2_default configuration### Board support modules#MODULES&&+=&drivers/stm32MODULES&&+=&drivers/boards/px4io-v2MODULES&&+=&modules/px4iofirmware
而处理到最后, “mkfile”存放的是个模块目录下的 “module.mk”文件。而最后编译使用的 mk文件为: “PX4Firmware/makefiles/module.mk”,目标为:
################################################################################# Build rules################################################################################## What we're going to build#module:&&&$(MODULE_OBJ) $(MODULE_COMMAND_FILES)## Object files we will generate from sources#OBJS&&&&= $(addsuffix .o,$(SRCS))## Dependency files that will be auto-generated#DEPS&&&&= $(addsuffix .d,$(SRCS))## SRCS -& OBJS rules#$(OBJS):&&$(GLOBAL_DEPS)vpath %.c $(MODULE_SRC)$(filter %.c.o,$(OBJS)): %.c.o: %.c $(GLOBAL_DEPS)&$(call COMPILE,$&,$@)vpath %.cpp $(MODULE_SRC)$(filter %.cpp.o,$(OBJS)): %.cpp.o: %.cpp $(GLOBAL_DEPS)&$(call COMPILEXX,$&,$@)vpath %.S $(MODULE_SRC)$(filter %.S.o,$(OBJS)): %.S.o: %.S $(GLOBAL_DEPS)&$(call ASSEMBLE,$&,$@)## Built product rules#$(MODULE_OBJ):&&$(OBJS) $(GLOBAL_DEPS)&$(call PRELINK,$@,$(OBJS))
&这里是将各自的源文件编译成各自的目标文件,即 &*.o&文件。而这许多个目标文件最后又通过 “PRELINK”链接成一个目标文件,也就是 “module.pre.o”。&&& 而通过 “$(MODULE_COMMAND_FILES)”会输出这样一些信息:
CMD:&&&&&l3gd20CMD:&&&&&ll40lsCMD:&&&&&mpu6000CMD:&&&&&ms5611CMD:&&&&&fmuCMD:&&&&&px4ioCMD:&&&&&reboot
也就是说 module并不特指硬件,正确的理解应当是应用程序。然而在操作系统里边像 Linux应用程序可以在 shell中以命令的方式进行调用,于是这里称之为命令也就不奇怪了。6. archives&&& “$(PX4_ROOT)/Archives/px4fmu-v2.export”是 px4-v2的又一个依赖,前面我们已经知道其编译的命令为: “make -C /home/bitcraze/apm/PX4Firmware NUTTX_SRC=/home/bitcraze/apm/PX4NuttX/nuttx/ archives MAXOPTIMIZATION=&-Os&”,我们找到 “archives”目标:
## Build the NuttX export archives.## Note that there are no&explicit&dependencies extended from these# archives. If NuttX is updated, the user is expected to rebuild the&# archives/build area manually. Likewise, when the&'archives'&target is# invoked, all archives are always rebuilt.## XXX Should support fetching/unpacking from a separate directory to permit#&&&&&downloads of the prebuilt archives as well...#NUTTX_ARCHIVES&&&=&$(foreach board,$(BOARDS),$(ARCHIVE_DIR)$(board).export).PHONY:&&&archivesarchives:&&$(NUTTX_ARCHIVES)# We cannot
note that we also force&-j1&for&the# sub-make invocations.ifneq ($(filter archives,$(MAKECMDGOALS)),).NOTPARALLEL:endif$(ARCHIVE_DIR)%.export:&board&=&$(notdir $(basename $@))$(ARCHIVE_DIR)%.export:&configuration&=&nsh$(NUTTX_ARCHIVES):&$(ARCHIVE_DIR)%.export:&$(NUTTX_SRC)&@$(ECHO)&%%&Configuring NuttX&for&$(board)&$(Q) (cd $(NUTTX_SRC)&&&&$(RMDIR) nuttx-export)&$(Q) $(MAKE)&-r&-j1&-C $(NUTTX_SRC)&-r $(MQUIET) distclean&$(Q) (cd $(NUTTX_SRC)/configs&&&&$(COPYDIR) $(PX4_BASE)nuttx-configs/$(board) .)&$(Q) (cd $(NUTTX_SRC)tools&&&&./configure.sh $(board)/$(configuration))&@$(ECHO)&%%&Exporting NuttX&for&$(board)&$(Q) $(MAKE)&-r&-j1&-C $(NUTTX_SRC)&-r $(MQUIET) CONFIG_ARCH_BOARD=$(board) export&$(Q) $(MKDIR)&-p $(dir $@)&$(Q) $(COPY) $(NUTTX_SRC)nuttx-export.zip $@&$(Q) (cd $(NUTTX_SRC)/configs&&&&$(RMDIR) $(board))
&于是最终将跳转到 “PX4NuttX/nuttx/”目的对 Nuttx进行编译。关于 Nuttx的编译就在这里点到为止,暂不做过深入的分析。7. $(SKETCHCPP)
## Build the sketch.cpp file$(SKETCHCPP):&showflags $(SKETCHCPP_SRC)&@echo&&building $(SKETCHCPP)&&$(RULEHDR)&$(v)$(AWK)&-v mode=header&'$(SKETCH_SPLITTER)'&&&$(SKETCHCPP_SRC)&&&&$@.new&$(v)echo&&#line 1 \&autogenerated\&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$@.new&$(v)$(AWK)&&&&&&&&&&&&&&&&'$(SKETCH_PROTOTYPER)'&$(SKETCHCPP_SRC)&&&&$@.new&$(v)$(AWK)&-v mode=body&&&'$(SKETCH_SPLITTER)'&&&$(SKETCHCPP_SRC)&&&&$@.new&$(v)cmp $@ $@.new&&&/dev/null&2&&1&||&mv $@.new&$@&$(v)rm&-f $@.new
这部分 Makefile其实只做了一件事,那就是 “ardupilot/Build.ArduCopter/ArduCopter.cpp”文件,而 “$(SKETCHCPP_SRC)”就是所有的这些 pde文件。也就是说 “ardupilot/ArduCopter”目录下的源文件最终将被处理成一个 ArduCopter.cpp文件进行编译。&&& 分析到这里,编译流程基本告一段路了,剩下的一些东西我们后面分析会借助源码进行理解。}

我要回帖

更多关于 洛杉矶住哪里方便 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信