打印
[STM32F7]

【ST资源大分享】Linux下用CMAKE及exvim进行STM32开发

[复制链接]
1522|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
okyouwin|  楼主 | 2016-7-29 14:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 okyouwin 于 2016-7-29 14:41 编辑

最近有闲时,买了一个Jlink,老的Puppy圣诞版不支持,在http://www.minilinux.net/node/2583上下载了一个lina-1.1.iso

分享地址:http://pan.baidu.com/s/1dDwxZep,不到300M,可以打开PAE,我的机器是4G内存,本来想使用Veket,但它所有的版本都不支持PAE,所以否定了。

它本身的开发环境中包含CMake

主要的问题是Virtualbox不容易找,编译的话太浪费时间。最后在Puppy的英文论坛中下载了一个。http://shinobar.server-on.net/puppy/opt/pup5/

其它的软件都没有升级。wine使用的还是1.01版,里面的生成chm等程序直接把/root/.wine/文件夹拷贝过来就能用了,实在太绿色了。exVim使用的是0.5版。arm-none-eabi-gcc (Sourcery CodeBench Lite 2013.05-23) 4.7.3 ,感觉没有什么升级的必要……

STM32的库函数使用的是3.5版。

CMakeList.txt如下:

PROJECT(HELLO)
#显示更详细的错误列表
#SET( CMAKE_VERBOSE_MAKEFILE on )
SET(PERIPH_LIB /STM32F10x_StdPeriph_Lib_V3.5.0/)
INCLUDE_DIRECTORIES(
    ${PERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/
    ${PERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/
    ${PERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc/
    ${PERIPH_LIB}/Project/STM32F10x_StdPeriph_Template
)
INCLUDE_DIRECTORIES(
    ${PROJECT_SOURCE_DIR}/User/inc/
    ${PROJECT_SOURCE_DIR}/User/src/
    ${PROJECT_SOURCE_DIR}/DPV0_DRV/
    ${PROJECT_SOURCE_DIR}/DP_INC/
    ${PROJECT_SOURCE_DIR}/contiki/
    ${PROJECT_SOURCE_DIR}/contiki/sys
    ${PROJECT_SOURCE_DIR}/contiki/net
    ${PROJECT_SOURCE_DIR}/contiki/dev
    ${PROJECT_SOURCE_DIR}/contiki/ctk)
SET(PERIPH_LIB_SRC ${PERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/)
#SET(CMAKE_VERBOSE_MAKEFILE 0)
SET(CMAKE_SYSTEM_NAME Linux)
#SET(CMAKE_BUILD_TYPE DEBUG)
SET(CMAKE_BUILD_TYPE RELEASE)
SET(CMAKE_C_COMPILER "arm-none-eabi-gcc")
SET(CMAKE_LINKER "arm-none-eabi-ld ")
SET(CMAKE_OBJCOPY "arm-none-eabi-objcopy")
SET(CMAKE_OBJDUMP "arm-none-eabi-objdump")
SET(CMAKE_SIZE "arm-none-eabi-size")
SET(LINK_SCRIPT ${CMAKE_SOURCE_DIR}/stm32f10x.ld)
#SET(FAMILY "STM32F103xB")
#SET(LINK_SCRIPT "stm32f10x.ld")
SET(FAMILY "STM32F10X_MD")
#宏 MCU 型号 FLASH大小
#STM32F10X_LD STM32F101xx STM32F102xx STM32F103xx 16 ~ 32 Kbytes
#STM32F10X_MD STM32F101xx STM32F102xx STM32F103xx 64 ~ 128 Kbytes
#STM32F10X_HD STM32F101xx STM32F103xx             256 ~ 512 Kbytes
#STM32F10X_CL STM32F105xx STM32F107xx
#startup_stm32f10x_cl.s 互联型的器件,STM32F105xx,STM32F107xx
#startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx
#startup_stm32f10x_hd_vl.s 大容量的STM32F100xx
#startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx
#startup_stm32f10x_ld_vl.s 小容量的STM32F100xx
#startup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx
#startup_stm32f10x_md_vl.s 中容量的STM32F100xx  (我项目中用的是此款芯片 stm32f100CB)
#startup_stm32f10x_xl.s FLASH在512K到1024K字节的STM32F101xx,STM32F102xx,STM32F103xx
#(例如:像stm32f103re 这个型号的 芯片flash是512k 的, 启动文件用startup_stm32f10x_xl.s  或者startup_stm32f10x_hd.s  都可以;)
#
#cl:互联型产品,stm32f105/107系列
#vl:超值型产品,stm32f100系列
#xl:超高密度产品,stm32f101/103系列
#ld:低密度产品,FLASH小于64K
#md:中等密度产品,FLASH=64 or 128
#hd:高密度产品,FLASH大于128

#SET(DEBUG_FLAGS "-O0 -g")
#SET(DEBUG_FLAGS "-Os -finput-charset=GB2312 -fexec-charset=GB2312 ")
SET(DEBUG_FLAGS "-Os ")

SET(MCU_FLAGS "-march=armv7-m -mcpu=cortex-m3 -mthumb")
SET(CMAKE_C_FLAGS "${MCU_FLAGS} -fno-common -fno-builtin -ffreestanding -Wall ${DEBUG_FLAGS}")
#编译选项:
#-ffunction-sections              将函数放到自己的section中(链接时配合--gc-sections可以移除没有使用的函数)
#-fdata-sections                   将data放到自己的section中(链接时配合--gc-sections可以移除没有使用的data)
#-Wl,-Map=$(IMG_PATH)/$(IMG_MAP)                   生成指定的map文件
#-Wl,--gc-sections                                              移除唯有链接的内容
#-Wl,-T$(L_SCRIPT)                指定ld文件
#-mfloat-abi=soft    使用软件浮点运算库,链接时加入 libgcc.a
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib -mfloat-abi=soft -ffunction-sections -fdata-sections -Wl,-Map,${PROJECT_NAME}.map -Wl,--gc-sections")
#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-T${LINK_SCRIPT}")
#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
add_definitions(-D${FAMILY} -DUSE_STDPERIPH_DRIVER)
SET(CMAKE_EXE_LINKER_FLAGS "${DEBUG_FLAGS} -nostartfiles -T${LINK_SCRIPT}")
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
LINK_DIRECTORIES(${PROJECT_BINARY_DIR})
ADD_SUBDIRECTORY(contiki)
ADD_SUBDIRECTORY(User/src)

全部编译.sh如下:

#! /bin/sh
PATH="/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin:/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin_cache:${PATH}"
export PATH
. ./clear.sh
if [ -f CMakeLists.txt ]; then
    echo "file CMakeLists.txt is ok"
else
    ln -sf /bin/CMakeLists.txt CMakeLists.txt
fi
if [ -d builder ]; then
    cd builder
else
    mkdir builder
    cd builder
    cmake ..
fi
make
read -p "Press any key to continue." var
exit 0

执行结果如下:

里面包含了printf,contiki(任务调度,etimer)编译后代码的容量为4K,效果还是很不错的。

使用SCT做为串口接收,JLink使用的是SEGGER J-Link Commander V4.86a

做了一个脚本,能够直接把程序下载到RAM,并且设置MSP,PC后在RAM中运行程序。

下载.sh 如下

#! /bin/sh
/opt/SEGGER/JLink/JLinkExe -device STM32F103VC  -speed 500 -CommanderScript script.jlink -settingsfile stm32_ram.jlnk

script.jlink 如下:

h
loadbin builder/HELLO.bin 20000000
r
mem 20000000 , 10
wreg msp 20004000
wreg psp 20004000
setpc 20000158
regs
g

使用ld脚本,直接把复位后的地址固定到了 20000158

/*
Linker script for STM32F10x_128K_8K

modified from

http://www.codesourcery.com/archives/arm-gnu/msg02972.html
http://communities.mentor.com/co ... m-gnu/msg02972.html
*/

/*
There will be a link error if there is not this amount of RAM free at the
end.
*/

_Minimum_Stack_Size = 256;

ENTRY(Reset_Handler)


/* Memory Spaces Definitions */

MEMORY
{
  RAM (rwx)  : ORIGIN = 0x20002000, LENGTH = 8K
  FLASH (rx) : ORIGIN = 0x20000000, LENGTH = 8K
}

__ram_start__ = ORIGIN(RAM);
__ram_size__  = LENGTH(RAM);
__ram_end__   = __ram_start__ + __ram_size__;
_estack = __ram_end__;
/* highest address of the user mode stack */



PROVIDE ( _Stack_Limit = _estack - _Minimum_Stack_Size );

/* Sections Definitions */

SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))            /* Startup code */
        KEEP(*(.Reset_Handler))         /* 固定启动代码的位置为0x20000158 */
        *(.text)                   /* code */
        *(.text.*)                 /* remaining code */
        *(.rodata)                 /* read-only data (constants) */
        *(.rodata.*)
        *(.glue_7)
        *(.glue_7t)
        *(.vfp11_veneer)
        *(.v4_bx)
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } >FLASH

    /* for exception handling/unwind - some Newlib functions (in
    common with C++ and STDC++) use this. */
    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)

    } > FLASH

     __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
        __exidx_end = .;

    . = ALIGN(4);
     _etext = .;
    /* This is used by the startup in order to initialize the .data secion
*/
    _sidata = _etext;

    /* This is the initialized data section
    The program executes knowing that the data is in the RAM
    but the loader puts the initial values in the FLASH (inidata).
    It is one task of the startup to copy the initial values from FLASH to
RAM. */
    .data  : AT ( _sidata )
    {
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data
secion */
        _sdata = . ;

        *(.data)
        *(.data.*)

        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data
secion */
        _edata = . ;
    } >RAM


    /* This is the uninitialized data section */
    .bss :
    {
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .bss
secion */
        _sbss = .;
    __bss_start__ = _sbss;
        *(.bss)
        *(.bss.*)
        *(COMMON)

        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .bss
secion */
        _ebss = . ;
    __bss_end__ = _ebss;
    } >RAM

    PROVIDE ( end = _ebss );
    PROVIDE ( _end = _ebss );
    PROVIDE ( _exit = _ebss );
    PROVIDE (_stackend = ORIGIN(RAM) + LENGTH(RAM) - _Minimum_Stack_Size);

    /* This is the user stack section
    This is just to check that there is enough RAM left for the User mode
stack
    It should generate an error if it's full.
     */
    ._usrstack :
    {
        . = ALIGN(4);
        _susrstack = . ;

        . = . + _Minimum_Stack_Size ;

        . = ALIGN(4);
        _eusrstack = . ;
    } >RAM



    /* after that it's only debugging information. */

    /* remove the debugging information from the standard libraries */
/*
    DISCARD :
    {
     libc.a ( * )
     libm.a ( * )
     libgcc.a ( * )
     }
*/

    /* Stabs debugging sections.  */
    .stab          0 : { *(.stab) }
    .stabstr       0 : { *(.stabstr) }
    .stab.excl     0 : { *(.stab.excl) }
    .stab.exclstr  0 : { *(.stab.exclstr) }
    .stab.index    0 : { *(.stab.index) }
    .stab.indexstr 0 : { *(.stab.indexstr) }
    .comment       0 : { *(.comment) }
    /* DWARF debug sections.
       Symbols in the DWARF debugging sections are relative to the beginning
       of the section so we begin them at 0.  */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }
}

直接双击下载图标后如下:

程序下载到目标板RAM中就立刻运行起来了。

总体上讲,这个开发环境配置有点难度,但使用起来速度是很快的。增减文件,只需要在资源管理器中增减就可以了,CMake自动的管理整个工程。exVim是一个中国人做的开源工程,使用起来比自己配的Vim要更全面一些,简直就是“神用的编辑器”了,速度及功能都是双丰收。

整个系统打包到一个SFS文件,文件大小为639.6Mb,而Keil5的安装包就500多Mb。另外也尝试过在Veket8中开发,可以说更方便更容易一些,只是它不支持PAE模式,不能充分发挥大内存的优势。(当前的系统不使用iconv将UTF8文本转换成GB2312,使用编辑器也不能正常打开GB2312编码的文件)

另外整个工程没有用到汇编文件,启动代码也是用C语言写的,让我感到了开源的神奇。


沙发
mmuuss586| | 2016-7-29 20:41 | 只看该作者
谢谢分享经验;

使用特权

评论回复
板凳
深夜星空| | 2016-7-29 23:02 | 只看该作者
楼主能否分享点详细的资料,最近也对linux下单片机开发感兴趣

使用特权

评论回复
地板
Larm1| | 2016-8-5 14:28 | 只看该作者
好东西,谢谢楼主分享...

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:把每天当做世界末日、。、

56

主题

765

帖子

3

粉丝