正点原子stm32H750北极星移植最新的RT-Thread

stm32H750移植最新的RT-Thread

硬件是正点原子的stm32H750北极星开发板,RT-Thread版本是H750目前最新的4.1.1版本(从RT studio找的,目前RT-Thread版本git上面已经5.0.1了),IDE和编译器使用的是keil和MDK523带的ARMCC编译器

因为烧写好像要涉及算法的问题,并且hal驱动的例程也用的keil开发,所以没有用其他IDE,这样烧写也方便。

keil自带的RT-Thread扩展的版本是3.1.5,比较过时,所以进行移植,移植5.0.1版本也是可行的,替换对应文件即可。

keil自带的RTT的pack

一、代码准备

  1. 正点原子的stm32H750北极星开发板的跑马灯例程

  2. 我用RT studio添加的stm32h750-artpi例程

二、移植HAL和CMSIS

把代码进行拷贝,并且把不用的代码进行删除。

正点原子给的HAL库版本也比较老,是1.3.0的。而stm32h750-artpi例程是1.7.0的,果断用新的,先替换HAL库

替换HAL版本成功

其实就是把之前的C文件和h文件替换掉,没有难度,除了HAL库,CMSIS我也按照最新的替换掉了

CMSIS替换成功

所以跑马灯工程下的USER目录只留main.c即可,其他并不需要。

三、移植内核

RT-Thread_latest\RTOS\
│  rtconfig.h
│
├─libcpu
│      backtrace.c
│      context_rvds.S
│      cpuport.c
│      cpu_cache.c
│      div0.c
│      showmem.c
│
└─source
        clock.c
        components.c
        cpu.c
        device.c
        idle.c
        ipc.c
        irq.c
        kservice.c
        mem.c
        mempool.c
        object.c
        rtdbg.h
        rtdebug.h
        rtdef.h
        rthw.h
        rtm.h
        rtservice.h
        rtthread.h
        scheduler.c
        signal.c
        thread.c
        timer.c

目录怎么放都可以,添加对的编译和头文件目录就可以。因为这里用的ARMCC编译器,所以复制过来context_rvds.S,gcc编译器的话就复制context_gcc.S

四、驱动的移植

不想光秃秃的用内核。也是需要一些driver的。按照stm32h750-artpi使用的driver进行移植,其实重要的我只想用clk、gpio、usart。所以只复制过来这么多。

DRIVER\
│  board.c
│  board.h
│  drv_clk.c
│  drv_common.c
│  drv_gpio.c
│  drv_hwtimer.c
│  drv_qspi.c
│  drv_soft_i2c.c
│  drv_usart.c
│  stm32h7xx_hal_conf.h
│
└─include
    │  drv_common.h
    │  drv_config.h
    │  drv_dma.h
    │  drv_eth.h
    │  drv_flash.h
    │  drv_log.h
    │  drv_qspi.h
    │  drv_sdio.h
    │  drv_soft_i2c.h
    │  drv_spi.h
    │  drv_usbh.h
    │
    └─config
            adc_config.h
            dma_config.h
            pwm_config.h
            qspi_config.h
            sdio_config.h
            spi_config.h
            tim_config.h
            uart_config.h
            usbd_config.h

五、component的移植

内核外需要一些component来运行,包括更高一级的driver比如pin、serial。还有比较重要的finsh交互式控制台,很好用。

那么把代码复制过来,别忘记把libc也移植过来,components可能要用到。

COMPONENTS\
├─drivers
│  ├─include
│  │  │  rtdevice.h
│  │  │
│  │  ├─drivers
│  │  │      adc.h
│  │  │      。。。这里头文件太多了,不一一列举占用篇幅。
│  │  │
│  │  └─ipc
│  │          completion.h
│  │          dataqueue.h
│  │          pipe.h
│  │          poll.h
│  │          ringblk_buf.h
│  │          ringbuffer.h
│  │          waitqueue.h
│  │          workqueue.h
│  │
│  ├─ipc
│  │      completion.c
│  │      dataqueue.c
│  │      pipe.c
│  │      ringblk_buf.c
│  │      ringbuffer.c
│  │      SConscript
│  │      waitqueue.c
│  │      workqueue.c
│  │
│  ├─misc
│  │      pin.c
│  │
│  └─serial
│          SConscript
│          serial.c
│
├─finsh
│      cmd.c
│      finsh.h
│      Kconfig
│      msh.c
│      msh.h
│      msh_parse.c
│      msh_parse.h
│      SConscript
│      shell.c
│      shell.h
│
└─libc
    └─compilers
        ├─common
        │  │  cctype.c
        │  │  cstdio.c
        │  │  cstdlib.c
        │  │  cstring.c
        │  │  ctime.c
        │  │  cwchar.c
        │  │  readme.md
        │  │  SConscript
        │  │
        │  ├─extension
        │  │  │  readme.md
        │  │  │  SConscript
        │  │  │
        │  │  ├─fcntl
        │  │  │  │  README.md
        │  │  │  │  SConscript
        │  │  │  │
        │  │  │  ├─msvc
        │  │  │  │      fcntl.h
        │  │  │  │      SConscript
        │  │  │  │
        │  │  │  └─octal
        │  │  │          fcntl.h
        │  │  │          SConscript
        │  │  │
        │  │  └─sys
        │  │          errno.h
        │  │          stat.h
        │  │          types.h
        │  │
        │  └─include
        │      │  compiler_private.h
        │      │  dirent.h
        │      │  unistd.h
        │      │
        │      ├─posix
        │      │      ctype.h
        │      │      stdio.h
        │      │      stdlib.h
        │      │      string.h
        │      │      wchar.h
        │      │
        │      └─sys
        │              ioctl.h
        │              select.h
        │              signal.h
        │              statfs.h
        │              time.h
        │              unistd.h
        │              vfs.h
        │
        └─newlib
            │  fcntl.h
            │  README.md
            │  SConscript
            │  syscalls.c
            │
            └─machine
                    time.h

六、代码的修改

当然前面只是移植的工作。目前完成一半,剩下就是代码的修改。

之说修改点吧

①板子初始化修改

hw_board_init函数进行板子的初始化,跑马灯实验中有对cache的workaround,把它复制过来

/**
 * This function will initial STM32 board.
 */
void hw_board_init(char *clock_src, int32_t clock_src_freq, int32_t clock_target_freq)
{
    extern void rt_hw_systick_init(void);
    extern void clk_init(char *clk_source, int source_freq, int target_freq);

#ifdef SCB_EnableICache
    /* Enable I-Cache---------------------------------------------------------*/
    SCB_EnableICache();
#endif

#ifdef SCB_EnableDCache
    /* Enable D-Cache---------------------------------------------------------*/
    SCB_EnableDCache();
#endif
    SCB->CACR|=1<<2;   //1997AURORA 强制D-Cache透写,从正点原子跑马灯复制过来的
    /* HAL_Init() function is called at the beginning of the program */
    HAL_Init();

    /* enable interrupt */
    __set_PRIMASK(0);
    /* System clock initialization */
    clk_init(clock_src, clock_src_freq, clock_target_freq);
    /* disbale interrupt */
    __set_PRIMASK(1);

    rt_hw_systick_init();

    /* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
    extern int rt_hw_pin_init(void);
    rt_hw_pin_init();
#endif

    /* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
    extern int rt_hw_usart_init(void);
    rt_hw_usart_init();
#endif

}

还有就是clock的变动,因为stm32h750-artpi使用的时钟是内部时钟,要改成外部时钟,并且频率配成400Mhz

void system_clock_config(int target_freq_mhz)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Supply configuration update enable
    */
    HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
    /** Configure the main internal regulator output voltage
    */
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

    while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
    /** Initializes the CPU, AHB and APB busses clocks
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
    RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 5;
    RCC_OscInitStruct.PLL.PLLN = 160;
    RCC_OscInitStruct.PLL.PLLP = 2;
    RCC_OscInitStruct.PLL.PLLQ = 4;
    // RCC_OscInitStruct.PLL.PLLR = 2;
    RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
    RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
    // RCC_OscInitStruct.PLL.PLLFRACN = 0;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }
    /* 1997AURORA 20230723 从跑马灯例程复制过来的 */
    QSPI_Enable_Memmapmode();

    /** Initializes the CPU, AHB and APB busses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                                |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
    RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
    /* 1997AURORA 20230723 */
    __HAL_RCC_CSI_ENABLE() ;
    __HAL_RCC_SYSCFG_CLK_ENABLE() ;  
    HAL_EnableCompensationCell();
    /* end */
}

然后再把QSPI_Enable_Memmapmode函数的实现也复制过来,直接复制,不再赘述

②rtconfig.h的修改

因为正点原子北极星开发板用的uart1,PA9作为Tx,PA10作为Rx,所以修改部分如下

#define RT_CONSOLE_DEVICE_NAME "uart1"

/* 1997AURORA 20230723 并不想用hook,看自己需要*/
// #define RT_USING_OVERFLOW_CHECK
// #define RT_USING_HOOK
// #define RT_HOOK_USING_FUNC_PTR、
。
。
。
/* 1997AURORA 20230723*/
#define RT_USING_MEMPOOL
// #define RT_USING_SMALL_MEM
// #define RT_USING_SMALL_MEM_AS_HEAP
// #define RT_USING_HEAP

这里把HEAP注释掉是因为我使用keil编译,对段地址的获取一直不成功,即使把HEAP_BEGIN变量名字换成与scf一致也会报错说找不到,所以干脆不用HEAP了,不过需要注释一些东西。我编译出错的点如下:

#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int RW_m_stmsram$$Limit;
#define HEAP_BEGIN      ((void *)RW_m_stmsram$$Limit)
#elif __ICCARM__
#pragma section="CSTACK"
#define HEAP_BEGIN      (__segment_end("CSTACK"))
#else

如果有大佬知道怎么改这部分,就可以用HEAP了,很多地方也会方便很多。欢迎评论区留言。

③board.h的修改

因为uart用的uart1,所以改一下

#define BSP_USING_UART1
#define BSP_UART1_TX_PIN       "PA9"
#define BSP_UART1_RX_PIN       "PA10"

clock部分也改一下

/*-------------------------- CHIP CONFIG END --------------------------*/

/*-------------------------- ROM/RAM CONFIG BEGIN --------------------------*/

#define ROM_START              ((uint32_t)0x08000000)
#define ROM_SIZE               (128 * 1024)
#define ROM_END                ((uint32_t)(ROM_START + ROM_SIZE))

#define RAM_START              (0x20000000)
#define RAM_SIZE               (128 * 1024)
#define RAM_END                (RAM_START + RAM_SIZE)

/*-------------------------- ROM/RAM CONFIG END --------------------------*/

/*-------------------------- CLOCK CONFIG BEGIN --------------------------*/

#define BSP_CLOCK_SOURCE                  ("HSE")
#define BSP_CLOCK_SOURCE_FREQ_MHZ         ((int32_t)0)
#define BSP_CLOCK_SYSTEM_FREQ_MHZ         ((int32_t)400)

④对于没有用HEAP宏包起来的代码修改

有些代码在用rt_malloc或者rt_free的时候,是不管有没有启用HEAP的。所以编译会出现几个错误,比如serial.c,以serial.c举例:

rt_free

比如像这样修改一下,但是申请内存的时候不能这么改,不然没有内存分配给要用的了。。。

rt_malloc

像这样定一个变量给他就可以了,注意用全局的,不要用局部的。

rt_uint8_t serial_malloc_buffer[200] = {0};
rt_uint8_t serial_malloc_fifo[200] = {0};

⑤scf散列文件修改

因为有些启动代码在qspi还未初始化之前执行,所以偷个懒,直接把qspi部分干掉就可以了,flash空间还是够的,不够的话,就把重要的文件丢在片内flash,等qspi配置完成后运行的代码部分放在qspi中

scf散列文件

⑥main.c的修改

当然这个修改就比较简单了,我是直接做个delay就完了,跑马灯的代码不要了。

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

int main(void)
{
    int count = 1;

    while (count++)
    {
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}

七、编译验证

编译配置

编译OK,读者们移植编译有可能会很花时间,因为笔者也是这么过来的,需要慢慢改慢慢调整。

烧写进去进行验证:

验证结果

很棒,至此移植完毕,感谢大家的阅读!评论收藏支持一下!

代码下载:正点原子stm32H750北极星+RT-Thread-4.1.1

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值