Try   HackMD

STM32 作業系統開發共筆

contributed by <ryanpatiency>, <hexrabbit>

學習目標

  • 發展 mini-arm-os,增加其功能。

這篇文件內容包含

  • 重要資源
    對我們有重大幫助的資源,網站,書籍,請確保你知道這些東西的存在,並且大概熟悉其目錄,方便找解決方案
  • 重要提示
    很重要的知識點
  • 學習紀錄
    開發過程的學習與紀錄,特別重要的部份會整理成前面的提示與資源
  • 問題討論
    我們卡關的地方和部份的解決辦法,作為紀錄,提供參考

重要資源

重要提示

  • 沒辦法 compile/ build/ 燒錄(program)/ 執行 等等都沒有關係,先跳到程式碼閱讀和資料查詢的步驟,因為了解所有程式碼 e.g. Makefile, linker script, register file 和其背後的知識後,前面那些問題就自然解決了

  • screen 中輸入 enter 只有 '\r' 沒有 '\n'

  • STM32F429xx block diagram
    在 datasheet 裡面找的到,對於判斷 那一個 peripheral 用那一個 clock 有幫助 (AHB, APB)

  • I2C
    可以幫助你了解 bus, master, slave 等是必備的知識

  • How to connect to stm32f429

    ​​​​(sudo) openocd -f board/stm32f429discovery.cfg \
    ​​​​                    -c "arm semihosting enable" \
    ​​​​                -c "reset run"
    
    ​​​​// in another terminal
    ​​​​arm-none-eabi-gdb somewhere/f429disco.elf -ex "target remote:3333"
    ​​​​// use load in gdb to flash ROM
    
  • How to open UART: (Also see README.md in mini-arm-os)

    ​​​​// After connect PA9, PA10 to PC by TTL to USB
    ​​​​(sudo) screen /dev/ttyUSB0 115200 8n1
    

    Note that Uart needs to have the same baud rate 115200

  • One don't need an extra usb-to-ttl line to talk with the board
    by data sheet, the default st-link are connect to the usart1

學習紀錄

  • 一個 stm 愛好者 的 blog

  • malloc in 07-Threads is from the c programming language. it is really the pearl of programming

  • when interupt happens in the middle of:

    • ldm: it will load the current register, and store the next register index into ICI bits in ePSR (note there exist aPSR, iPSR, ePSR)
    • ld in itete: it will abandon the execution and start from first when return;

    So ARM hardwares will do these things (save & resume the status) for us,
    and we don't need to bother considering it right?
    HexRabbit
    Right ryanpatiency

  • There is a document called "AAPCS", which means <Procedure Call Standard for the Arm Architecture> and has nothing to do with "APPCS"

  • .data section is fetched by system bus, instead of data bus. The range of D-Code bus have the same range with I-Code bus. As a result, the .data section put on 0x20000000 and above can only be fetched by system bus

  • 03-context-switch2, the key point is r0 in context-switch.S

  • it, itt, ittt, itttt are all available. and t can be replaced with e, which means if then, if else, and which means it, ite, itet, itete are available as well.

    • flash alias to 0x0 from 0x08000000 is a special case in stm32, not required in arm-cortex-m3, and only happened at boot-from-flash mode, not the other 2 modes.
  • qemu can be connected to gdb:

    • terminal 1: qemu-system-arm -M stm32-p103 -semihosting -nographic -kernel semi.bin -gdb tcp::1234 -S
    • terminal 2: gdb with command target remote :1234
  • ENTRY(reset_handler) is unnecessary since there is no os yet, and the reset_handler's trigger is because of its address location (byte 4)

  • the * in *(.reset_headler) is wildcard, before I think it is *ptr

  • uint32_t *isr_vectors[] could be modified to uint32_t isr_vectors[], and the latter is more meaningful. (at least to me), or modify it a void * since it holds pointer to stack, pointer to function, pointer toetc

  • module semihosting can be simulated, and one can use SYS_READ (0x06) for fun by qemu option -serial null -monitor null, see semihosting and qemu

  • Change code to fit stm32-f4 according to reference manual
    ex change RCC to 0x40023800 from 0x40021000

  • mini-arm-os study note
    之前修課同學的共筆

  • Build minimal ARM Kernel from Scratch

  • Super Simple Tasker

  • mini-arm-os 2016

  • mini-arm-os 問題紀錄

  • 嵌入式作業系統: mini-arm-os

  • 10分鐘讀懂-linker-scripts

  • Discovering the STM32 Microcontroller
    Geoffrey Brown 的授課講義

  • openocd
    燒程式的重要工具

  • arm cortex m3 tutorial English / Chinese

  • arm-bare-metal tutorial

問題討論

  • fail to emulate rtenv+ with QEMU

  • gdb will fail tracing svc call in content_switch (but I've succeeded once..)
    => needs to set breakpoint in svc handler

  • In 04,06,07 there's a
    stack += STACK_SIZE - 32; /* End of stack, minus what we are about to push */
    but actually, we only need place (9+8) * sizeof(int) = 17 byte above the end of stack, so what does that 32 mean ?
    => just a large number

  • Is there any benefit of lr register design in arm compared to intel's push instruction with no need of a register to save return address ?

  • In 06-Preemptive, I think task_init() is unnecessary, what is the meaning of calling svc 0 in privileged mode ?

Yes task_init() is unnecessary in this version, you could create a pull request.
ryanpatiency

  • in arm, mrs seems not available in v7? link
    => it is supported, but the link given is in coprocessor section, which doesn't support by cortex-m3 link
  • Why user_stack_start from -8 instead of 0
    => because beside the 8 callee saved register, there is still 8 caller saved register.
  • what does the 'i' in sidata means?
    => initializer
  • Where can one find that one can use UART through the st-lint to print hello world. And How?
    => by the study note given below
  • Different between bin and elf
    => All symbols and relocation information will be discarded in bin
  • Why as file_name.s -o a.out is different from as file_name.s
    => there is no different, but notice that ld's default output is also a.out, thus a conflict
  • where is my dev/stlink
    => don't use stlink, use openocd
  • in arm-none-eabi, what does "none" means?
    => it means no os
  • exception table start from memory 0 (stack) and memory 4 (handler), and flash memory alias at memory 0?
    => detail is in the the definitive guide to arm-cortex-M3
  • 指定MSP為0x20001000,即堆疊大小為0x1000 -> 所以預設的stack上界是0x20000000 ?
    => detail is in the the definitive guide to arm-cortex-M3
  • Where can one find that how to enable and manipulate UART in reference manual? and the rcc-enable in 01-helloworld, and all the hardware related things in 00 to 08
    => ctrl-F "UART" in reference manual and finish it
    => download the CMSIS and search the keyword inside
  • What does [-2] means in svc_number = ((char*)PSP[6])[-2]; refers to SVC and <guide> ch9 p.146
    => for example, the user call svc, the disassembly is like the following:, so [-2] means, from 800047e, we minus two, which is the svc number
800047c: df00 svc 0 800047e: 4770 bx lr

要注意到使用[-2]而不是[-1]的原因是因為程式是運行在 little endian 環境且為 fixed-length instructions 架構下,所以實際上 .text 中真正的排列是 00df,這和一般 intel 的 variable-length instructions 架構下的排列不同
HexRabbit

  • <the definitive guide to arm> ch7 p128. figure 7.17, can systick interupt be pended? and will us use pendsv?
  • Is sp nether callee saved nor caller saved?
    => document
  • why save psr to ip(r12) when activate, it should be caller saved register. by AAPCS
    => no need
  • Why -serial=null work on qemu semihosting, (and what does it means?)
    => qemu document
  • is Ram(!rx) in linker script memory layout means not read-only and excutable?
    => it is !r and x
  • difference between __attribute and __atribute__
    => back is right
  • why use -kernel option, in qemu? its help: -kernel bzImage use 'bzImage' as kernel image
    => the manual lie
  • what is system boot and why will it use System memory which is from 0x1FFF F000 - 0x1FFF F7FF 2 Kbytes
    => it is corresponding to two pin which can boot from external source.
  • What does ENTRY exactly do in link stage, I don't see any?
    => link
    It will setup a symbol for the os to call, like main, or _start, and that is why when you didn't include a _start symbol, it will say something like couldn't find _start, entry set at 0x4002800
  • In content_switch_2, after svc call lr will be modified to an very large value, so what will happen when it returns(bx lr) ?
    => Exception return, pc and also lr will be restored from stack
  • Why there is nop in syscall.S? Is it used for optimization purpose?
    => According to jserv, this nop was added because qemu's bug, and qemu might fix this bug already.