IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【M32】F103CBTx 移植 ThreadX -> 正文阅读

[嵌入式]【M32】F103CBTx 移植 ThreadX

1.配置

取消 Pendable request for system service 和 System tick timer 选项
在这里插入图片描述
库函数时基源改为普通定时器
在这里插入图片描述
Project Manager 不生成 mian 入口函数
在这里插入图片描述

2.移植

下载 threadx 源码包:源码包

在这里插入图片描述

拷贝下面两个文件夹到项目
在这里插入图片描述
ports 选择对应的内核,M32F103CB 是 cortex-m3 内核,使用 keil 编译,拷贝 cortex_m3/keil 下的文件夹到 ports 中,将 example_build 中的 tx_initialize_low_level.s 拷贝出来,删除其他文件夹
在这里插入图片描述

keil 分组导入对应的文件,ThreadX/common 分组导入 common 路径下所有 C 文件;ThreadX/ports 分组导入 ports 路径下所有 S 文件以及 tx_initialize_low_level.s
在这里插入图片描述

3.适配

修改 tx_initialize_low_level.s,仅保留系统时钟信息、_tx_initialize_low_level 函数和 __tx_SysTickHandler 函数

;   在 _tx_initialize_low_level 中使用的外部函数
    IMPORT  _tx_thread_system_stack_ptr
    IMPORT  _tx_initialize_unused_memory
    IMPORT  __initial_sp
    IMPORT  __Vectors
;   在 __tx_SysTickHandler 中使用的外部函数   
    IMPORT  _tx_timer_interrupt
    
; 系统时钟信息
SYSTEM_CLOCK        EQU     72000000
SYSTICK_CYCLES      EQU     ((SYSTEM_CLOCK / 1000) -1)


    AREA ||.text||, CODE, READONLY
    
;   __initial_sp 取代 |Image\$\$ZI\$\$Limit|,__Vectors 取代 __tx_vectors
    
    EXPORT  _tx_initialize_low_level
_tx_initialize_low_level
    CPSID   i
    LDR     r0, =_tx_initialize_unused_memory   ; Build address of unused memory pointer
    LDR     r1, =__initial_sp                   ; Build first free address
    ADD     r1, r1, #4                          ;
    STR     r1, [r0]                            ; Setup first unused memory pointer
    MOV     r0, #0xE000E000                     ; Build address of NVIC registers
    LDR     r1, =__Vectors                      ; Pickup address of vector table
    STR     r1, [r0, #0xD08]                    ; Set vector table address
    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
    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
    LDR     r1, =0x00000000                     ; Rsrv, UsgF, BusF, MemM
    STR     r1, [r0, #0xD18]                    ; Setup System Handlers 4-7 Priority Registers

    LDR     r1, =0xFF000000                     ; SVCl, Rsrv, Rsrv, Rsrv
    STR     r1, [r0, #0xD1C]                    ; Setup System Handlers 8-11 Priority Registers
                                                ; Note: SVC must be lowest priority, which is 0xFF

    LDR     r1, =0x40FF0000                     ; SysT, PnSV, Rsrv, DbgM
    STR     r1, [r0, #0xD20]                    ; Setup System Handlers 12-15 Priority Registers
                                                ; Note: PnSV must be lowest priority, which is 0xFF
    BX      lr

;   SysTick_Handler 取代 __tx_SysTickHandler
    EXPORT  SysTick_Handler
SysTick_Handler
    PUSH    {r0, lr}
    BL      _tx_timer_interrupt
    POP     {r0, lr}
    BX      LR


    ALIGN
    LTORG
    END

4.运行

创建 tx_application_define.c 文件,定义 tx_application_define 函数,实现 main 函数入口,循环打印内部温度

#include "tx_api.h"
#include <stdio.h>
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "rtc.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"

#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 2048

TX_THREAD thread_0;
TX_BYTE_POOL byte_pool_0;
UCHAR memory_area[DEMO_BYTE_POOL_SIZE];

#define AVMAX 10
struct
{
  uint16_t temp;
  uint16_t vref;
} AdcValue[AVMAX];
UINT status;
RTC_DateTypeDef sdatestructure;
RTC_TimeTypeDef stimestructure;

// 引入 main.c 中的时钟配置
extern void SystemClock_Config(void);

// 主函数入口
int main()
{
  HAL_Init();
  SystemClock_Config();
  // 挂起时基
  HAL_SuspendTick();
  tx_kernel_enter();
}

void thread_0_entry(ULONG thread_input);

/* Define what the initial system looks like.  */

void tx_application_define(void *first_unused_memory)
{

  CHAR *pointer = TX_NULL;

  /* Create a byte memory pool from which to allocate the thread stacks.  */
  tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEMO_BYTE_POOL_SIZE);

  /* Put system definition stuff in here, e.g. thread creates and other assorted
     create information.  */

  /* Allocate the stack for thread 0.  */
  tx_byte_allocate(&byte_pool_0, (VOID **)&pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

  /* Create the main thread.  */
  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
                   pointer, DEMO_STACK_SIZE,
                   1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
}

/* Define the test threads.  */

void thread_0_entry(ULONG thread_input)
{
  // 恢复时基
  HAL_ResumeTick();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_USB_DEVICE_Init();
  MX_RTC_Init();
  MX_ADC1_Init();
  HAL_ADCEx_Calibration_Start(&hadc1);
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&AdcValue, sizeof(AdcValue) / sizeof(uint16_t));

  /* This thread simply sits in while-forever-sleep loop.  */
  while (1)
  {
    HAL_RTC_GetTime(&hrtc, &stimestructure, RTC_FORMAT_BIN);
    HAL_RTC_GetDate(&hrtc, &sdatestructure, RTC_FORMAT_BIN);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    printf("%02d/%02d/%02d\r\n", 2000 + sdatestructure.Year, sdatestructure.Month, sdatestructure.Date);
    printf("%02d:%02d:%02d\r\n", stimestructure.Hours, stimestructure.Minutes, stimestructure.Seconds);

    int32_t temp = 0.0, vref = 0.0;
    for (uint8_t i = 0; i < AVMAX; i++)
    {
      temp += AdcValue[i].temp;
      vref += AdcValue[i].vref;
    }
    temp /= AVMAX;
    vref /= AVMAX;

    printf("MCU Temperature : %.5f\r\n", ((temp * 3300.0 / 4096 - 1410) / 4.2 + 25));
    printf("Vrefint value = %1.3fV \r\n", vref * 3.3f / 4096);

    HAL_GPIO_TogglePin(LED_TSF_GPIO_Port, LED_TSF_Pin);

    /* Sleep for 10 ticks.  */
    tx_thread_sleep(1000);
  }
}

在调度器开启之前,进行外设资源的初始化操作,可能会导致不可预测的错误,我在实际项目中出现了意外死机,频繁产生 HardFault…在放置在任务中进行初始化资源后,错误消失,具体原因尚未深究

注意:如果编译提示 __initial_sp 未定义,一定要勾选微库
在这里插入图片描述
在 startup_stm32f103xb.s 启动文件中,识别到微库的宏,才释放 __initial_sp

IF      :DEF:__MICROLIB           
  EXPORT  __initial_sp

5.运行

系统启动后,成功打印
在这里插入图片描述

参考

1.手把手教你移植ThreadX操作系统,基于在Keil MDK环境
2.stm32移植threadx rtos
3.关于Free-RTOS调度器启动前API调用造成中断关闭问题
4.【安富莱】ThreadX内核教程更新记录帖

交流

项目仓库:https://github.com/dissor/F1-Link.git

git clone https://github.com/dissor/F1-Link.git
cd F1-Link
git reset --hard bd3590d197ff7ad90462c88c7722282b983d482d

微信公众号:物联指北
B站:物联指北
千人企鹅群:658685162

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-27 17:23:20  更:2022-05-27 17:23:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:55:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码