参考资料:RT-Thread 文档中心
环境:1、stm32f103开发板 2、keil 3、rt-thread nano pack
步骤:
1、添加rt-thread nano到keil工程,步骤参见 基于 Keil MDK 移植 RT-Thread Nano
2、stm32f10x_it.c文件下删除异常处理函数 HardFault_Handler()
和悬挂处理函数 PendSV_Handler(),
这两个函数已由 RT-Thread 实现,所以需要删除工程里中断服务例程文件中的这两个函数,避免在编译时产生重复定义。
3、SysTick_Handler()
中断服务例程由用户在 board.c 中重新实现,stm32f10x_it.c文件下删除 SysTick_Handler()
,避免在编译时产生重复定义。
4、board.c文件下配置rt_hw_board_init函数,屏蔽掉 #error "TODO 1: OS Tick Configuration.",重新定义函数SysTick_Handler,添加系统时钟配置 SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
void SysTick_Handler()
{
rt_interrupt_enter();
rt_tick_increase();
rt_interrupt_leave();
}
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.
*/
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
}
5、board.c文件下 添加头文件#include "stm32f10x.h",main.c文件下添加头文件 #include <rtthread.h>。
6、编写测试例程
void thread01_entry( void *parameter);
static rt_thread_t thread01 = RT_NULL;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
thread01 = rt_thread_create( "thread01",thread01_entry,RT_NULL,512,3,20);
rt_thread_startup(thread01);
}
void thread01_entry( void *parameter)
{
while(1)
{
LED0=!LED0;
rt_thread_delay(2000);
}
}
//void thread01_entry( void *parameter)
//{
// u16 t;
// u16 len;
// u16 times=0;
// while(1)
// {
// if(USART_RX_STA&0x8000)
// {
// len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
// printf("\r\n您发送的消息为:\r\n\r\n");
// for(t=0;t<len;t++)
// {
// USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
// while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
// }
// printf("\r\n\r\n");//插入换行
// USART_RX_STA=0;
// }else
// {
// times++;
// if(times%5000==0)
// {
// printf("\r\n战舰STM32开发板 串口实验\r\n");
// printf("正点原子@ALIENTEK\r\n\r\n");
// }
// if(times%200==0)printf("请输入数据,以回车键结束\n");
// if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
// rt_thread_delay(10);
// }
// }
//}
7、烧录代码,程序可以实现RTOS的基本功能
移植shell步骤
1、rtconfig.h文件下打开RT_USING_CONSOLE注释,编译报错后,注释报错代码,board.c重新定义rt_hw_console_output函数
void rt_hw_console_output(const char *str)
{
rt_enter_critical();
/* 直到字符串结束 */
while ( *str != '\0' )
{
/* 换行 */
//RT-Thread 系统中已有的打印均以 \n 结尾,而并非 \r\n,所以在字符输出时,需要在输出 \n 之前输出 \r,完成回车与换行,否则系统打印出来的信息将只有换行
if ( *str == '\n' )
{
USART_SendData( USART1, '\r' );
while ( USART_GetFlagStatus( USART1, USART_FLAG_TXE ) == RESET );
}
USART_SendData( USART1, *str++ );
while ( USART_GetFlagStatus( USART1, USART_FLAG_TXE ) == RESET );
}
/* 退出临界段 */
rt_exit_critical();
}
2、编写下载后,串口工具打印相关信息
3、参考教程 在 RT-Thread Nano 上添加控制台与 FinSH
实现基本的串口打印后,添加shell组件
rtconfig.h 中打开 finsh 相关选项,如下图:
编译后有报错,finsh_port.c需要实现rt_hw_console_getchar函数,如下所示
RT_WEAK char rt_hw_console_getchar(void)
{
/* Note: the initial value of ch must < 0 */
int ch = -1;
//查询方式实现,记得将Usart1初始化中的中断接收配置相关代码注释掉
/*等待串口1输入数据*/
if( USART_GetFlagStatus( USART1, USART_FLAG_RXNE ) != RESET )
{
ch = ( int )USART_ReceiveData( USART1 );
USART_ClearFlag( USART1, USART_FLAG_RXNE );
}
else
{
if( USART_GetFlagStatus( USART1, USART_FLAG_ORE ) != RESET )
{
USART_ClearFlag( USART1, USART_FLAG_ORE );
}
rt_thread_mdelay( 10 );
}
return ch;
//#error "TODO 4: Read a char from the uart and assign it to 'ch'."
return ch;
}
4、串口shell实现