[原创] 【基于KW41Z的环境传感器】第1贴 - MCUXpresso 新建工程经验分享

liyuyao001   2017-6-29 18:24 楼主
拿到FRDM-KW41Z开发板后,按照NXP网站的Getting Started Guide,上手试了试板子的Demo,有几个蓝牙的Demo无法和手机正常通信,比如Running Speed and Cadence, 有的Demo没有App上的对应选型,但是其他的几个都比较正常,蓝牙配对和很快。 我的比赛项目是用KW41Z做一个环境传感器,先从温湿度传感器开始,计划第一步先实现温湿度的正常读取和解析,然后可以通过BLE将数据发送到手机的BLE调试助手,再下一步,可以考虑用Raspberry Pi做一个网关,把BLE的数据发送到云服务,然后通过手机App可以在远程查看数据,并且可以在设定的触发条件满足的时候收到消息推送。 第一步,当然是要有一个KW41Z的工程。我当然也计划在Demo程序的基础上修改,这样最节省时间,其实Demo程序中的Blood Pressure,Health Thermometer等都可以拿过来直接改。 但是,我的强迫症告诉我,自己的工程名字一定要自己起,编译出来的代码一定要和自己的工程名一致。所以,我凭借自己有之前用基于Eclipse的IDE开发的经验,就那MCUXpresso来新建一个工程,然后拷贝示例工程的代码到里面去,然后解决依赖关系,成功编译。 但是想法总是美好的,现实往往很残酷,本来认为简单的操作却花掉我不少时间,走了不少弯路,好在终于还是成功了。在过程中有很多操作写下来当个手把手教程,给没有用过MCUXpresso这样基于Eclipse的IDE的童鞋参考,比如,如何设置include 路径,如何定义symbols,如何将不需要的源代码暂时排除编译,调试时如何查看register window等等。 1.打开MCUXpressoIDE,File->New->Project 1.jpeg 2.选择MCUXpressoIDE,New C/C++ Project 2.jpeg 3.弹出的Board and/or Device selection page中,选择KW4x和frdmkw41z SDK 3.jpeg 4.填写工程名字,我的工程名字是MKW41Z_BLE_Environmental_Sensor,我要使用FreeRTOS,虽然计划在NXP给的例程基础上修改,但是还是勾上。Board也选择“Default board files”,驱动勾选I2C,取消勾择“Enable Semihost”,点Next。 4.jpeg 5.勾掉Redirect SDK “PRINTF” to C library “printf”, 点finish 5.jpeg 6.生成后的工程内容如下,直接编译的话,是可以通过的,说明IDE的向导还是比较好用的,没有出现依赖问题。 6.jpeg 7.可以看到,里面并没有bluetooth的相关代码,我需要从示例工程中拷贝该文件夹到我的工程中来。我从示例工程frdmkw41z_wireless_examples_bluetooth_health_thermometer_freertos 中直接拷贝所有源代码文件夹到我的工程中,在IDE中,刷新一下,能够看到新的文件 7.jpeg 8.在IED中右键我的工程,Refresh,就能看到这些新加入的文件 8.jpeg 9.接下来,先测试工程是否可以正常编译,先把我的主函数所在文件MKW41Z_BLE_Environmental_Sensor.c 以及文件夹frdmkw41z在编译时排除,该文件点右键,Resources Configurations -> Exclude from build. 这样就不会编译时有重复的函数定义冲突了。另外startup文件夹中startup_mkw41z4.c也需要exclude from build。 9.jpeg 10.将bluetooth 和framwork等文件夹下面的源文件加入到编译中,有哪些文件路径,参考frdmkw41z_wireless_examples_bluetooth_health_thermometer_freertos这个示例,所以,在这个示例工程右键,选Properties,在C/C++ General中选择Paths and Symbols, 可以看到所有的Include路径 10.jpeg 11.我发现这里不能用windows的复制粘贴功能把这些路径拷贝出来,那么就只能用Export Settings了,将他们导出到我的工程中,名称叫做ffrdmkw41z_wireless_examples_bluetooth_health_thermometer_freertos.xml, 注意左上的Select Project一定要选中要从哪一个project导出,之前没有注意,我以为这里需要选择的是导出到哪一个Project,所以我选择了我的工程,所以发现总是不成功…… 11.jpeg 12.然后回到我自己的工程MKW41Z_BLE_Environmental_Sensor中,右键,Properties,在C/C++ General中选择Paths and Symbols,点Import Settings, 把那个.xml文件导进来 12.jpeg 12a.jpeg 13.再重新在我的工程MKW41Z_BLE_Environmental_Sensor中,右键,Properties,在C/C++ General中选择Paths and Symbols,可以看到,那些include路径加进来了 13.jpeg 14.我的工程中因为拷贝了board 文件夹,IDE生成的frdmkw41z文件夹已经不再使用,所以,可以删掉/${ProjName}/frdmkw41z 然后再在C/C++ General中选择Paths and Symbols,点Source Location->Add Folder, 把bluetooth,framework和board的文件夹加进来。 14.jpeg 14a.jpeg 15.看到我的工程中Libraries和Library Paths是空的,而示例工程中是包含了几个函数库的这应该还是需要加进来的。 15.jpeg 15a.jpeg 先从示例工程中把libs文件夹整个拷贝到自己的工程中,然后到自己的工程属性中把这些加进来, 15b.jpeg 15c.jpeg 15d.jpeg 16.之后编译工程,发现会出错 16.jpeg 打开app_preinclude.h文件,看到明明有定义BD_ADDR啊, 16a.jpeg 去参考工程中看看,发现了不同 16b.jpeg 发现整个app_preinclude.h文件里面的内容其实都被编译开关关掉了。因为在其他地方定义了这个符号 _APP_PREINCLUDE_H_ 16c.jpeg 那说明这个符号是在Eclipse中定义过了,但是找遍了#Symbols,以及C/C++ Build的Setting,并没有发现 16d.jpeg 那么就可能是eclipse显示有问题,实际上这个头文件并没有被编译开关关掉,只是因为app_preinclude.h没有在那些.c文件中包含才导致找不到声明。 使出大招,在整个workspace中搜索app_preinclude 16e.jpeg 终于找到了 16f.jpeg 然后,参照示例工程的.cproject 修改我自己工程的这两项 把两处gnu.c.compiler.option.misc.other 行中 name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/> 修改为 name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -imacros "${ProjDirPath}/source/app_preinclude.h"" valueType="string"/> 后来发现,这个设置在 C/C++ Build -> Settings -> MCU C Compiler -> Miscellaneous -> Other Flags中,复制示例工程中的命令即可 -c -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -imacros "${ProjDirPath}/source/app_preinclude.h" 17.再编译,还是有错误 17.jpeg 貌似是startup_MKW41Z4.S和startup_mkw41z4.c不同,因为我没有用IDE向导生成的startup_mkw41z4.c,但是并没有在工程属性中做相关配置,找到实例工程,C/C++ Build -> Settings -> Tools Settings -> MCU Linker -> Managed Linker Script 看到设定如下 17a.jpeg 而我的工程该设定勾选了Managed Linker Script,如下 17b.jpeg 需要按照示例工程修改成一样的,使用MKW41Z512xxx4_connectivity.ld这个linker script。 18.再编译,这个错误没有了,堆栈的错误没有了。但是依然有别的错误 18.jpeg 思路还是去看示例工程中是什么样的,在整个workspace搜索 “_start”, 18a.jpeg 结果如下 18b.jpeg 挨个仔细看了之后没有发现有用的信息。然后想,不就是个常量嘛,大不了把它改成立即数。 但是这个数是多少,需要想办法知道。 19.用单步调试功能,加个断点,看能不能在示例工程调试时看到寄存器的值。先在示例工程中__START 前面加个断点 19.jpeg 然后点击调试,restart 19a.jpeg 之后 step over执行到ldr r0,=__START 19b.jpeg 看到的确能执行到这里,太好了,接下来读寄存器的值就好了 20.打开寄存器窗口,Window -> Show View -> Other 20.jpeg Debug -> Registers 20a.jpeg 看到了R0的值,是0x481 20b.jpeg 21.修改自己工程中 _start 改为 0x481 21.jpeg 22.编译,成功! 22.jpeg 23.接下来把程序下载到板子中,看是否可以正常运行。结果发现运行不正常,卡死在了blx r0 处。 因此,肯定有地方还有问题,进入示例工程的调试页面,打开startup_MKW41Z4.S文件,在文件中右键,Open with -> Other…, 可以选择C/C++ Editor, 这样可以看到里面的变量信息和函数地址。 23.jpeg 23a.jpeg 然后鼠标放在_start 上,发现_start 实际上的值是0x480。,同样的,查看__libc_init_array的值和main的值分别为 0x2a300 和 0x23bb0, 这些是C函数的调用地址,当然不应该直接改成立即数,但是为了排查问题,先替换了试试看。 23b.jpeg 24.回到自己的工程中,把这几个函数地址直接用立即数写进去 24.jpeg 测试,可以正常编译,但是还是运行不正常……至此,想死的心都有了,折腾了好久,难不成只能放弃……… 25.打起精神来对比示例工程和自己的工程的所有配置,在找了若干遍之后,终于发现,C/C++ Build -> Settings -> Tools Settings -> MCU Linker -> General这里有不同。实例工程中勾掉了“No startup or default libs(-nostdlib)“ 25.jpeg 26.将我的工程中该勾取消掉,然后,把startup_MKW41Z4.S文件的所有绝对地址都改回函数名,就是用示例工程的startup_MKW41Z4.S文件。编译,终于不报错了。程序下载到板子中,终于迎来了三色LED欢快的闪烁! 按下评估板的SW4,进入配对,能够正常连接,终于成功。 26.jpeg 26a.jpeg 此内容由EEWORLD论坛网友liyuyao001原创,如需转载或用于商业用途需征得作者同意并注明出处 本帖最后由 liyuyao001 于 2017-7-24 23:40 编辑

回复评论 (6)

占沙发
点赞  2017-6-29 18:44
强迫症加油,还有20天
点赞  2017-6-30 09:47
管理员,我的帖子图片好像挂了。但是我现在无法编辑,能设置一下让我重新编辑一下吗?@nmg
点赞  2017-7-22 09:33

5楼 nmg 

引用: liyuyao001 发表于 2017-7-22 09:33
管理员,我的帖子图片好像挂了。但是我现在无法编辑,能设置一下让我重新编辑一下吗?@nmg

暂时给你版主权限,可以编辑了,你试一下
点赞  2017-7-22 14:05

重新一张张上传到了论坛,这回图片正常了
可以把版主权限拿掉了@nmg
点赞  2017-7-24 23:50

7楼 nmg 

引用: liyuyao001 发表于 2017-7-24 23:50
重新一张张上传到了论坛,这回图片正常了
可以把版主权限拿掉了@nmg

麻烦了,我找下技术帮忙看看什么原因
点赞  2017-7-28 10:16
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复