准备:
1.Keil5_AT32MCU_AddOn_V2.2.7.zip
https://www.arterytek.com/file/download/1691
2.RealThread.RT-Thread.3.1.5.pack
https://www.rt-thread.org/download/mdk/RealThread.RT-Thread.3.1.5.pack
开始建立工程:
1.新建AT32工程
2.在Manage Run-time Environment中选择以下内容
3.Options(仅列出需要注意的选项)
4.注释掉 at32f403a_407_int.c中HardFault_Handler、PendSV_Handler、SysTick_Handler
5.配置rtthread
6.配置board.c中#error "TODO 1: OS Tick Configuration."
/****************************************************************************
* 名 称:void SysTick_Handler(void)
* 描 述:Systick中断服务程序,这个函数必须要更新rtthread系统节拍
* 参 数:
* 调 用:
****************************************************************************/
void SysTick_Handler(void)
{
rt_os_tick_callback();
}
void rt_hw_board_init(void)
{
//#error "TODO 1: OS Tick Configuration."
/*
* 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.
*/
/* Call components board initial (use INIT_BOARD_EXPORT()) */
/****************************************************************************/
//设定系统时钟
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
system_clock_config();
//设定systick
systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/****************************************************************************/
#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
}
7.配置board.c中#error "TODO 2: Enable the hardware uart and config baudrate."和#error "TODO 3: Output the string 'str' through the uart."
static int uart_init(void)
{
//#error "TODO 2: Enable the hardware uart and config baudrate."
/****************************************************************************/
debug_uart_init(115200);
/****************************************************************************/
return 0;
}
INIT_BOARD_EXPORT(uart_init);
void rt_hw_console_output(const char *str)
{
//#error "TODO 3: Output the string 'str' through the uart."
/****************************************************************************/
rt_enter_critical();
/* 直到字符串结束 */
while (*str != '\0')
{
/* 换行 */
if (*str == '\n')
{
// 发送
usart_data_transmit(USART1, '\r');
// 发送完成标志
while (usart_flag_get(USART1, USART_TDC_FLAG) == RESET);
}
usart_data_transmit(USART1, *str++);
// 发送完成标志
while (usart_flag_get(USART1, USART_TDC_FLAG) == RESET) ;
}
/* 退出临界段 */
rt_exit_critical();
/****************************************************************************/
}
8.配置finsh_port.c中#error "TODO 4: Read a char from the uart and assign it to 'ch'."
RT_WEAK char rt_hw_console_getchar(void)
{
/* Note: the initial value of ch must < 0 */
int ch = -1;
//#error "TODO 4: Read a char from the uart and assign it to 'ch'."
/****************************************************************************/
if (usart_flag_get(USART1, USART_RDBF_FLAG) != RESET)
{
ch = USART1->dt & 0xff;
}
else
{
if(usart_flag_get(USART1, USART_ROERR_FLAG) != RESET)
{
/* clear overrun flag */
USART1->sts;
USART1->dt;
}
rt_thread_mdelay(1);
}
/****************************************************************************/
return ch;
}
9.main.c内容如下
#include <rtthread.h>
#include <project_config.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
ALIGN(RT_ALIGN_SIZE) //RT_ALIGN_SIZE此处为4,要求给下面的数组分配地址时满足4字节对齐
/* 定义线程栈 */
static struct rt_thread thread1;
rt_uint8_t thread1_stack[1024];
static struct rt_thread thread2;
rt_uint8_t thread2_stack[1024];
/****************************************************************************
* 名 称:void thread1_entry(void *p_arg)
* 描 述:
* 参 数:
* 调 用:
****************************************************************************/
/* 线程 1 */
void thread1_entry(void *p_arg) // (1)
{
while (1)
{
delay_ms(100);
}
}
/****************************************************************************
* 名 称:void thread2_entry(void *p_arg)
* 描 述:
* 参 数:
* 调 用:
****************************************************************************/
/* 线程 2 */
void thread2_entry(void *p_arg) // (2)
{
while (1)
{
delay_ms(500);
POUT1_1;
delay_ms(500);
POUT1_0;
}
}
/****************************************************************************
* 名 称:void thread_init(void)
* 描 述:线程初始化
* 参 数:
* 调 用:
****************************************************************************/
void thread_init(void)
{
LOG_I("**************************************************");
/* 初始化线程1,名称是thread1,入口是thread1_entry */
if (rt_thread_init(&thread1, "thread1", thread1_entry, RT_NULL,
&thread1_stack[0], sizeof(thread1_stack), 1, 10) == RT_EOK)
{
LOG_I("'thread1' thread startup...");
rt_thread_startup(&thread1);
}
else
{
LOG_E("'thread1' Creation failure!");
}
/* 初始化线程2,名称是thread2,入口是thread2_entry */
if (rt_thread_init(&thread2, "thread2", thread2_entry, RT_NULL,
&thread2_stack[0], sizeof(thread2_stack), 2, 10) == RT_EOK)
{
LOG_I("'thread2' thread startup...");
rt_thread_startup(&thread2);
}
else
{
LOG_E("'thread2' Creation failure!");
}
LOG_I("**************************************************");
}
/****************************************************************************
* 名 称:
* 描 述:
* 参 数:
* 调 用:
****************************************************************************/
int main()
{
//keil rtthread main函数 不能用delay,否则main线程会卡死 。只适合初始化开机条件
//问题修复方法,启用 RT_USING_HEAP
user_board_init();
thread_init();
while(1)
{
delay_ms(500);
POUT2_1;
delay_ms(500);
POUT2_0;
}
}