ThreadX移植

TreadX移植
移植需要的文件
  1. GitHub\threadx-6.1.9_rel\common\inc\
  2. GitHub\threadx-6.1.9_rel\common\src\
  3. GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\inc\
  4. GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\src\
  5. GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\example_build\tx_initialize_low_level.S

​ GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\example_build\tx_simulator_startup.s为example定义的中断向量表,不需要,使用原先系统自带的中断向量表即可。

​ GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\example_build\cortexm3_crt0.s为reset_handler函数的具体实现,不需要,使用原先系统自带的中断复位函数即可。

​ GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\example_build\sample_threadx.ld为ThreadX的链接脚本,不需要,使用原先系统自带的链接脚本即可。

​ GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\example_build\sample_threadx.c为TheadX的示例程序,写应用程序时,可参考此文件。

$(wildcard ThreadX/common/src/*.c) \
$(wildcard ThreadX/ports/*.c)

$(wildcard ThreadX/ports/src/*.s) \
$(wildcard ThreadX/ports/tx_initialize_low_level.s)

-IThreadX/common/inc \
-IThreadX/ports/inc
tx_initialize_low_level.S

​ GitHub\threadx-6.1.9_rel\ports\cortex_m3\gnu\example_build\tx_initialize_low_level.S为需要移植的底层初始化文件。

  1. 修改SYSTEM_CLOCK系统时钟频率,SYSTICK_CYCLES表示多少次系统时钟进行一次重载,SYSTEM_CLOCK / 100表示10ms会产生一次SysTick中断。

    SYSTEM_CLOCK      =   6000000
    SYSTICK_CYCLES    =   ((SYSTEM_CLOCK / 100) -1)
    

    配置SysTick

    @
    @    /* Configure SysTick for 100Hz clock, or 16384 cycles if no reference.  */
    @
        MOV     r0, #0xE000E000                         @ Build address of NVIC registers
        LDR     r1, =SYSTICK_CYCLES
        STR     r1, [r0, #0x14]                         @ Setup SysTick Reload Value
        MOV     r1, #0x7                                @ Build SysTick Control Enable Value
        STR     r1, [r0, #0x10]                         @ Setup SysTick Control
    
  2. 设置可用内存的起始地址

    @
    @    /* Set base of available memory to end of non-initialised RAM area.  */
    @
        LDR     r0, =_tx_initialize_unused_memory       @ Build address of unused memory pointer
        LDR     r1, =__RAM_segment_used_end__           @ Build first free address
        ADD     r1, r1, #4                              @
        STR     r1, [r0]                                @ Setup first unused memory pointer
    

    *_RAM_segment_used_end_*的值要看内存的具体布局,

    若为下面的内存布局,*_RAM_segment_used_end_*应该在bss尾,即:heap的起始位置???

    RAM region:
    stack ↓
    heap ↑
    bss
    data

    若为下面的内存布局,*_RAM_segment_used_end_*应该在stack栈底,即:heap的起始位置???

    RAM region:
    heap ↑
    stack ↓
    bss
    data

    上述这个移植点需要后续确认一下!!!

  3. 设置中断向量表起始地址

    @
    @    /* Setup Vector Table Offset Register.  */
    @
        MOV     r0, #0xE000E000                         @ Build address of NVIC registers
        LDR     r1, =_vectors                           @ Pickup address of vector table
        STR     r1, [r0, #0xD08]                        @ Set vector table address
    @
    @    /* Set system stack pointer from vector value.  */
    @
        LDR     r0, =_tx_thread_system_stack_ptr        @ Build address of system stack pointer
        LDR     r1, =_vectors                           @ Pickup address of vector table
        LDR     r1, [r1]                                @ Pickup reset stack pointer
        STR     r1, [r0]                                @ Save system stack pointer
    

    _vectors根据链接脚本按实际的修改,如:GCC下应该为g_pfnVectors

  4. 在SysTick_Handler函数中添加Tick值的计数函数

    @ /* System Tick timer interrupt handler */
        .global  __tx_SysTickHandler
        .global  SysTick_Handler
        .thumb_func
    __tx_SysTickHandler:
        .thumb_func
    SysTick_Handler:
    @ VOID TimerInterruptHandler (VOID)
    @ {
    @
        PUSH    {r0, lr}
    #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
        BL      _tx_execution_isr_enter             @ Call the ISR enter function
    #endif
        BL      _tx_timer_interrupt
        BL       HAL_IncTick
    #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
        BL      _tx_execution_isr_exit              @ Call the ISR exit function
    #endif
        POP     {r0, lr}
        BX      LR
    @ }
    

    ThreadX接管了SysTick_Handler后,Tick值无法增加,因为可能别的外设驱动需要系统Tick值,所以需要调用BL HAL_IncTick(即原SysTick_Handler函数里面做的事情)。

  5. 注释掉无用的代码

    下面的代码均需注释掉:

        .global     __tx_SVCallHandler
        .global     _vectors    
        .global     __tx_NMIHandler                     @ NMI
        .global     __tx_BadHandler                     @ HardFault
        .global     __tx_SVCallHandler                  @ SVCall
        .global     __tx_DBGHandler                     @ Monitor    
    
    @/* Define shells for each of the unused vectors.  */
    @
        .global  __tx_BadHandler
        .thumb_func
    __tx_BadHandler:
        B       __tx_BadHandler
    
    @ /* added to catch the hardfault */
    
        .global  __tx_HardfaultHandler
        .thumb_func
    __tx_HardfaultHandler:
        B       __tx_HardfaultHandler
    
    
    @ /* added to catch the SVC */
    
        .global  __tx_SVCallHandler
        .thumb_func
    __tx_SVCallHandler:
        B       __tx_SVCallHandler  
        
     
    @ /* NMI, DBG handlers */
        .global  __tx_NMIHandler
        .thumb_func
    __tx_NMIHandler:
        B       __tx_NMIHandler
    
        .global  __tx_DBGHandler
        .thumb_func
    __tx_DBGHandler:
        B       __tx_DBGHandler
    
启动文件startup.s

​ 本地startup.s为启动文件。

  1. 修改中断向量表中的几个向量

    __tx_PendSVHandler ← PendSV_Handler
    __tx_SysTickHandler ← SysTick_Handler
    
  2. 注释掉原项目中的SysTick_Handler函数和PendSV_Handler函数。

mark
/* Memory mapping of Core Hardware */
#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address */
#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address */
#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */

#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */
#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct */
#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */

/**
  \brief  Structure type to access the System Timer (SysTick).
 */
typedef struct
{
  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;

/**
  \brief  Structure type to access the System Control Block (SCB).
 */
typedef struct
{
  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
  __IOM uint8_t  SHP[12U];               /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
  __IOM uint32_t CFSR;                   /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register */
  __IOM uint32_t HFSR;                   /*!< Offset: 0x02C (R/W)  HardFault Status Register */
  __IOM uint32_t DFSR;                   /*!< Offset: 0x030 (R/W)  Debug Fault Status Register */
  __IOM uint32_t MMFAR;                  /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register */
  __IOM uint32_t BFAR;                   /*!< Offset: 0x038 (R/W)  BusFault Address Register */
  __IOM uint32_t AFSR;                   /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register */
  __IM  uint32_t PFR[2U];                /*!< Offset: 0x040 (R/ )  Processor Feature Register */
  __IM  uint32_t DFR;                    /*!< Offset: 0x048 (R/ )  Debug Feature Register */
  __IM  uint32_t ADR;                    /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register */
  __IM  uint32_t MMFR[4U];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register */
  __IM  uint32_t ISAR[5U];               /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register */
        uint32_t RESERVED0[5U];
  __IOM uint32_t CPACR;                  /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register */
} SCB_Type;

​ 结合tx_initialize_low_level.S可以看出,SysTickVector Table设置了两遍,但是由于OS启动会调用 tx_kernel_enter -> _tx_initialize_kernel_enter -> _tx_initialize_low_level,最终会调到tx_initialize_low_level.S里来,所以最终生效的还是tx_initialize_low_level.S里设置的SysTickVector Table

  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值