当前位置: 首页 > news >正文

ThreadX在STM32上的移植:F1,F4通用启动文件tx_initialize_low_level.s

在这里插入图片描述

在嵌入式系统开发中,实时操作系统(RTOS)的选择对于系统性能和稳定性至关重要。ThreadX是一种广泛使用的RTOS,它以其小巧、快速和可靠而闻名。在本文中,我们将探讨如何将ThreadX移植到STM32微控制器上,特别是我们将深入研究通用启动文件tx_initialize_low_level.s

什么是tx_initialize_low_level.s?

tx_initialize_low_level.s是ThreadX启动过程的关键组成部分。这个文件包含了一些底层的初始化代码,这些代码在系统启动时运行,以设置正确的硬件环境并跳转到主程序。

tx_initialize_low_level.s的主要组成部分

让我们来看一下tx_initialize_low_level.s的主要组成部分:

IMPORT  _tx_thread_system_stack_ptr
IMPORT  _tx_initialize_unused_memory
IMPORT  _tx_thread_context_save
IMPORT  _tx_thread_context_restore
IMPORT  _tx_timer_interrupt
IMPORT  __main
IMPORT  __initial_sp
IMPORT  __Vectors
IMPORT  __tx_PendSVHandler

这部分代码导入了一些外部符号

SYSTEM_CLOCK        EQU     168000000
SYSTICK_CYCLES      EQU     ((SYSTEM_CLOCK / 1000) -1)

这部分代码定义了一些常量,包括系统时钟频率、SysTick定时器的周期。

AREA ||.text||, CODE, READONLY
PRESERVE8

这部分代码定义了代码区域,并指示堆栈应保持8字节对齐。

EXPORT  _tx_initialize_low_level
_tx_initialize_low_level

这部分代码是_tx_initialize_low_level函数的定义开始的地方。在这个函数中,会写入初始化系统的代码。

EXPORT  SysTick_Handler
SysTick_Handler
PUSH    {r0, lr}
BL      _tx_timer_interrupt
POP     {r0, lr}
BX      LR

这部分代码是SysTick中断处理程序的定义。当系统定时器产生中断时,这个函数会被调用。

完整代码

	IMPORT  _tx_thread_system_stack_ptrIMPORT  _tx_initialize_unused_memoryIMPORT  _tx_thread_context_saveIMPORT  _tx_thread_context_restoreIMPORT  _tx_timer_interruptIMPORT  __mainIMPORT  __initial_spIMPORT  __VectorsIMPORT  __tx_PendSVHandler
SYSTEM_CLOCK        EQU     168000000
SYSTICK_CYCLES      EQU     ((SYSTEM_CLOCK / 1000) -1)AREA ||.text||, CODE, READONLYPRESERVE8EXPORT  _tx_initialize_low_level
_tx_initialize_low_levelCPSID   iLDR     r0, =_tx_initialize_unused_memory       ; Build address of unused memory pointerLDR     r1, =__initial_sp                       ; Build first free addressADD     r1, r1, #4                              ;STR     r1, [r0]                                ; Setup first unused memory pointerMOV     r0, #0xE000E000                         ; Build address of NVIC registersLDR     r1, =__Vectors                          ; Pickup address of vector tableSTR     r1, [r0, #0xD08]                        ; Set vector table addressLDR     r0, =_tx_thread_system_stack_ptr        ; Build address of system stack pointerLDR     r1, =__Vectors                          ; Pickup address of vector tableLDR     r1, [r1]                                ; Pickup reset stack pointerSTR     r1, [r0]                                ; Save system stack pointerMOV     r0, #0xE000E000                         ; Build address of NVIC registersLDR     r1, =SYSTICK_CYCLESSTR     r1, [r0, #0x14]                         ; Setup SysTick Reload ValueMOV     r1, #0x7                                ; Build SysTick Control Enable ValueSTR     r1, [r0, #0x10]                         ; Setup SysTick ControlLDR     r1, =0x00000000                         ; Rsrv, UsgF, BusF, MemMSTR     r1, [r0, #0xD18]                        ; Setup System Handlers 4-7 Priority RegistersLDR     r1, =0xFF000000                         ; SVCl, Rsrv, Rsrv, RsrvSTR     r1, [r0, #0xD1C]                        ; Setup System Handlers 8-11 Priority Registers
; Note: SVC must be lowest priority, which is 0xFFLDR     r1, =0x40FF0000                     ; SysT, PnSV, Rsrv, DbgMSTR     r1, [r0, #0xD20]                    ; Setup System Handlers 12-15 Priority RegistersBX      lrEXPORT  SysTick_Handler
SysTick_HandlerPUSH    {r0, lr}BL      _tx_timer_interruptPOP     {r0, lr}BX      LRALIGN
LTORGEND

注意事项:

  1. 在移植到自己板子上的时候要注意更改系统时钟频率,我这里是168Mhz,
  2. 代码中的指令是有缩进的,不能取消,不然会把指令识别成标签

在某些汇编语言中,指令前面的空格可能是有意义的。这是因为一些汇编器(如ARM汇编器)使用缩进来区分标签和指令。具体来说:
如果一行的开始处直接是一个指令,那么汇编器可能会将其视为一个标签。标签通常用于表示内存位置,如函数的开始。
如果一行的开始处是一个或多个空格,然后是一个指令,那么汇编器会正确地将其视为一个指令。
因此,如果你删除了指令前面的空格,汇编器可能会误将指令视为标签,从而导致错误。

http://www.lryc.cn/news/478410.html

相关文章:

  • 【算法】递归+深搜:814.二叉树剪枝
  • spring Framework 特定条件下目录遍历漏洞(CVE-2024-38816)修复
  • ESP32-C3 入门笔记03:VScode + flash_download_tool 下载烧录程序(ESP-IDF + PlatformIO)
  • Node.js——fs模块-文件重命名和移动
  • vue2.0版本引入Element-ui问题解决
  • qt QTableView详解
  • 将Notepad++添加到右键菜单【一招实现】
  • Nature Methods | 基于流形约束的RNA速度推断精准解析细胞周期动态调节规律
  • 在离线环境中使用sealos工具快速部署一套高可用的k8s服务集群
  • ReactPress系列—Next.js 的动态路由使用介绍
  • DevOps业务价值流:需求设计最佳实践
  • A15基于Spring Boot的宠物爱心组织管理系统的设计与实现
  • RC高通滤波器Bode图分析(传递函数零极点)
  • SpeechT5 模型
  • 网站用户行为分析:方法、工具与实践
  • 医疗医药企业新闻稿怎么写?健康行业品牌宣传背书的报纸期刊杂志媒体有哪些
  • 2024-11-06 问AI: [AI面试题] 人工智能如何用于欺诈检测和网络安全?
  • 个人3DCoat设置分享
  • Spark 程序开发与提交:本地与集群模式全解析
  • Linux编程:DMA增加UDP 数据传输吞吐量并降低延迟
  • 鸿蒙开启无线调试
  • C. DS循环链表—约瑟夫环 (Ver. I - B)
  • 【刷题】优选算法
  • Python 在PDF中绘制形状(线条、矩形、椭圆形等)
  • 《今日制造与升级》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • loading为什么不更新
  • Rust 力扣 - 1652. 拆炸弹
  • 使用Golang实现开发中常用的【并发设计模式】
  • 基于Zynq FPGA对雷龙SD NAND的性能测试评估
  • 4.WebSocket 配置与Nginx 的完美结合