基于keil环境下mm32f327单片机rtthread的移植

文章目录

  • 基于keil环境下mm32f327单片机rtthread的移植
  • 前言
  • 一、所需资源
  • 二、创建工程目录
  • 三、复制所需文件到相应文件夹
  • 四、创建keil工程
  • 五、添加文件到工程
  • 六、更改相应的.c文件
  • 七、编译运行

前言

第十七届智能车竞赛赛前准备,为 mm32f3277G9p 移植rtthread系统。

RT-Thread Nano 是一个极简版的硬实时内核,它是由 C 语言开发,采用面向对象的编程思维,具有良好的代码风格,是一款可裁剪的、抢占式实时多任务的 RTOS。其内存资源占用极小,功能包括任务处理、软件定时器、信号量、邮箱和实时调度等相对完整的实时操作系统特性。适用于家电、消费电子、医疗设备、工控等领域大量使用的 32 位 ARM 入门级 MCU 的场合。

灵动微MM32F3277系列采用高性能的ARM®Cortex®-M3为内核的32位单片机微控制器,工作频率可达高达120MHz,内置SRAM及内存高速存储器,丰富的I/O端口和外设连接到外部总线。
灵动微MM32F3277包含多达3个12位的ADC、2个比较器、2个16位通用定时器、2个32位通用定时器、2个16位基本定时器和2个16位高级定时器。还包含标准的通信接口:2个I2C接口、3个I2S接口、3个SPI接口、1个USBOTG全速接口、1个CAN接口、1个SDIO接口、1个Ethernet接口和8个UART接口。

一、所需资源

1、rtthread源码: RT_Thread开源库
2、mm32f3277逐飞库: 逐飞开源库

二、创建工程目录

目录如下:
CODE (用于存放用户编写的驱动代码)
Library (用于存放工程依赖的库文件和启动文件)
MDK (存放keil工程文件)
USER (存放主程序文件main.c等)
​​​​
在USER文件夹下新建inc和src子文件夹用于存放.c和.h文件。
之后在inc文件夹下新建isr.h文件,在src文件夹下新建isr.c和main.c文件。

三、复制所需文件到相应文件夹

将下载好的逐飞库源码中Library文件夹下的文件移动到工程Library文件夹中并新建rtthread_library文件夹。

将下载好的rtthread源码中图示目录复制到rtthread_library文件夹下并新建bsp文件夹

在rtt源码目录的bsp文件夹下找到mm32f327x文件夹,将其中的rtconfig.h文件复制到新建的bsp文件夹下,之后对整个rtthread_library文件夹下的文件进行裁剪。
裁剪后目录如下:
Components目录:


include文件夹不做修改

libcpu文件夹仅留下arm\cortex-m3路径下的文件

src文件夹下文件:

四、创建keil工程

Keil 新建工程到 MDK 文件夹下。
芯片型号选择为 MM32F3277G9p 。
创建分组目录如下:

五、添加文件到工程

在 USER 分组添加:
USER 目录子文件夹 src 中的 .c 文件;
Library\rtthread_libraries\bsp 目录下的 .h 文件;

CODE 分组加入自己配置的外设驱动;
board 分组添加 :
Library\seekfree_libraries\board 文件夹下的 board.c 文件;

common 分组加入 :
Library\seekfree_libraries\common 下的所有.c文件;

startup分组下添加 :
Library\Device\MM32F327x\Source 下的 system_mm32f327x.c 文件;
Library\Device\MM32F327x\Source\KEIL_StartAsm下的startup_mm32f327x
.c文件;

doc分组添加工程的说明文档;
seekfree_libraries分组下添加:
Library\seekfree_libraries目录下的.c文件;

seekfree_peripheral分组下添加:
Library\seekfree_peripheral目录下的.c文件;

MM32_HAL分组下添加:
Library\Device\MM32F327x\HAL_Lib\Src目录下的.c文件;

rtt_src分组下添加:
Library\rtthread_libraries\src目录下的.c文件;

rtt_inc分组下添加:
Library\rtthread_libraries\include和Library\rtthread_libraries\include\libc目录下的.h文件;

rtt_lib分组下添加:
Library\rtthread_libraries\libcpu目录下的context_rvds.S和cpuport.c文件;

rtt_componer分组下添加:
Library\rtthread_libraries\components\finsh目录下的所有文件;

添加头文件路径如下:

六、更改相应的.c文件

isr.c文件:

/*********************************************************************************************************************
* COPYRIGHT NOTICE
* Copyright (c) 2019,逐飞科技
* All rights reserved.
* 技术讨论QQ群:一群:179029047(已满)  二群:244861897
*
* 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
* 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
*
* @file                isr
* @company         成都逐飞科技有限公司
* @author          逐飞科技(QQ3184284598)
* @version         查看doc内version文件 版本说明
* @Software            IAR 8.3 or MDK 5.28
* @Target core     MM32F3277
* @Taobao          https://seekfree.taobao.com/
* @date                2021-02-22
********************************************************************************************************************/#include "headfile.h"
#include "isr.h"void TIM1_UP_IRQHandler (void)
{uint32 state = TIM1->SR;                                                       // 读取中断状态TIM1->SR &= ~state;                                                                // 清空中断状态
}void TIM8_UP_IRQHandler (void)
{uint32 state = TIM8->SR;                                                       // 读取中断状态TIM8->SR &= ~state;                                                                // 清空中断状态
}void TIM2_IRQHandler (void)
{uint32 state = TIM2->SR;                                                       // 读取中断状态TIM2->SR &= ~state;                                                                // 清空中断状态
}void TIM5_IRQHandler (void)
{uint32 state = TIM5->SR;                                                       // 读取中断状态TIM5->SR &= ~state;                                                                // 清空中断状态
}void TIM3_IRQHandler (void)
{uint32 state = TIM3->SR;                                                       // 读取中断状态TIM3->SR &= ~state;                                                                // 清空中断状态
}void TIM4_IRQHandler (void)
{uint32 state = TIM4->SR;                                                       // 读取中断状态TIM4->SR &= ~state;                                                                // 清空中断状态
}void TIM6_IRQHandler (void)
{uint32 state = TIM6->SR;                                                       // 读取中断状态TIM6->SR &= ~state;                                                                // 清空中断状态
}void TIM7_IRQHandler (void)
{uint32 state = TIM7->SR;                                                       // 读取中断状态TIM7->SR &= ~state;                                                                // 清空中断状态
}//void UART1_IRQHandler(void)
//{//  if(UART1->ISR & UART_ISR_TX_INTF)                                                // 串口发送缓冲空中断
//  {//      UART1->ICR |= UART_ICR_TXICLR;                                              // 清除中断标志位
//  }
//  if(UART1->ISR & UART_ISR_RX_INTF)                                                // 串口接收缓冲中断
//  {//      UART1->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位
//  }
//}void UART2_IRQHandler(void)
{if(UART2->ISR & UART_ISR_TX_INTF)                                               // 串口发送缓冲空中断{UART2->ICR |= UART_ICR_TXICLR;                                             // 清除中断标志位}if(UART2->ISR & UART_ISR_RX_INTF)                                             // 串口接收缓冲中断{UART2->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位}
}void UART3_IRQHandler(void)
{if(UART3->ISR & UART_ISR_TX_INTF)                                               // 串口发送缓冲空中断{UART3->ICR |= UART_ICR_TXICLR;                                             // 清除中断标志位}if(UART3->ISR & UART_ISR_RX_INTF)                                             // 串口接收缓冲中断{UART3->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位}
}void UART4_IRQHandler(void)
{if(UART4->ISR & UART_ISR_TX_INTF)                                               // 串口发送缓冲空中断{UART4->ICR |= UART_ICR_TXICLR;                                             // 清除中断标志位}if(UART4->ISR & UART_ISR_RX_INTF)                                             // 串口接收缓冲中断{UART4->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位}
}void UART5_IRQHandler(void)
{if(UART5->ISR & UART_ISR_TX_INTF)                                               // 串口发送缓冲空中断{UART5->ICR |= UART_ICR_TXICLR;                                             // 清除中断标志位}if(UART5->ISR & UART_ISR_RX_INTF)                                             // 串口接收缓冲中断{UART5->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位}
}void UART6_IRQHandler(void)
{if(UART6->ISR & UART_ISR_TX_INTF)                                               // 串口发送缓冲空中断{UART6->ICR |= UART_ICR_TXICLR;                                             // 清除中断标志位}if(UART6->ISR & UART_ISR_RX_INTF)                                             // 串口接收缓冲中断{UART6->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位}
}void UART7_IRQHandler(void)
{if(UART7->ISR & UART_ISR_TX_INTF)                                               // 串口发送缓冲空中断{UART7->ICR |= UART_ICR_TXICLR;                                             // 清除中断标志位}if(UART7->ISR & UART_ISR_RX_INTF)                                             // 串口接收缓冲中断{UART7->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位}
}void UART8_IRQHandler(void)
{if(UART8->ISR & UART_ISR_TX_INTF)                                               // 串口发送缓冲空中断{UART8->ICR |= UART_ICR_TXICLR;                                             // 清除中断标志位}if(UART8->ISR & UART_ISR_RX_INTF)                                             // 串口接收缓冲中断{UART8->ICR |= UART_ICR_RXICLR;                                              // 清除中断标志位switch(camera_type)                                                           // 查询摄像头类型 未初始化摄像头则此处会进入default{case CAMERA_BIN_UART:                                                   // 串口小钻风ov7725_cof_uart_interrupt();                                        // 调用串口小钻风的串口接收处理break;case CAMERA_GRAYSCALE:                                                   // 总钻风mt9v03x_uart_callback();                                          // 调用总钻风的串口接收处理break;default:break;}}
}void EXTI0_IRQHandler(void)
{// 检测与清除中断标志可以根据实际应用进行删改EXTI_ClearFlag(EXTI_Line0);                                                        // 清除 line0 触发标志
}void EXTI1_IRQHandler(void)
{// 检测与清除中断标志可以根据实际应用进行删改EXTI_ClearFlag(EXTI_Line1);                                                        // 清除 line1 触发标志
}void EXTI2_IRQHandler(void)
{// 检测与清除中断标志可以根据实际应用进行删改EXTI_ClearFlag(EXTI_Line2);                                                        // 清除 line2 触发标志
}void EXTI3_IRQHandler(void)
{// 检测与清除中断标志可以根据实际应用进行删改EXTI_ClearFlag(EXTI_Line3);                                                        // 清除 line3 触发标志
}void EXTI4_IRQHandler(void)
{// 检测与清除中断标志可以根据实际应用进行删改EXTI_ClearFlag(EXTI_Line4);                                                        // 清除 line4 触发标志
}void EXTI9_5_IRQHandler(void)
{// 检测与清除中断标志可以根据实际应用进行删改if(EXTI_GetITStatus(EXTI_Line5))                                               // 检测 line5 是否触发{EXTI_ClearFlag(EXTI_Line5);                                                    // 清除 line5 触发标志}if(EXTI_GetITStatus(EXTI_Line6))                                               // 检测 line6 是否触发{EXTI_ClearFlag(EXTI_Line6);                                                    // 清除 line6 触发标志}if(EXTI_GetITStatus(EXTI_Line7))                                               // 检测 line7 是否触发{EXTI_ClearFlag(EXTI_Line7);                                                    // 清除 line8 触发标志}if(EXTI_GetITStatus(EXTI_Line8))                                               // 检测 line8 是否触发{switch(camera_type)                                                            // 查询摄像头类型 未初始化摄像头则此处会进入default{case CAMERA_BIN:                                                        // IIC小钻风ov7725_vsync();break;case CAMERA_BIN_UART:                                                     // 串口小钻风ov7725_uart_vsync();break;case CAMERA_GRAYSCALE:                                                    // 总钻风mt9v03x_vsync();break;default:break;}EXTI_ClearFlag(EXTI_Line8);                                                  // 清除 line8 触发标志}if(EXTI_GetITStatus(EXTI_Line9))                                               // 检测 line9 是否触发{EXTI_ClearFlag(EXTI_Line9);                                                    // 清除 line9 触发标志}
}void EXTI15_10_IRQHandler (void)
{// 检测与清除中断标志可以根据实际应用进行删改if(EXTI_GetITStatus(EXTI_Line10))                                              // 检测 line10 是否触发{EXTI_ClearFlag(EXTI_Line10);                                              // 清除 line10 触发标志}if(EXTI_GetITStatus(EXTI_Line11))                                             // 检测 line11 是否触发{EXTI_ClearFlag(EXTI_Line11);                                              // 清除 line11 触发标志}if(EXTI_GetITStatus(EXTI_Line12))                                             // 检测 line12 是否触发{EXTI_ClearFlag(EXTI_Line12);                                              // 清除 line12 触发标志}if(EXTI_GetITStatus(EXTI_Line13))                                             // 检测 line13 是否触发{EXTI_ClearFlag(EXTI_Line13);                                              // 清除 line13 触发标志}if(EXTI_GetITStatus(EXTI_Line14))                                             // 检测 line14 是否触发{EXTI_ClearFlag(EXTI_Line14);                                              // 清除 line14 触发标志}if(EXTI_GetITStatus(EXTI_Line15))                                             // 检测 line15 是否触发{EXTI_ClearFlag(EXTI_Line15);                                              // 清除 line15 触发标志}
}void DMA1_Channel1_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC1))                                      // 判断触发通道{DMA_ClearFlag(DMA1_FLAG_TC1);                                             // 清空该通道中断标志}
}void DMA1_Channel2_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC2))                                      // 判断触发通道{DMA_ClearFlag(DMA1_FLAG_TC2);                                             // 清空该通道中断标志}
}void DMA1_Channel3_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC3))                                      // 判断触发通道{DMA_ClearFlag(DMA1_FLAG_TC3);                                             // 清空该通道中断标志}
}void DMA1_Channel4_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC4))                                      // 判断触发通道{DMA_ClearFlag(DMA1_FLAG_TC4);                                             // 清空该通道中断标志switch(camera_type)                                                         // 查询摄像头类型 未初始化摄像头则此处会进入default{case CAMERA_BIN:                                                        // IIC小钻风ov7725_dma();break;case CAMERA_BIN_UART:                                                   // 串口小钻风ov7725_uart_dma();break;case CAMERA_GRAYSCALE:                                                  // 总钻风mt9v03x_dma();break;default:break;}}
}void DMA1_Channel5_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC5))                                      // 判断触发通道{DMA_ClearFlag(DMA1_FLAG_TC5);                                             // 清空该通道中断标志}
}void DMA1_Channel6_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC6))                                      // 判断触发通道{DMA_ClearFlag(DMA1_FLAG_TC6);                                             // 清空该通道中断标志}
}void DMA1_Channel7_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA1_FLAG_TC7))                                      // 判断触发通道{DMA_ClearFlag(DMA1_FLAG_TC7);                                             // 清空该通道中断标志}
}void DMA2_Channel1_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA2_FLAG_TC1))                                      // 判断触发通道{DMA_ClearFlag(DMA2_FLAG_TC1);                                             // 清空该通道中断标志}
}void DMA2_Channel2_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA2_FLAG_TC2))                                      // 判断触发通道{DMA_ClearFlag(DMA2_FLAG_TC2);                                             // 清空该通道中断标志}
}void DMA2_Channel3_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA2_FLAG_TC3))                                      // 判断触发通道{DMA_ClearFlag(DMA2_FLAG_TC3);                                             // 清空该通道中断标志}
}void DMA2_Channel4_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA2_FLAG_TC4))                                      // 判断触发通道{DMA_ClearFlag(DMA2_FLAG_TC4);                                             // 清空该通道中断标志}
}void DMA2_Channel5_IRQHandler(void)
{if(SET == DMA_GetFlagStatus(DMA2_FLAG_TC5))                                      // 判断触发通道{DMA_ClearFlag(DMA2_FLAG_TC5);                                             // 清空该通道中断标志}
}#ifdef Will_never_be_defined
WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_CRS_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
FlashCache_IRQHandler
CAN1_RX_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_IRQHandler
I2C2_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
UART3_IRQHandler
EXTI15_10_IRQHandler
RTCAlarm_IRQHandler
OTG_FS_WKUP_IRQHandler
TIM8_BRK_IRQHandler
TIM8_UP_IRQHandler
TIM8_TRG_COM_IRQHandler
TIM8_CC_IRQHandler
ADC3_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_IRQHandler
DMA2_Channel5_IRQHandler
ETH_IRQHandler
COMP1_2_IRQHandler
OTG_FS_IRQHandler
UART6_IRQHandler
UART7_IRQHandler
UART8_IRQHandler
#endif

main.c文件:

/*********************************************************************************************************************
* COPYRIGHT NOTICE
* Copyright (c) 2019,逐飞科技
* All rights reserved.
* 技术讨论QQ群:一群:179029047(已满)  二群:244861897
*
* 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
* 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
*
* @file                main
* @company         成都逐飞科技有限公司
* @author          逐飞科技(QQ3184284598)
* @version         查看doc内version文件 版本说明
* @Software            IAR 8.3 or MDK 5.24
* @Target core     MM32F3277
* @Taobao          https://seekfree.taobao.com/
* @date                2021-02-22
********************************************************************************************************************/#include "headfile.h"
#include "isr.h"
// **************************** 宏定义 ****************************// **************************** 宏定义 ****************************// **************************** 变量定义 ****************************// **************************** 变量定义 ****************************// **************************** 代码区域 ****************************
//-------------------------------------------------------------------------------------------------------------------
//  @brief      线程1入口
//  @param      parameter   参数
//  @return     void
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void thread1_entry(void *parameter)
{while(1){rt_kprintf("dynamic thread is running.\n");rt_thread_mdelay(1000);}
}//-------------------------------------------------------------------------------------------------------------------
//  @brief      线程2入口
//  @param      parameter   参数
//  @return     void
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void thread2_entry(void *parameter)
{while(1){rt_kprintf("static thread is running.\n");rt_thread_mdelay(500);}
}//-------------------------------------------------------------------------------------------------------------------
//  @brief      动态线程创建以及启动
//  @param      void        空
//  @return     void
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
int dynamic_thread_example(void)
{//线程控制块指针rt_thread_t tid1;//创建动态线程tid1 = rt_thread_create("thread1",      //线程名称thread1_entry,                  //线程入口函数RT_NULL,                        //线程参数512,                            //512个字节的栈空间5,                              //线程优先级为5,数值越小,优先级越高,0为最高优先级。//可以通过修改rt_config.h中的RT_THREAD_PRIORITY_MAX宏定义(默认值为8)来修改最大支持的优先级5);                             //时间片为5rt_kprintf("create dynamic thread.\n");if(tid1 != RT_NULL)                     //线程创建成功{rt_kprintf("thread1 dynamic thread create OK.\n");rt_thread_startup(tid1);            //运行该线程}else                                    //线程创建失败{rt_kprintf("thread1 dynamic thread create ERROR.\n");return 1;}return 0;
}//-------------------------------------------------------------------------------------------------------------------
//  @brief      静态线程创建以及启动
//  @param      void        空
//  @return     void
//  Sample usage:
//-------------------------------------------------------------------------------------------------------------------
static rt_uint8_t thread2_stack[1024];  //线程栈数组
struct rt_thread thread2_thread;        //线程控制块
int static_thread_example(void)
{rt_err_t res;//创建静态线程res = rt_thread_init(&thread2_thread,                //线程控制块"thread2",                      //线程名称thread2_entry,                  //线程入口函数RT_NULL,                        //线程参数thread2_stack,                  //栈的起始地址sizeof(thread2_stack),          //栈大小3,                              //线程优先级为3,数值越小,优先级越高,0为最高优先级。//可以通过修改rt_config.h中的RT_THREAD_PRIORITY_MAX宏定义(默认值为8)来修改最大支持的优先级5                               //时间片为5);rt_kprintf("create static thread.\n");if(res == RT_EOK)                                       //线程创建成功{rt_kprintf("thread2 static thread create OK\n");rt_thread_startup(&thread2_thread);                 //运行该线程}else                                                    //线程创建失败{rt_kprintf("thread2 static thread create ERROR\n");return 1;}return 0;
}//使用INIT_APP_EXPORT宏自动初始化,也可以通过在其他线程内调用dynamic_thread_example函数进行初始化
INIT_APP_EXPORT(dynamic_thread_example);     //应用初始化//使用INIT_APP_EXPORT宏自动初始化,也可以通过在其他线程内调用static_thread_example函数进行初始化
INIT_APP_EXPORT(static_thread_example);      //应用初始化//静态创建方法
//当我们没有开启RT_USING_HEAP宏定义我们只能使用静态的方法创建线程、信号量、互斥量等等
//或者当我们想要指定控制块控制块或者栈的位置的时候,也可以用静态创建方法//动态创建方法
//动态创建务必开启RT_USING_HEAP宏定义
//动态创建好处在于我们不用自己定义控制块或者栈数组,创建的时候填写的参数更加的少非常的方便
//如果HEAP大小不够了,可以在board.c中找到RT_HEAP_SIZE宏进行修改int main(void)
{//此处编写用户代码(例如:外设初始化代码等)gpio_init(H2, GPO, 0, GPO_PUSH_PULL);//此处编写用户代码(例如:外设初始化代码等)while(1){rt_thread_mdelay(100);gpio_toggle(H2);}
}
// **************************** 代码区域 ****************************

board.c文件:

/*********************************************************************************************************************
* COPYRIGHT NOTICE
* Copyright (c) 2019,逐飞科技
* All rights reserved.
* 技术讨论QQ群:一群:179029047(已满)  二群:244861897
*
* 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
* 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
*
* @file                board.c
* @company         成都逐飞科技有限公司
* @author          逐飞科技(QQ3184284598)
* @version         查看doc内version文件 版本说明
* @Software            IAR 8.32.4 or MDK 5.28
* @Target core     MM32F3277
* @Taobao          https://seekfree.taobao.com/
* @date                2021-02-22
********************************************************************************************************************/#include "board.h"
#include "zf_uart.h"
#include <rtthread.h>
#include "mm32_reg_redefine_v1.h"extern uint32_t SystemCoreClock;//finsh组件接收串口数据,是通过在串口中断内发送邮件,finsh线程接收邮件进行获取的
rt_mailbox_t uart_mb;static uint32_t systick_config(rt_uint32_t ticks)
{if ((ticks - 1) > 0xFFFFFF){return 1;}SysTick->LOAD = ticks - 1; nvic_init(SysTick_IRQn, 3, ENABLE);SysTick->VAL  = 0;SysTick->CTRL = 0x07;  return 0;
}#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
#define RT_HEAP_SIZE 700static uint32_t rt_heap[RT_HEAP_SIZE];     // heap default size: 4K(1024 * 4)
RT_WEAK void *rt_heap_begin_get(void)
{return rt_heap;
}RT_WEAK void *rt_heap_end_get(void)
{return rt_heap + RT_HEAP_SIZE;
}
#endifvoid rt_hw_board_init()
{systick_config(SystemCoreClock / RT_TICK_PER_SECOND);board_init(1);/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INITrt_components_board_init();
#endif#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endifuart_mb = rt_mb_create("uart_mb", 10, RT_IPC_FLAG_FIFO);
}void SysTick_Handler(void)
{rt_interrupt_enter();rt_tick_increase();rt_interrupt_leave();
}void rt_hw_console_output(const char *str)
{while(RT_NULL != *str){if('\n' == *str){uart_putchar(DEBUG_UART, '\r');}uart_putchar(DEBUG_UART, *str++);}
}char rt_hw_console_getchar(void)
{uint32 dat;//等待邮件rt_mb_recv(uart_mb, &dat, RT_WAITING_FOREVER);//uart_getchar(DEBUG_UART, &dat);return (char)dat;
}//-------------------------------------------------------------------------------------------------------------------
// @brief      核心板初始化
// @param      debug_enable    是否开启默认 debug 输出 DEBUG_UART 默认 UART1
// @return     void
// Sample usage:                board_init(TRUE);
//-------------------------------------------------------------------------------------------------------------------
void board_init (bool debug_enable)
{if(debug_enable){uart_init(DEBUG_UART, DEBUG_UART_BAUD, DEBUG_UART_TX, DEBUG_UART_RX);                 // 默认初始化 UART1 用以支持 printf 输出}uart_rx_irq(DEBUG_UART, 1);
}void UART1_IRQHandler(void)
{uint8 dat;rt_interrupt_enter();if(UART1->ISR & UART_ISR_TX_INTF)        // 串口发送缓冲空中断{UART1->ICR |= UART_ICR_TXICLR;     // 清除中断标志位}if(UART1->ISR & UART_ISR_RX_INTF)     // 串口接收缓冲中断{uart_getchar(DEBUG_UART, &dat);rt_mb_send(uart_mb, dat);           // 发送邮件UART1->ICR |= UART_ICR_RXICLR;        // 清除中断标志位}rt_interrupt_leave();
}

rtconfig.h文件:

/* RT-Thread config file */#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__#if defined(__CC_ARM) || defined(__CLANG_ARM)
//#include "RTE_Components.h" // 用来开关 FinSH 组件,仅 MDK 会产生该文件#if defined(RTE_USING_FINSH)
#define RT_USING_FINSH
#endif //RTE_USING_FINSH#endif //(__CC_ARM) || (__CLANG_ARM)// <<< Use Configuration Wizard in Context Menu >>>
// <h>Basic Configuration
// <o>Maximal level of thread priority <8-256>
//  <i>Default: 32
#define RT_THREAD_PRIORITY_MAX  8
// <o>OS tick per second
//  <i>Default: 1000   (1ms)
#define RT_TICK_PER_SECOND  1000
// <o>Alignment size for CPU architecture data access
//  <i>Default: 4
#define RT_ALIGN_SIZE   4
// <o>the max length of object name<2-16>
//  <i>Default: 8
#define RT_NAME_MAX    8
// <c1>Using RT-Thread components initialization
//  <i>Using RT-Thread components initialization
#define RT_USING_COMPONENTS_INIT
// </c>#define RT_USING_USER_MAIN// <o>the stack size of main thread<1-4086>
//  <i>Default: 512
#define RT_MAIN_THREAD_STACK_SIZE     512// </h>// <h>Debug Configuration
// <c1>enable kernel debug configuration
//  <i>Default: enable kernel debug configuration
//#define RT_DEBUG
// </c>
// <o>enable components initialization debug configuration<0-1>
//  <i>Default: 0
#define RT_DEBUG_INIT 0
// <c1>thread stack over flow detect
//  <i> Diable Thread stack over flow detect
//#define RT_USING_OVERFLOW_CHECK
// </c>
// </h>// <h>Hook Configuration
// <c1>using hook
//  <i>using hook
//#define RT_USING_HOOK
// </c>
// <c1>using idle hook
//  <i>using idle hook
//#define RT_USING_IDLE_HOOK
// </c>
// </h>// <e>Software timers Configuration
// <i> Enables user timers
#define RT_USING_TIMER_SOFT         0
#if RT_USING_TIMER_SOFT == 0#undef RT_USING_TIMER_SOFT
#endif
// <o>The priority level of timer thread <0-31>
//  <i>Default: 4
#define RT_TIMER_THREAD_PRIO        3
// <o>The stack size of timer thread <0-8192>
//  <i>Default: 512
#define RT_TIMER_THREAD_STACK_SIZE  256
// </e>// <h>IPC(Inter-process communication) Configuration
// <c1>Using Semaphore
//  <i>Using Semaphore
#define RT_USING_SEMAPHORE
// </c>
// <c1>Using Mutex
//  <i>Using Mutex
//#define RT_USING_MUTEX
// </c>
// <c1>Using Event
//  <i>Using Event
#define RT_USING_EVENT
// </c>
// <c1>Using MailBox
//  <i>Using MailBox
#define RT_USING_MAILBOX
// </c>
// <c1>Using Message Queue
//  <i>Using Message Queue
#define RT_USING_MESSAGEQUEUE
// </c>
// </h>// <h>Memory Management Configuration
// <c1>Dynamic Heap Management
//  <i>Dynamic Heap Management
#define RT_USING_HEAP
// </c>
// <c1>using small memory
//  <i>using small memory
#define RT_USING_SMALL_MEM
// </c>
// <c1>using tiny size of memory
//  <i>using tiny size of memory
//#define RT_USING_TINY_SIZE
// </c>
// </h>// <h>Console Configuration
// <c1>Using console
//  <i>Using console
#define RT_USING_CONSOLE
// </c>
// <o>the buffer size of console <1-1024>
//  <i>the buffer size of console
//  <i>Default: 128  (128Byte)
#define RT_CONSOLEBUF_SIZE          128
// </h>#define RT_USING_FINSH#if defined(RT_USING_FINSH)#define FINSH_USING_MSH#define FINSH_USING_MSH_ONLY// <h>Finsh Configuration// <o>the priority of finsh thread <1-7>//  <i>the priority of finsh thread//  <i>Default: 6#define __FINSH_THREAD_PRIORITY     4#define FINSH_THREAD_PRIORITY       (RT_THREAD_PRIORITY_MAX / 8 * __FINSH_THREAD_PRIORITY + 1)// <o>the stack of finsh thread <1-4096>//  <i>the stack of finsh thread//  <i>Default: 4096  (4096Byte)#define FINSH_THREAD_STACK_SIZE     768// <o>the history lines of finsh thread <1-32>//  <i>the history lines of finsh thread//  <i>Default: 5#define FINSH_HISTORY_LINES         1#define FINSH_USING_SYMTAB// </h>
#endif// <<< end of configuration section >>>#endif

common.c文件:

/*********************************************************************************************************************
* COPYRIGHT NOTICE
* Copyright (c) 2019,逐飞科技
* All rights reserved.
* 技术讨论QQ群:一群:179029047(已满)  二群:244861897
*
* 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
* 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
*
* @file                common.c
* @company         成都逐飞科技有限公司
* @author          逐飞科技(QQ3184284598)
* @version         查看doc内version文件 版本说明
* @Software            IAR 8.32.4 or MDK 5.28
* @Target core     MM32F3277
* @Taobao          https://seekfree.taobao.com/
* @date                2021-02-22
********************************************************************************************************************/#include "common.h"
#include "hal_misc.h"CAMERA_TYPE_enum camera_type;                                                    // 摄像头类型变量
uint8 *camera_buffer_addr;                                                      // 摄像头缓冲区地址指针//-------------------------------------------------------------------------------------------------------------------
// @brief      中断初始化
// @param      irqn            中断号,可以查看 reg_common.h 文件中的 IRQn_Type 枚举体定义
// @param      priority        选择该中断优先级 范围 [0-7]
// @param      status          使能或者失能
// @return     void
// Sample usage:                nvic_init(EXTI0_IRQn, 0, ENABLE);               // 外部中断0使能,抢占优先级最高
//-------------------------------------------------------------------------------------------------------------------
void nvic_init(IRQn_Type irqn, uint8 priority, FunctionalState status)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = irqn;                                  // 中断号设置NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= priority & 0x07;       // 抢占优先级值越小,优先级越高NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;                          // 响应优先级值越小,优先级越高NVIC_InitStructure.NVIC_IRQChannelCmd = status;                                // 使能NVIC_Init(&NVIC_InitStructure);
}//-------------------------------------------------------------------------------------------------------------------
// @brief      全局中断使能
// @return     void
// Sample usage:                nvic_interrput_enable();
//-------------------------------------------------------------------------------------------------------------------
void nvic_interrput_enable (void)
{__ASM volatile("cpsie i");
}//-------------------------------------------------------------------------------------------------------------------
// @brief      全局中断失能
// @return     void
// Sample usage:                nvic_interrput_disable();
//-------------------------------------------------------------------------------------------------------------------
void nvic_interrput_disable (void)
{__ASM volatile("cpsid i");
}void NMI_Handler(void)
{while(1);
}
//void HardFault_Handler(void)
//{//  //硬件上访  可能是数组越界或者使用了未初始化的设备
//  //这里提示大家一个问题,经常有人说我的外设初始化了怎么就是要进HardFault呢
//  //很多是因为自己开了中断,然后在中断里面使用了外设,然后他的初始化顺序是先初始化中断然后再初始化外设
//  //那么问题就来了,中断初始化完成之后会部分中断直接进入中断函数或者满足调节也会进入中断函数,那么就会造成中断里面使用到的外设还没被初始化
//  //所以大家需要注意这个问题
//  while(1);
//}
void MemManage_Handler(void)
{while(1);
}
void BusFault_Handler(void)
{while(1);
}
void UsageFault_Handler(void)
{while(1);
}
void SVC_Handler(void)
{while(1);
}
void DebugMon_Handler(void)
{while(1);
}
//void PendSV_Handler(void)
//{//  while(1);
//}

headfile.h文件添加“#include “rtthread.h””

//RTT头文件
#include “rtthread.h”

七、编译运行

可看到板载led持续闪烁
串口持续打印如下数据:


工程源码链接: MM32_RT_thread_Demo.

基于keil环境下mm32f327单片机rtthread的移植相关推荐

  1. Keil环境下完成一个基于STM32汇编程序的编写

    本文内容:\color{red}{本文内容:}本文内容: 1)记录build生成的 hex文件各段的大小,了解Hex文件格式及其前8个字节内容含义: 2)学习在没有硬件条件下进行仿真调试的方法,观察A ...

  2. 计算机网络环境中学科教学,浅谈基于计算机网络环境下的农村小学的科学学科教育...

    浅谈基于计算机网络环境下的农村小学的科学学科教育 [内容摘要] <国家中长期教育改革和发展规划纲要(2010-2020年)>明确提出:加快教育信息化进程.重点加强农村学校信息基础建设,缩小 ...

  3. 基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案

    基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案 参考文章: (1)基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案 (2)https://www.cn ...

  4. 基于SDN环境下的DDoS异常攻击的检测与缓解--实验

    基于SDN环境下的DDoS异常攻击的检测与缓解--实验 基于SDN环境下的DDoS异常攻击的检测与缓解--实验 1.安装floodlight 2.安装sFlow-RT流量监控设备 3.命令行安装cur ...

  5. linux使用gcc实现扫雷,基于linux环境下扫雷应用程序

    基于linux环境下扫雷应用程序 (16页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 <网络操作系统>报告(应用程序开发) ...

  6. 五天完成项目-《基于Linux环境下的Cortex A53的手势识别智能家居》-第四天

    音视频播放功能 <智能家居系列> 一.音频播放 1.Linux下的音频播放实现 2.实现步骤 二.语音播报信息 三.视频播放 1.素材准备 2.实现步骤 四.项目框架搭建 <智能家居 ...

  7. 基于linux环境pdf,基于Linux环境下的Snif论r设计与芸}瑰.PDF

    基于Linux环境下的Snif论r设计与芸}瑰 基于Linux环境下的Snif论r设计与芸}瑰 李刍每莹周姆 铬编程技I:,夏‰骼r实现方法进行了棵耐 7IP.w.h 关键词嗅挺器,滑动窗口,'r(: ...

  8. 五天完成项目-《基于Linux环境下的Cortex A53的手势识别智能家居》-第五天

    视频监控和家电控制 <智能家居系列> 一.视频监控基础 1.摄像头 2.v4l2 3.Linux下的摄像头使用流程 4.烧写程序到开发板 5.运行程序 (先插上摄像头) 二.视频监控功能 ...

  9. Keil环境下用STM32汇编语言工程分析HEX文件内容

    一.创建工程 1创建工程,点击Project,选择第一项创建新工程.并保存文件的地址和文件名. 2 配置环境 ①选择STM32F103RC芯片,点击OK. 然后在CMSIS下选择CORE:Device ...

最新文章

  1. C#中调用Windows API的要点
  2. 第十、十一周项目-阅读程序,写出这些程序的运行结果(1)
  3. 自适应IFRAME的大小
  4. well 这是第一次记录
  5. IBASE category 设置为01的情况下 IBASE自动创建情况
  6. Android View 的滑动
  7. 使用JavaScript的图像识别游戏
  8. OpenCV2和OpenCV3兼容安装
  9. 使用no-gui 模式执行分布式测试
  10. 我的失败与伟大 —— 产品原型的打造
  11. 文字转语音(Python pyttsx3)
  12. android APK加密、签名
  13. 华三OSPF多区域配置实例
  14. 比较常用的平面设计软件都有哪些?
  15. 老板到底能不能,监控到电脑版微信聊天?
  16. 很牛的几篇圈内爆料——影视圈
  17. Ajax的简历技能如何写,web前端简历专业技能填写样本
  18. 【SIN】函数使用技巧
  19. 使用pandas筛选优质基金
  20. 【拆解】Apple Watch Series 6 ,电池更大、陶瓷和蓝宝石外壳更薄,更强硬,更耐磨!...

热门文章

  1. Swoft2.x 小白学习笔记 (二) --- mysql、redis
  2. 地球坐标系与投影方式的理解(关于北京54,西安80,WGS84;高斯,兰勃特,墨卡托投影)
  3. 自然语言理解中的意图识别
  4. 字符函数(strlen、strcpy、strcmp、strerror)
  5. 2021杨雪洋高考成绩查询,十万火急!多省已开通2020高考成绩查询通道(附各省最新查询网址)...
  6. 我们一起学linux之V4L2摄像头应用流程
  7. Android开发框架介绍
  8. CORS error错误 has been blocked by CORS policy前端请求浏览器出错
  9. Ubuntu永久修改USB设备操作权限
  10. 输入框【普通输入框,邮箱输入框,验证码输入框,手机号码输入框】测试用例