本篇只要介绍这么使用STM32CubeMx工具添加RT-Thread操作系统组件,码代码的IDE是keil。介绍单线程SRAM静态内存使用。如果还不知道,这么使用STM32CubeMx工具添加RT-Thread操作系统组件,请移步到《基于 STM32CubeMX 添加 RT-Thread 操作系统组件(一)- 详细介绍操作步骤》文章阅读。好了,喝杯茶先^_^,继续前行。上一篇介绍关于《内存管理》
#include "rtthread.h"
#include "main.h"
#include "stdio.h"
#include
#include "usart.h"
/* 定义线程控制块 */
static rt_thread_t key_thread = RT_NULL;
static rt_thread_t usart_thread = RT_NULL;
/* 定义消息队列控制块 */
rt_mq_t test_mq = RT_NULL;
/* 定义信号量控制块 */
rt_sem_t test_sem = RT_NULL;
/* 定义申请内存的指针 */
static rt_uint32_t *p_test = RT_NULL;
/* 变量声明 */
/* 相关宏定义 */
#define USART_RBUFF_SIZE 1024
char Usart_Rx_Buf[USART_RBUFF_SIZE];
/* 函数声明 */
static void key_thread_entry(void* parameter);
static void usart_thread_entry(void* parameter);
void MX_UART_IT_Init(void)
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart1, (uint8_t*)Usart_Rx_Buf, USART_RBUFF_SIZE);
}
int MX_RT_Thread_Init(void)
{
rt_kprintf("This is an RTT interrupt management experiment!\n");
rt_kprintf("Press KEY1 | KEY2 to trigger an interrupt!\n");
rt_kprintf("Serial port send data trigger interrupt, thread process data!\n");
/* 创建一个消息队列 */
test_mq = rt_mq_create("test_mq",/* 消息队列名字 */
4, /* 消息的最大长度 */
2, /* 消息队列的最大容量 */
RT_IPC_FLAG_FIFO);/* 队列模式 FIFO(0x00)*/
if (test_mq != RT_NULL)
rt_kprintf("Message queue created successfully!\n\n");
/* 创建一个信号量 */
test_sem = rt_sem_create("test_sem",/* 消息队列名字 */
0, /* 信号量初始值,默认有一个信号量 */
RT_IPC_FLAG_FIFO); /* 信号量模式 FIFO(0x00)*/
if (test_sem != RT_NULL)
rt_kprintf("Semaphore created successfully!\n\n");
/* 创建一个线程 */
key_thread = /* 线程控制块指针 */
rt_thread_create( "key", /* 线程名字 */
key_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
1, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (key_thread != RT_NULL)
rt_thread_startup(key_thread);
else
return -1;
usart_thread = /* 线程控制块指针 */
rt_thread_create( "usart", /* 线程名字 */
usart_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
2, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (usart_thread != RT_NULL)
rt_thread_startup(usart_thread);
else
return -1;
}
/*
************************************************************
* 线程定义
*********************************************************
*/
static void key_thread_entry(void* parameter)
{
rt_err_t uwRet = RT_EOK;
uint32_t r_queue;
/* 线程都是一个无限循环,不能返回 */
while (1) {
/* 队列读取(接收),等待时间为一直等待 */
uwRet = rt_mq_recv(test_mq, /* 读取(接收)队列的 ID(句柄) */
&r_queue, /* 读取(接收)的数据保存位置 */
sizeof(r_queue), /* 读取(接收)的数据的长度 */
RT_WAITING_FOREVER); /* 等待时间:一直等 */
if (RT_EOK == uwRet) {
rt_kprintf("The interrupt is triggered by KEY %d!\n",r_queue);
} else {
rt_kprintf("Data receiving error, error code:0x%lx\n",uwRet);
}
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
}
}
static void usart_thread_entry(void* parameter)
{
rt_err_t uwRet = RT_EOK;
/* 线程都是一个无限循环,不能返回 */
while (1) {
uwRet = rt_sem_take(test_sem, /* 获取串口中断的信号量 */
0); /* 等待时间: 0 */
if (RT_EOK == uwRet) {
rt_kprintf("Receive the data:%s\n",Usart_Rx_Buf);
memset(Usart_Rx_Buf,0,USART_RBUFF_SIZE);/* 清零 */
HAL_UART_Receive_DMA(&huart1, (uint8_t*)Usart_Rx_Buf, USART_RBUFF_SIZE);
}
}
}
#include "stm32f1xx_hal.h"
#include "rtthread.h"
#include "gpio.h"
#include "usart.h"
/* 外部定义消息队列控制块 */
extern rt_mq_t test_mq;
extern rt_sem_t test_sem;
uint32_t send_data1 = 1;
uint32_t send_data2 = 2;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
void DEBUG_USART_IRQHandler(void);
/************************************************************************
* @ 函数名 :
* @ 功能说明: 外部中断服务函数
* @ 参数 : 无
* @ 返回值 : 无
********************************************************************/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* 进入中断 */
rt_interrupt_enter();
switch(GPIO_Pin)
{
case KEY1_Pin:
/* 将数据写入(发送)到队列中,等待时间为 0 */
rt_mq_send( test_mq, /* 写入(发送)队列的 ID(句柄) */
&send_data1, /* 写入(发送)的数据 */
sizeof(send_data1)); /* 数据的长度 */
break;
case KEY2_Pin:
/* 将数据写入(发送)到队列中,等待时间为 0 */
rt_mq_send( test_mq, /* 写入(发送)队列的 ID(句柄) */
&send_data2, /* 写入(发送)的数据 */
sizeof(send_data2)); /* 数据的长度 */
break;
default:
break;
}
/* 离开中断 */
rt_interrupt_leave();
}
// 串口中断服务函数
void DEBUG_USART_IRQHandler(void)
{
uint32_t tmp_flag = 0;
uint32_t temp;
/* 进入中断 */
rt_interrupt_enter();
tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
if((tmp_flag != RESET))//idle标志被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
//temp = huart1.Instance->SR; //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
//temp = huart1.Instance->DR; //读取数据寄存器中的数据
//这两句和上面那句等效
HAL_UART_DMAStop(&huart1); //
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数
temp = hdma_usart1_rx.Instance->CNDTR;//读取NDTR寄存器 获取DMA中未传输的数据个数
//这句和上面那句等效
//rx_len = USART_RBUFF_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
//给出二值信号量,发送接收到新数据标志,供前台程序查询
rt_sem_release(test_sem);
}
/* 离开中断 */
rt_interrupt_leave();
}
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
extern void DEBUG_USART_IRQHandler(void);
/* USER CODE END TD */
.
.
.
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
DEBUG_USART_IRQHandler(); //新增串口中断函数
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
extern void MX_UART_IT_Init(void);
extern int MX_RT_Thread_Init(void);
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
MX_UART_IT_Init();
MX_RT_Thread_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
#include "usart.h"
.
.
.
RT_WEAK void rt_hw_console_output(const char *str)
{
/* empty console output */
/* 进入临界段 */
rt_enter_critical();
/* 直到字符串结束 */
while (*str!='\0') {
/* 换行 */
if (*str=='\n') {
HAL_UART_Transmit(&huart1,(uint8_t *)'\r',1,1000);
}
HAL_UART_Transmit(&huart1,(uint8_t *)(str++),1,1000);
}
/* 退出临界段 */
rt_exit_critical();
}