cruelfox 发表于 2019-5-18 23:12

【STM32WB55 测评】BLE_p2pServer工程提取&编译

<div class='showpostmsg'>  CubeWB 当中提供了不少的例子,可以给软件开发环境直接使用。支持三种IDE——IAR EWARM, MDK-ARM 和 SW4STM32. 后者是用GCC编译器的。我没有这些开发环境,一贯是用GCC+make直接搞,所以要费一番工夫了。当然是利用 SW4STM32 例子作为参考,这里有GCC需要用到的启动文件和链接脚本。
  先练练手,就自己编译 Nucleo 上面带的 BLE_p2pServer 工程,好检验效果。目录是 CubeWB 软件包的 Projects\NUCLEO-WB55.Nucleo\Applications\BLE\BLE_p2pServer,里面的目录树结构如下:
├─Binary
├─Core
│├─Inc
│└─Src
├─EWARM
├─MDK-ARM
├─STM32_WPAN
│├─App
│└─Target
└─SW4STM32
    └─BLE_p2pServer
这里,Binary目录有一个编译好的 HEX 文件可作为参照。万一搞砸了搞不定可以拿它烧回板子去,恢复功能。Core 目录和 STM32_WPAN 目录下面都是源代码,其余目录就是不同开发环境各自的工程文件了。

  我的目的是自己写一个 Makefile, 然后在命令行上执行一下 make 命令就可以编译完整个工程的文件,以后每次修改以后再 make 就可以。如果有 SW4STM32 的话我猜想它会生成一个 Makefile, 可惜我没有(曾经想下载,没成功)。然后呢,把用到的比如 HAL 库,无线库中的文件提取出来另外存放(我不想保留庞大的库的目录树,平常也不用),供编译现有工程和以它们为参照的开发。

  光有 Core 和 STM32_WPAN 两个子目录的文件必然不够。用到的大量函数库的文件并不在这里,比如在 CubeWB 包中的 Drivers 目录下。对于头文件,可以根据工程源文件里面所有 #include 的线索去找,然后把这些文件搜集起来,另存放在一个目录下(因为ST的库大,文件多,并不是都用得着的);对于 .c 文件,只能在链接的时候根据缺失的符号(函数名或全局变量)去找它们在哪个文件里面——这两种都接近于“人肉”操作,当然自己写个工具程序来做也是可以。按照我以往的经验,对付 HAL 库这种的引用,费点手工就能搞定了。结果确实如此,HAL库的目录树还是简单的。然而,对于 WPAN 库,就是无线功能部分,我就搞不定了:文件太多,出现了编译错误,在没有报告头文件缺失的情况下就缺了类型定义。

  于是放弃“人肉”,从 SW4STM32 工程的文件里面下手。这里的 .project 和 .cproject 两个文件是 XML 文件,当文本看是可以的。不难找到,所有的 include 的路径都写在里面了:

  WPAN库 有那么多个子目录要包含,“人肉”搞果然不方便(后来发现原因是,不同目录下的头文件有重名的,难怪我会找错了)。于是我把这些路径都写到我的编译命令行参数 -I 中去,就可以顺利编译了。先借用原始的库目录树完成编译,再提取文件。

  下面的问题是怎样确定那些 .c 文件是需要的。在工程文件中必然有线索,如下面这种:

  那么把文本处理一下,不难得到文件列表了。按目录再整理整理,我的 Makefile 就差不多了。

default: test.hex

CC =arm-none-eabi-gcc -c
LD =arm-none-eabi-gcc -nostdlib
CFLAGS =-g -O2 -Wall -mcpu=cortex-m4 -mthumb -DSTM32WB55xx -DUSE_STM32WBXX_NUCLEO -ffunction-sections -fdata-sections
LDFLAGS=-mcpu=cortex-m4 -mthumb -T ../stm32wb55xx_flash_cm4.ld -Wl,--gc-sections
INC =-I. -IWPAN -I../../ST -I../../CMSIS -I../BSP -I../HAL -I../radio/Inc

APPOBJ = main.o \
         app_entry.o \
         hw_lpm.o \
         hw_timerserver.o \
         hw_uart.o \
         stm32wbxx_hal_msp.o \
         stm32wbxx_it.o \
         app_ble.o \
         p2p_server_app.o \
         hw_ipcc.o \
         stm32wbxx_nucleo.o
         
HALOBJ = hal/stm32wbxx_hal.o\
         hal/stm32wbxx_hal_cortex.o \
         hal/stm32wbxx_hal_pwr.o \
         hal/stm32wbxx_hal_pwr_ex.o \
         hal/stm32wbxx_hal_rcc.o \
         hal/stm32wbxx_hal_rcc_ex.o \
         hal/stm32wbxx_hal_uart.o \
         hal/stm32wbxx_hal_uart_ex.o \
         hal/stm32wbxx_hal_gpio.o \
         hal/stm32wbxx_hal_dma.o \
         hal/stm32wbxx_hal_rtc.o \
         hal/stm32wbxx_hal_rtc_ex.o

BLEOBJ = radio/ble_gap_aci.o \
         radio/ble_gatt_aci.o \
         radio/ble_hal_aci.o \
         radio/ble_hci_le.o \
         radio/ble_l2cap_aci.o \
         radio/dbg_trace.o \
         radio/hci_tl.o \
         radio/lpm.o \
         radio/osal.o \
         radio/otp.o \
         radio/p2p_stm.o \
         radio/scheduler.o \
         radio/shci.o \
         radio/shci_tl.o \
         radio/stm_list.o \
         radio/stm_queue.o \
         radio/svc_ctl.o \
         radio/tl_if.o \
         radio/tl_mbox.o

test.elf : $(APPOBJ) system_stm32wbxx.o startup_stm32wb55xx_cm4.o $(HALOBJ) $(BLEOBJ)
    $(LD) $(LDFLAGS) $^ -o $@

%.o : ../%.s
    $(CC) $(CFLAGS) $<

%.o : %.c
    $(CC) $(CFLAGS) $(INC) $<

%.o : WPAN/%.c
    $(CC) $(CFLAGS) $(INC) $<

%.o : ../BSP/%.c
    $(CC) $(CFLAGS) $(INC) $<

hal/%.o : ../HAL/%.c
    $(CC) $(CFLAGS) $(INC) $< -o $@

radio/%.o : ../radio/%.c
    $(CC) $(CFLAGS) $(INC) $< -o $@

%.hex : %.elf
    arm-none-eabi-objcopy -Oihex $< $@


  radio 子目录用来放 WPAN 库中提取出来的文件,把原始的目录树放弃了,简化嘛,毕竟也记不住。好在 .c 文件数量并不很多。radio/Inc 目录里面的头文件是后来确定后放进去的,用到哪些头文件在SW4STM32的工程文件里面并没有写。

  各个文件编译完成后在链接时出错了,报告说 _read, _lseek 等函数找不到。无疑,这是工程里面用了 printf 引起的,C标准库文件系统的函数。我找到的解决办法是在 stm32wb55xx_flash_cm4.ld 中在那几个库文件列表处补充了一行 libnosys.a ( * )

  终于得到了 HEX 文件。烧进板子去运行,Dongle 能连上它。但遗留问题是:虚拟串口没有信息输出,很可能还是 printf 相关的问题。
另外还有一个现象是,我生成的 HEX 文件要比 ST 提供的参考文件大 60% 多,编译器的差异也太明显了?

  头文件的提取,最后我用了访问时间戳的办法,在一次全部编译的前后根据文件的访问时间变化来查找被用到的头文件。于是,WPAN 库的文件得到了精简。提取后目录树如下:
│startup_stm32wb55xx_cm4.s
│stm32wb55xx_flash_cm4.ld

├─BLE_p2pServer
││app_common.h
││app_conf.h
││app_entry.c
││app_entry.h
││hw_conf.h
││hw_lpm.c
││hw_timerserver.c
││hw_uart.c
││main.c
││main.h
││Makefile
││stm32wbxx_hal_conf.h
││stm32wbxx_hal_msp.c
││stm32wbxx_it.c
││stm32wbxx_it.h
││system_stm32wbxx.c
││utilities_conf.h
││
│├─hal
│├─radio
│└─WPAN
│          app_ble.c
│          app_ble.h
│          ble_conf.h
│          ble_dbg_conf.h
│          hw_ipcc.c
│          p2p_server_app.c
│          p2p_server_app.h
│         
├─BSP
│      stm32wbxx_nucleo.c
│      stm32wbxx_nucleo.h
│      
├─HAL
││stm32wbxx_hal.c
││stm32wbxx_hal.h
││stm32wbxx_hal_cortex.c
││stm32wbxx_hal_cortex.h
││stm32wbxx_hal_def.h
││stm32wbxx_hal_dma.c
││stm32wbxx_hal_dma.h
││stm32wbxx_hal_dma_ex.h
││stm32wbxx_hal_flash.h
││stm32wbxx_hal_flash_ex.h
││stm32wbxx_hal_gpio.c
││stm32wbxx_hal_gpio.h
││stm32wbxx_hal_gpio_ex.h
││stm32wbxx_hal_hsem.h
││stm32wbxx_hal_ipcc.h
││stm32wbxx_hal_pwr.c
││stm32wbxx_hal_pwr.h
││stm32wbxx_hal_pwr_ex.c
││stm32wbxx_hal_pwr_ex.h
││stm32wbxx_hal_rcc.c
││stm32wbxx_hal_rcc.h
││stm32wbxx_hal_rcc_ex.c
││stm32wbxx_hal_rcc_ex.h
││stm32wbxx_hal_rtc.c
││stm32wbxx_hal_rtc.h
││stm32wbxx_hal_rtc_ex.c
││stm32wbxx_hal_rtc_ex.h
││stm32wbxx_hal_uart.c
││stm32wbxx_hal_uart.h
││stm32wbxx_hal_uart_ex.c
││stm32wbxx_hal_uart_ex.h
││stm32wbxx_ll_bus.h
││stm32wbxx_ll_cortex.h
││stm32wbxx_ll_crs.h
││stm32wbxx_ll_dma.h
││stm32wbxx_ll_dmamux.h
││stm32wbxx_ll_exti.h
││stm32wbxx_ll_hsem.h
││stm32wbxx_ll_ipcc.h
││stm32wbxx_ll_pwr.h
││stm32wbxx_ll_rcc.h
││stm32wbxx_ll_system.h
││stm32wbxx_ll_utils.h
││
│└─Legacy
│          stm32_hal_legacy.h
│         
└─radio
    │ble_gap_aci.c
    │ble_gatt_aci.c
    │ble_hal_aci.c
    │ble_hci_le.c
    │ble_l2cap_aci.c
    │dbg_trace.c
    │hci_tl.c
    │lpm.c
    │osal.c
    │otp.c
    │p2p_stm.c
    │scheduler.c
    │shci.c
    │shci_tl.c
    │stm_list.c
    │stm_queue.c
    │svc_ctl.c
    │tl_if.c
    │tl_mbox.c
    │
    └─Inc
            ble.h
            ble_common.h
            ble_const.h
            ble_defs.h
            ble_gap.h
            ble_gap_aci.h
            ble_gatt_aci.h
            ble_gatt_server.h
            ble_hal.h
            ble_hal_aci.h
            ble_hci_le.h
            ble_l2cap_aci.h
            ble_status.h
            ble_types.h
            bls.h
            common_blesvc.h
            compiler.h
            crs_stm.h
            dbg_trace.h
            dis.h
            eds_stm.h
            hal_types.h
            hci_const.h
            hci_tl.h
            hids.h
            hrs.h
            hts.h
            hw.h
            ias.h
            link_layer.h
            lls.h
            lpm.h
            mbox_def.h
            mesh.h
            osal.h
            otas_stm.h
            otp.h
            p2p_stm.h
            scheduler.h
            shci.h
            shci_tl.h
            stm32_wpan_common.h
            stm_list.h
            stm_queue.h
            svc_ctl.h
            template_stm.h
            tl.h
            tps.h
            utilities_common.h
            uuid.h



此内容由EEWORLD论坛网友cruelfox原创,如需转载或用于商业用途需征得作者同意并注明出处


</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

cruelfox 发表于 2019-5-18 23:17

上面贴的代码中有一个 -$@被论坛系统识别为 URL, 然后帖子就要审核了 :lol

cruelfox 发表于 2019-5-20 22:43

我遇到的 printf 输出没有到串口的问题: 将 dbg_trace.c 中定义的 __write() 函数改名为 _write() 就好了. 这是C标准库实现的差异.
页: [1]
查看完整版本: 【STM32WB55 测评】BLE_p2pServer工程提取&编译