文章目录[隐藏]
1.cubemx建立工程
选择合适的芯片版本,编辑芯片管脚配置如下
激活uart1,配置串口数据输出及全局中断,选择ide选择mdk-arm,注意生成代码时勾选如下选项
2、keli引入rt-threand及修改相关代码
首先从网上下载rt-threand keli包如下图所示
之后将该包导入keli5。在打开项目后,选择如下选项
在其中选择引入rt-threand
引入后项目结构如图所示
将项目中自动生成的异常处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler()删除(通常在stm32f1xx_it.h中)。之后需要在 board.c 中实现 系统时钟配置(为 MCU、外设提供工作时钟)与 os_tick 的配置 (为操作系统提供心跳 / 节拍)。
代码如下所示
/**
* This function will initial your board.
*/
/* board.c */
/* timer 定时器中断服务函数调用 rt_os_tick_callback function,cortex-m 架构使用 SysTick_Handler() */
void rt_os_tick_callback(void)
{
rt_interrupt_enter();
rt_tick_increase();
rt_interrupt_leave();
}
/* cortex-m 架构使用 SysTick_Handler() */
void SysTick_Handler()
{
rt_os_tick_callback();
}
void rt_hw_board_init(void)
{
/*
* TODO 1: OS Tick Configuration
* Enable the hardware timer and call the rt_os_tick_callback function
* periodically with the frequency RT_TICK_PER_SECOND.
*/
/* 1、系统、时钟初始化 */
HAL_Init(); // 初始化 HAL 库
SystemClock_Config(); // 配置系统时钟
SystemCoreClockUpdate(); // 对系统时钟进行更新
/* 2、OS Tick 频率配置,RT_TICK_PER_SECOND = 1000 表示 1ms 触发一次中断 */
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_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());
#endif
}
由于 SysTick_Handler() 中断服务例程由用户在 board.c 中重新实现,做了系统 OS_Tick,所以还需要删除工程里中原本已经实现的 SysTick_Handler() ,避免在编译时产生重复定义。
启用系统堆,修改rtconfig.h如下所示
同时,在borad.c中,可以调整系统堆空间大小,堆空间大小根据芯片ram大小调整。本次调整大小如下所示
将while循环前代码修改为如下所示:
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
rt_thread_startup(rt_thread_create("led1",led1,0,256,1,10));
rt_thread_mdelay(500);
rt_thread_startup(rt_thread_create("led2",led2,0,256,2,10));
rt_thread_mdelay(500);
rt_thread_startup(rt_thread_create("sendchar",sendchar,0,256,3,10));
相应函数实现如下所示
void led1(void* p){
while (1)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
rt_thread_delay(200);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
rt_thread_delay(500);
// rt_schedule();
}
}
void led2(void* p){
while (1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
rt_thread_delay(500);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
rt_thread_delay(200);
// rt_schedule();
}
}
/**
* @brief 重定向printf函数到串口
*
* @param None
* @retval None
*
* @attention None
*
*/
int fputc(int ch, FILE * f)
{
rt_enter_critical();
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);///<普通串口发送数据
rt_exit_critical();
return ch;
}
void sendchar(void *p){
while(1){
rt_enter_critical();
printf("hello world\n");
rt_exit_critical();
rt_thread_delay(500);
}
}
二、使用步骤
虚拟示波器显示结果如下:
串口输出信息如下:
总结
rt-threand作为物联网中一个rtos系统,移植相对于usos要简单许多,入门难度也要简单许多,在ucos中需要修改很多才能实现的功能通过rt-threand可以相对简单的实现。
参考
版权声明:本文为CSDN博主「weixin_45747542」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45747542/article/details/122134595
暂无评论