RT-Thread(一)-快速上手

  新换的工作目前的工程跑在RT-Thread上,虽然听说过这个操作系统,但是没有在这个操作系统上做过开发,所以打算尽快熟悉起来。

  目前手头没有开发版,所以先试用模拟器熟悉下:Keil模拟器STM32F103 (rt-thread.org)

  按照文档二话不说先把例程跑起来:

 1.$Super$$和$Sub$$

  在keil 的ARM Development Tools中找到对应的介绍:

 告诉了我们这个用法:

1.$Super$$foo:标识原始函数foo,使用它直接调用原始函数foo。

2.$Sub$$foo:标识调用的新函数,也就是对原始函数foo的扩展函数。

 根据上边的介绍我们对例程中的led函数进行下扩展实验:

 有了以上的实验,对这个$Super$$和$Sub$$的使用有了初步的了解,下面再进行系统启动代码的分析。

2.系统启动代码

2.1startup_stm32f103xe.s

;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
;* File Name          : startup_stm32f103xe.s
;* Author             : MCD Application Team
;* Version            : V4.2.0
;* Date               : 31-March-2017
;* Description        : STM32F103xE Devices vector table for MDK-ARM toolchain. 
;*                      This module performs:
;*                      - Set the initial SP
;*                      - Set the initial PC == Reset_Handler
;*                      - Set the vector table entries with the exceptions ISR address
;*                      - Configure the clock system
;*                      - Branches to __main in the C library (which eventually
;*                        calls main()).
;*                      After Reset the Cortex-M3 processor is in Thread mode,
;*                      priority is Privileged, and the Stack is set to Main.
;********************************************************************************
;*
;* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
;*
;* Redistribution and use in source and binary forms, with or without modification,
;* are permitted provided that the following conditions are met:
;*   1. Redistributions of source code must retain the above copyright notice,
;*      this list of conditions and the following disclaimer.
;*   2. Redistributions in binary form must reproduce the above copyright notice,
;*      this list of conditions and the following disclaimer in the documentation
;*      and/or other materials provided with the distribution.
;*   3. Neither the name of STMicroelectronics nor the names of its contributors
;*      may be used to endorse or promote products derived from this software
;*      without specific prior written permission.
;*
;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
; 
;*******************************************************************************

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
                                                  
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

                PRESERVE8
                THUMB


; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                DCD     FLASH_IRQHandler           ; Flash
                DCD     RCC_IRQHandler             ; RCC
                DCD     EXTI0_IRQHandler           ; EXTI Line 0
                DCD     EXTI1_IRQHandler           ; EXTI Line 1
                DCD     EXTI2_IRQHandler           ; EXTI Line 2
                DCD     EXTI3_IRQHandler           ; EXTI Line 3
                DCD     EXTI4_IRQHandler           ; EXTI Line 4
                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2
                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler            ; TIM2
                DCD     TIM3_IRQHandler            ; TIM3
                DCD     TIM4_IRQHandler            ; TIM4
                DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                DCD     SPI1_IRQHandler            ; SPI1
                DCD     SPI2_IRQHandler            ; SPI2
                DCD     USART1_IRQHandler          ; USART1
                DCD     USART2_IRQHandler          ; USART2
                DCD     USART3_IRQHandler          ; USART3
                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                DCD     RTC_Alarm_IRQHandler        ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
                DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
                DCD     TIM8_UP_IRQHandler         ; TIM8 Update
                DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
                DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
                DCD     ADC3_IRQHandler            ; ADC3
                DCD     FSMC_IRQHandler            ; FSMC
                DCD     SDIO_IRQHandler            ; SDIO
                DCD     TIM5_IRQHandler            ; TIM5
                DCD     SPI3_IRQHandler            ; SPI3
                DCD     UART4_IRQHandler           ; UART4
                DCD     UART5_IRQHandler           ; UART5
                DCD     TIM6_IRQHandler            ; TIM6
                DCD     TIM7_IRQHandler            ; TIM7
                DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
                DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End

__Vectors_Size  EQU  __Vectors_End - __Vectors

                AREA    |.text|, CODE, READONLY
                
; Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP
                
; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler     PROC
                EXPORT  NMI_Handler                [WEAK]
                B       .
                ENDP
HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler          [WEAK]
                B       .
                ENDP
MemManage_Handler\
                PROC
                EXPORT  MemManage_Handler          [WEAK]
                B       .
                ENDP
BusFault_Handler\
                PROC
                EXPORT  BusFault_Handler           [WEAK]
                B       .
                ENDP
UsageFault_Handler\
                PROC
                EXPORT  UsageFault_Handler         [WEAK]
                B       .
                ENDP
SVC_Handler     PROC
                EXPORT  SVC_Handler                [WEAK]
                B       .
                ENDP
DebugMon_Handler\
                PROC
                EXPORT  DebugMon_Handler           [WEAK]
                B       .
                ENDP
PendSV_Handler  PROC
                EXPORT  PendSV_Handler             [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP

Default_Handler PROC

                EXPORT  WWDG_IRQHandler            [WEAK]
                EXPORT  PVD_IRQHandler             [WEAK]
                EXPORT  TAMPER_IRQHandler          [WEAK]
                EXPORT  RTC_IRQHandler             [WEAK]
                EXPORT  FLASH_IRQHandler           [WEAK]
                EXPORT  RCC_IRQHandler             [WEAK]
                EXPORT  EXTI0_IRQHandler           [WEAK]
                EXPORT  EXTI1_IRQHandler           [WEAK]
                EXPORT  EXTI2_IRQHandler           [WEAK]
                EXPORT  EXTI3_IRQHandler           [WEAK]
                EXPORT  EXTI4_IRQHandler           [WEAK]
                EXPORT  DMA1_Channel1_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel2_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel3_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel4_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel5_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel6_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel7_IRQHandler   [WEAK]
                EXPORT  ADC1_2_IRQHandler          [WEAK]
                EXPORT  USB_HP_CAN1_TX_IRQHandler  [WEAK]
                EXPORT  USB_LP_CAN1_RX0_IRQHandler [WEAK]
                EXPORT  CAN1_RX1_IRQHandler        [WEAK]
                EXPORT  CAN1_SCE_IRQHandler        [WEAK]
                EXPORT  EXTI9_5_IRQHandler         [WEAK]
                EXPORT  TIM1_BRK_IRQHandler        [WEAK]
                EXPORT  TIM1_UP_IRQHandler         [WEAK]
                EXPORT  TIM1_TRG_COM_IRQHandler    [WEAK]
                EXPORT  TIM1_CC_IRQHandler         [WEAK]
                EXPORT  TIM2_IRQHandler            [WEAK]
                EXPORT  TIM3_IRQHandler            [WEAK]
                EXPORT  TIM4_IRQHandler            [WEAK]
                EXPORT  I2C1_EV_IRQHandler         [WEAK]
                EXPORT  I2C1_ER_IRQHandler         [WEAK]
                EXPORT  I2C2_EV_IRQHandler         [WEAK]
                EXPORT  I2C2_ER_IRQHandler         [WEAK]
                EXPORT  SPI1_IRQHandler            [WEAK]
                EXPORT  SPI2_IRQHandler            [WEAK]
                EXPORT  USART1_IRQHandler          [WEAK]
                EXPORT  USART2_IRQHandler          [WEAK]
                EXPORT  USART3_IRQHandler          [WEAK]
                EXPORT  EXTI15_10_IRQHandler       [WEAK]
                EXPORT  RTC_Alarm_IRQHandler        [WEAK]
                EXPORT  USBWakeUp_IRQHandler       [WEAK]
                EXPORT  TIM8_BRK_IRQHandler        [WEAK]
                EXPORT  TIM8_UP_IRQHandler         [WEAK]
                EXPORT  TIM8_TRG_COM_IRQHandler    [WEAK]
                EXPORT  TIM8_CC_IRQHandler         [WEAK]
                EXPORT  ADC3_IRQHandler            [WEAK]
                EXPORT  FSMC_IRQHandler            [WEAK]
                EXPORT  SDIO_IRQHandler            [WEAK]
                EXPORT  TIM5_IRQHandler            [WEAK]
                EXPORT  SPI3_IRQHandler            [WEAK]
                EXPORT  UART4_IRQHandler           [WEAK]
                EXPORT  UART5_IRQHandler           [WEAK]
                EXPORT  TIM6_IRQHandler            [WEAK]
                EXPORT  TIM7_IRQHandler            [WEAK]
                EXPORT  DMA2_Channel1_IRQHandler   [WEAK]
                EXPORT  DMA2_Channel2_IRQHandler   [WEAK]
                EXPORT  DMA2_Channel3_IRQHandler   [WEAK]
                EXPORT  DMA2_Channel4_5_IRQHandler [WEAK]

WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
DMA1_Channel1_IRQHandler
DMA1_Channel2_IRQHandler
DMA1_Channel3_IRQHandler
DMA1_Channel4_IRQHandler
DMA1_Channel5_IRQHandler
DMA1_Channel6_IRQHandler
DMA1_Channel7_IRQHandler
ADC1_2_IRQHandler
USB_HP_CAN1_TX_IRQHandler
USB_LP_CAN1_RX0_IRQHandler
CAN1_RX1_IRQHandler
CAN1_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
USART1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler
EXTI15_10_IRQHandler
RTC_Alarm_IRQHandler
USBWakeUp_IRQHandler
TIM8_BRK_IRQHandler
TIM8_UP_IRQHandler
TIM8_TRG_COM_IRQHandler
TIM8_CC_IRQHandler
ADC3_IRQHandler
FSMC_IRQHandler
SDIO_IRQHandler
TIM5_IRQHandler
SPI3_IRQHandler
UART4_IRQHandler
UART5_IRQHandler
TIM6_IRQHandler
TIM7_IRQHandler
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_5_IRQHandler
                B       .

                ENDP

                ALIGN

;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                 IF      :DEF:__MICROLIB
                
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                
                 ELSE
                
                 IMPORT  __use_two_region_memory
                 EXPORT  __user_initial_stackheap
                 
__user_initial_stackheap

                 LDR     R0, =  Heap_Mem
                 LDR     R1, =(Stack_Mem + Stack_Size)
                 LDR     R2, = (Heap_Mem +  Heap_Size)
                 LDR     R3, = Stack_Mem
                 BX      LR

                 ALIGN

                 ENDIF

                 END

;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****

这段启动代码的作用是:

1.设置堆栈

2.定义中断向量表

3.初始化系统时钟

4.初始化堆栈

5.执行__main,准备c语言的运行环境,初始化程序计数器指针PC指向main,进入c代码

stm32f103是m3的内核,首先来看下存储器映射:

RAM的起始地址是0x20000000。

 再来看我们仿真用的stm32f103zf的flash和RAM大小:

 到此处我们再来逐步分析启动文件:

一.设置堆栈:

; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
                                                  
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

                PRESERVE8
                THUMB

1.定义了一段大小为1KB(0x00000400)的栈空间。

2.__initial_sp:标名,栈顶地址。

看一下.map文件中的一段信息,在.map文件中搜索__initial_sp

   .data                                    0x20000000   Section      192  drv_gpio.o(.data)
    .data                                    0x200000c0   Section       68  drv_usart.o(.data)
    .data                                    0x20000104   Section        4  system_stm32f1xx.o(.data)
    .data                                    0x20000108   Section        4  stm32f1xx_hal.o(.data)
    .data                                    0x2000010c   Section        4  clock.o(.data)
    rt_tick                                  0x2000010c   Data           4  clock.o(.data)
    .data                                    0x20000110   Section        9  irq.o(.data)
    rt_interrupt_enter_hook                  0x20000110   Data           4  irq.o(.data)
    rt_interrupt_leave_hook                  0x20000114   Data           4  irq.o(.data)
    .data                                    0x2000011c   Section       12  kservice.o(.data)
    __rt_errno                               0x2000011c   Data           4  kservice.o(.data)
    _console_device                          0x20000120   Data           4  kservice.o(.data)
    .data                                    0x20000128   Section       32  mem.o(.data)
    rt_malloc_hook                           0x20000128   Data           4  mem.o(.data)
    rt_free_hook                             0x2000012c   Data           4  mem.o(.data)
    heap_ptr                                 0x20000130   Data           4  mem.o(.data)
    heap_end                                 0x20000134   Data           4  mem.o(.data)
    lfree                                    0x20000138   Data           4  mem.o(.data)
    mem_size_aligned                         0x2000013c   Data           4  mem.o(.data)
    used_mem                                 0x20000140   Data           4  mem.o(.data)
    max_mem                                  0x20000144   Data           4  mem.o(.data)
    .data                                    0x20000148   Section        8  mempool.o(.data)
    rt_mp_alloc_hook                         0x20000148   Data           4  mempool.o(.data)
    rt_mp_free_hook                          0x2000014c   Data           4  mempool.o(.data)
    .data                                    0x20000150   Section      180  object.o(.data)
    rt_object_container                      0x20000150   Data         160  object.o(.data)
    rt_object_attach_hook                    0x200001f0   Data           4  object.o(.data)
    rt_object_detach_hook                    0x200001f4   Data           4  object.o(.data)
    .data                                    0x20000204   Section       28  scheduler.o(.data)
    rt_scheduler_lock_nest                   0x20000204   Data           2  scheduler.o(.data)
    rt_scheduler_hook                        0x2000021c   Data           4  scheduler.o(.data)
    .data                                    0x20000220   Section        4  signal.o(.data)
    _rt_siginfo_pool                         0x20000220   Data           4  signal.o(.data)
    .data                                    0x20000224   Section       16  timer.o(.data)
    rt_timer_list                            0x20000224   Data           8  timer.o(.data)
    rt_timer_timeout_hook                    0x2000022c   Data           4  timer.o(.data)
    random_nr                                0x20000230   Data           4  timer.o(.data)
    .data                                    0x20000234   Section       12  thread.o(.data)
    rt_thread_suspend_hook                   0x20000234   Data           4  thread.o(.data)
    rt_thread_resume_hook                    0x20000238   Data           4  thread.o(.data)
    rt_thread_inited_hook                    0x2000023c   Data           4  thread.o(.data)
    .data                                    0x20000240   Section       16  cpuport.o(.data)
    rt_exception_hook                        0x2000024c   Data           4  cpuport.o(.data)
    .data                                    0x20000250   Section        4  shell.o(.data)
    .data                                    0x20000254   Section       16  symbol.o(.data)
    .data                                    0x20000264   Section        8  idlehook_sample.o(.data)
    tid                                      0x20000264   Data           4  idlehook_sample.o(.data)
    hook_times                               0x20000268   Data           4  idlehook_sample.o(.data)
    .data                                    0x2000026c   Section        4  interrupt_sample.o(.data)
    cnt                                      0x2000026c   Data           4  interrupt_sample.o(.data)
    .data                                    0x20000270   Section       39  mailbox_sample.o(.data)
    mb_str1                                  0x20000270   Data          12  mailbox_sample.o(.data)
    mb_str2                                  0x2000027c   Data          22  mailbox_sample.o(.data)
    mb_str3                                  0x20000292   Data           5  mailbox_sample.o(.data)
    .data                                    0x20000298   Section        8  memp_sample.o(.data)
    tid1                                     0x20000298   Data           4  memp_sample.o(.data)
    tid2                                     0x2000029c   Data           4  memp_sample.o(.data)
    .data                                    0x200002a0   Section        6  mutex_sample.o(.data)
    dynamic_mutex                            0x200002a0   Data           4  mutex_sample.o(.data)
    number1                                  0x200002a4   Data           1  mutex_sample.o(.data)
    number2                                  0x200002a5   Data           1  mutex_sample.o(.data)
    .data                                    0x200002a8   Section       16  priority_inversion.o(.data)
    tid1                                     0x200002a8   Data           4  priority_inversion.o(.data)
    tid2                                     0x200002ac   Data           4  priority_inversion.o(.data)
    tid3                                     0x200002b0   Data           4  priority_inversion.o(.data)
    mutex                                    0x200002b4   Data           4  priority_inversion.o(.data)
    .data                                    0x200002b8   Section       16  producer_consumer.o(.data)
    set                                      0x200002b8   Data           4  producer_consumer.o(.data)
    get                                      0x200002bc   Data           4  producer_consumer.o(.data)
    producer_tid                             0x200002c0   Data           4  producer_consumer.o(.data)
    consumer_tid                             0x200002c4   Data           4  producer_consumer.o(.data)
    .data                                    0x200002c8   Section       16  scheduler_hook.o(.data)
    tid1                                     0x200002d0   Data           4  scheduler_hook.o(.data)
    tid2                                     0x200002d4   Data           4  scheduler_hook.o(.data)
    .data                                    0x200002d8   Section       13  semaphore_sample.o(.data)
    dynamic_sem                              0x200002d8   Data           4  semaphore_sample.o(.data)
    count                                    0x200002dc   Data           1  semaphore_sample.o(.data)
    result                                   0x200002e0   Data           4  semaphore_sample.o(.data)
    number                                   0x200002e4   Data           1  semaphore_sample.o(.data)
    .data                                    0x200002e8   Section        4  signal_sample.o(.data)
    tid1                                     0x200002e8   Data           4  signal_sample.o(.data)
    .data                                    0x200002ec   Section        4  thread_sample.o(.data)
    tid1                                     0x200002ec   Data           4  thread_sample.o(.data)
    .data                                    0x200002f0   Section       12  timer_sample.o(.data)
    timer1                                   0x200002f0   Data           4  timer_sample.o(.data)
    timer2                                   0x200002f4   Data           4  timer_sample.o(.data)
    cnt                                      0x200002f8   Data           4  timer_sample.o(.data)
    .bss                                     0x200002fc   Section       84  drv_usart.o(.bss)
    .bss                                     0x20000350   Section      420  idle.o(.bss)
    idle                                     0x20000350   Data         148  idle.o(.bss)
    rt_thread_stack                          0x200003e4   Data         256  idle.o(.bss)
    idle_hook_list                           0x200004e4   Data          16  idle.o(.bss)
    .bss                                     0x200004f4   Section      128  kservice.o(.bss)
    rt_log_buf                               0x200004f4   Data         128  kservice.o(.bss)
    .bss                                     0x20000574   Section       32  mem.o(.bss)
    heap_sem                                 0x20000574   Data          32  mem.o(.bss)
    .bss                                     0x20000594   Section      256  scheduler.o(.bss)
    .bss                                     0x20000694   Section       68  pin.o(.bss)
    _hw_pin                                  0x20000694   Data          68  pin.o(.bss)
    .bss                                     0x200006d8   Section      129  shell.o(.bss)
    finsh_prompt                             0x200006d8   Data         129  shell.o(.bss)
    .bss                                     0x2000075c   Section     2376  event_sample.o(.bss)
    event                                    0x2000075c   Data          32  event_sample.o(.bss)
    thread1_stack                            0x2000077c   Data        1024  event_sample.o(.bss)
    thread1                                  0x20000b7c   Data         148  event_sample.o(.bss)
    thread2_stack                            0x20000c10   Data        1024  event_sample.o(.bss)
    thread2                                  0x20001010   Data         148  event_sample.o(.bss)
    .bss                                     0x200010a4   Section     2520  mailbox_sample.o(.bss)
    mb                                       0x200010a4   Data          48  mailbox_sample.o(.bss)
    mb_pool                                  0x200010d4   Data         128  mailbox_sample.o(.bss)
    thread1_stack                            0x20001154   Data        1024  mailbox_sample.o(.bss)
    thread1                                  0x20001554   Data         148  mailbox_sample.o(.bss)
    thread2_stack                            0x200015e8   Data        1024  mailbox_sample.o(.bss)
    thread2                                  0x200019e8   Data         148  mailbox_sample.o(.bss)
    .bss                                     0x20001a7c   Section     4352  memp_sample.o(.bss)
    ptr                                      0x20001a7c   Data         200  memp_sample.o(.bss)
    mempool                                  0x20001b44   Data        4096  memp_sample.o(.bss)
    mp                                       0x20002b44   Data          56  memp_sample.o(.bss)
    .bss                                     0x20002b7c   Section     4444  msgq_sample.o(.bss)
    mq                                       0x20002b7c   Data          52  msgq_sample.o(.bss)
    msg_pool                                 0x20002bb0   Data        2048  msgq_sample.o(.bss)
    thread1_stack                            0x200033b0   Data        1024  msgq_sample.o(.bss)
    thread1                                  0x200037b0   Data         148  msgq_sample.o(.bss)
    thread2_stack                            0x20003844   Data        1024  msgq_sample.o(.bss)
    thread2                                  0x20003c44   Data         148  msgq_sample.o(.bss)
    .bss                                     0x20003cd8   Section     2344  mutex_sample.o(.bss)
    thread1_stack                            0x20003cd8   Data        1024  mutex_sample.o(.bss)
    thread1                                  0x200040d8   Data         148  mutex_sample.o(.bss)
    thread2_stack                            0x2000416c   Data        1024  mutex_sample.o(.bss)
    thread2                                  0x2000456c   Data         148  mutex_sample.o(.bss)
    .bss                                     0x20004600   Section      116  producer_consumer.o(.bss)
    .bss                                     0x20004674   Section     2344  semaphore_sample.o(.bss)
    thread1_stack                            0x20004674   Data        1024  semaphore_sample.o(.bss)
    thread1                                  0x20004a74   Data         148  semaphore_sample.o(.bss)
    thread2_stack                            0x20004b08   Data        1024  semaphore_sample.o(.bss)
    thread2                                  0x20004f08   Data         148  semaphore_sample.o(.bss)
    .bss                                     0x20004f9c   Section     1172  thread_sample.o(.bss)
    thread2_stack                            0x20004f9c   Data        1024  thread_sample.o(.bss)
    thread2                                  0x2000539c   Data         148  thread_sample.o(.bss)
    STACK                                    0x20005430   Section     1024  startup_stm32f103xe.o(STACK)

 

    pin_irq_hdr_tab                          0x20000000   Data         192  drv_gpio.o(.data)
    uart1                                    0x200000c0   Data          68  drv_usart.o(.data)
    SystemCoreClock                          0x20000104   Data           4  system_stm32f1xx.o(.data)
    uwTick                                   0x20000108   Data           4  stm32f1xx_hal.o(.data)
    rt_interrupt_nest                        0x20000118   Data           1  irq.o(.data)
    rt_assert_hook                           0x20000124   Data           4  kservice.o(.data)
    rt_object_trytake_hook                   0x200001f8   Data           4  object.o(.data)
    rt_object_take_hook                      0x200001fc   Data           4  object.o(.data)
    rt_object_put_hook                       0x20000200   Data           4  object.o(.data)
    rt_current_thread                        0x20000208   Data           4  scheduler.o(.data)
    rt_current_priority                      0x2000020c   Data           1  scheduler.o(.data)
    rt_thread_ready_priority_group           0x20000210   Data           4  scheduler.o(.data)
    rt_thread_defunct                        0x20000214   Data           8  scheduler.o(.data)
    rt_interrupt_from_thread                 0x20000240   Data           4  cpuport.o(.data)
    rt_interrupt_to_thread                   0x20000244   Data           4  cpuport.o(.data)
    rt_thread_switch_interrupt_flag          0x20000248   Data           4  cpuport.o(.data)
    shell                                    0x20000250   Data           4  shell.o(.data)
    _syscall_table_begin                     0x20000254   Data           4  symbol.o(.data)
    _syscall_table_end                       0x20000258   Data           4  symbol.o(.data)
    _sysvar_table_begin                      0x2000025c   Data           4  symbol.o(.data)
    _sysvar_table_end                        0x20000260   Data           4  symbol.o(.data)
    count                                    0x200002c8   Data           8  scheduler_hook.o(.data)
    serial1                                  0x200002fc   Data          84  drv_usart.o(.bss)
    rt_thread_priority_table                 0x20000594   Data         256  scheduler.o(.bss)
    array                                    0x20004600   Data          20  producer_consumer.o(.bss)
    sem_lock                                 0x20004614   Data          32  producer_consumer.o(.bss)
    sem_empty                                0x20004634   Data          32  producer_consumer.o(.bss)
    sem_full                                 0x20004654   Data          32  producer_consumer.o(.bss)
    Image$$RW_IRAM1$$ZI$$Limit               0x20005830   Number         0  anon$$obj.o ABSOLUTE
    __initial_sp                             0x20005830   Data           0  startup_stm32f103xe.o(STACK)

从map文件中可以看到栈的起始地址(0x20005430)和大小(1024)以及栈顶地址(0x20005830):

 

 画图示意一下:

 栈的大小我们设置的为1k,栈底地址为0x20005430,那么__initial_sp为什么是0x20005830而不是0x2000582F呢?这个可以在《Cortex M3权威指南》中找到答案:

 3.开辟堆空间

 堆大小:0.5K

堆的基地址:__heap_base

堆的顶地址:__heap_limit

 在map文件中找HEAP发现被优化掉了:

 添加一段代码,把堆用起来防止被优化掉:

 如愿以偿的得到了堆:

 画图示意一下:

 4.向量表

  异常类型:

  Cortex-M3在内核水平上搭载了一个异常相应系统,支持位数众多的系统异常和外部中断。编号为1-15的对应系统异常,大于等于16的则全是外部中断。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的(所有能打断正常执行流的事件都称为异常)

  系统异常清单:

 外部中断清单:

   关于异常相关知识参考《Cortex M3权威指南》。

  当发生了异常并且要相应它时,CM3需要定位其处理例程的入口地址。这些入口地址存储在所谓的"(异常)向量表中"。缺省情况下,CM3认为该表位于零地址处,且各向量占4字节,因此每个表项占用4字节:

   由以上的信息我们结合汇编代码来看向量表其实就是一个32位整数数组,每个下标对应了一种异常,对应的元素值就是异常服务例程的入口地址。其中下标0不是异常服务例程的入口地址,而是复位后的MSP的初值__initial_sp(实验例程中从map文件中查看当前值为0x20005A38),向量表从FLASH的0地址开始放置,除了地址0存放的是MSP初始值之外,从代码上看,其他元素都是中断服务函数的函数名,函数名就是地址。

; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                DCD     FLASH_IRQHandler           ; Flash
                DCD     RCC_IRQHandler             ; RCC
                DCD     EXTI0_IRQHandler           ; EXTI Line 0
                ;省略部分代码
__Vectors_End

__Vectors_Size  EQU  __Vectors_End - __Vectors

                AREA    |.text|, CODE, READONLY

仿真将例程,可以看到寄存器R13的值被初始化为栈顶地址0x20005A38,向量表中存放了各个异常服务例程入口地址。

有人可能会有疑问:为什么向量表中的值是0x080041B1(也就是奇数),而实际的服务函数的地址是0x080041B0呢?

这个问题在《Cortex M3权威指南》中有详细说明。

 复位程序,默认商店复位后执行的程序

 

我们把Run to main()勾掉,点击仿真,可以看出刚开始执行时的情况->内核停止在Reset_Handler上:

 

 在Reset_Handler中,程序最后调用了__main,需要注意的是这个函数并不是main函数的别名或者编译之后的名字,__main和main是两个完全不同的函数,我们确实在工程中找不到__main函数的源代码,因为这个函数是链接器自动创建的:

 __main()函数中有两个函数:

__scatterload():

__rt_entry():初始化堆栈、C库函数初始化,调用各种初始化函数最终调用用户层的main(),以下列出__rt_entry()可以调用的函数(按调用顺序列出)。

 

 1. _platform_pre_stackheap_init:标准C库不提供,用户自己定义,__rt_entry在设置堆栈和堆之前调用此函数

 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method:

 3. _platform_post_stackheap_init

 4. __rt_lib_init

 5. _platform_post_lib_init

 6. main()

 7. exit()

_platform_*函数不是标准C库的一部分,如果你定义它们,__rt_enry会调用它们。

main()函数是用户级应用程序入口点,寄存器r0和r1包含main()的参数。如果main()返回,则将其返回值传递给exit()并退出应用程序。

我们在c语言标准中可以看到对main函数的标准定义:

 所以标准中是没有void main(void){}形式的定义的。

__rt_enry还负责设置堆栈和堆。但是设置堆栈和堆取决于用户指定的方法。

 

__user_initial_stackheap:这个函数使你设置并返回初始堆栈和堆的位置,C库不提供此函数,你可以自定义它,然后被__rt_entry调用。

我们在启动文件中可以看到此函数定义:

;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                 IF      :DEF:__MICROLIB;如果使用了微库(MicroLib),直接导出堆栈地址符号
                
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                
                 ELSE
                
                 IMPORT  __use_two_region_memory;导入外部程序并执行
                 EXPORT  __user_initial_stackheap;导出子程序符号给外部程序调用
                 
__user_initial_stackheap

                 LDR     R0, =  Heap_Mem
                 LDR     R1, =(Stack_Mem + Stack_Size)
                 LDR     R2, = (Heap_Mem +  Heap_Size)
                 LDR     R3, = Stack_Mem
                 BX      LR

                 ALIGN

                 ENDIF

                 END

__rt_lib_init

 此函数初始化了C库子系统。初始化了引用的库函数、语言环境。必要时为main()设置argc和argv。在启动时__rt_entry必调此函数。

以下列出__rt_lib_init调用的函数:

1. _fp_init

2. _init_alloc

3. _rand_init

4. _get_lc_collate

5. _get_lc_ctype

6. _get_lc_monetary

7. _get_lc_numeric

8. _get_lc_time

9. _atexit_init

10. _signal_init

11. _fp_trap_init

12. _clock_init

13. _getenv_init

14. _initio

15. _ARM_get_argv

16._alloca_initialize

17. _ARM_exceptions_init

18. __cpp_initialize__aeabi_

各个函数具体看官方文档。

总结:通过以上的分析,我们知道了CM3复位之后通过向量表调到Reset_Handler中断服务子程序中调用库函数__main()->__rt_entry->main()这么一个流程。

2.2 rtthread对main()函数的扩展操作

components.c中的代码:

$Sub$$main()调用rtthread_startup()函数。rtthread_startup()函数是RT-Thread规定的统一入口点。

 首先来看下rt_hw_interrupt_disable()和rt_hw_interrupt_enable(),他们的定义在context_rvds.S中:

;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable    PROC
    EXPORT  rt_hw_interrupt_disable
    MRS     r0, PRIMASK;读取PRIMASK到r0
    CPSID   I;关中断,PRIMASK=1
    BX      LR
    ENDP

;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable    PROC
    EXPORT  rt_hw_interrupt_enable
    MSR     PRIMASK, r0;写r0到PRIMASK
    BX      LR
    ENDP

特殊功能寄存器组

  Cortex-M3中的特殊功能寄存器包括:

  1.程序状态寄存器组(PSRs或xPSR)

  2.中断屏蔽寄存器组(PRIMASK,FAULTMASK,BASEPRI):用于控制异常的使能和除能。

  3.控制寄存器(CONTROL)

 对于时间-关键任务而言,PRIMASK和BASEPRI对于暂时关闭中断是非常重要的。为了快速开关中断,CM3还设置了一条CPS指令:

仿真来看一下程序启动关闭中断:

 RT-Thread的启动流程:

int rtthread_startup(void)
{
    rt_hw_interrupt_disable();

    /* board level initalization
     * NOTE: please initialize heap inside board initialization.
     */
    rt_hw_board_init();

    /* show RT-Thread version */
    rt_show_version();

    /* timer system initialization */
    rt_system_timer_init();

    /* scheduler system initialization */
    rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

    /* create init_thread */
    rt_application_init();

    /* timer thread initialization */
    rt_system_timer_thread_init();

    /* idle thread initialization */
    rt_thread_idle_init();

    /* start scheduler */
    rt_system_scheduler_start();

    /* never reach here */
    return 0;
}

1.初始化系统相关硬件

2.初始化系统内核对象

3.初始化系统设备

4.初始化各个应用线程,启动调度器

RT-Thread将main函数作为用户代码入口,只需要在main函数里添加自己的应用即可:

 main函数在main_thread_entry中调用:

 跑马灯的例子:

在UART#1中输入msh命令:led+回车就可以运行起来了:

 事已至此呢,跑马灯例程成功运行。上手成功

 

posted @ 2023-12-31 18:11  别别别别闹  阅读(435)  评论(0)    收藏  举报