KEIL+MM3F0121_RTT-NANO的移植
一、概述:
本次任务主要是移植RTT-NANO到MM32上运行,由于只有8K RAM,因此移植NANO版本的rt-thread,编译环境为keil。
二、官网下载rtt-nano的包
从官网下载软件包,打开后如下图所示:

bsp:保留board.c和rtconfig.h,其他的删了。
include:头文件目录
components:组件文件夹
libcpu:处理器相关的启动文件(mm32f0120属于cortex-m0系列,只要保留cortex-m0文件夹即可,其他都可以删除)
src:内核源码
三、KEIL添加源文件
我们需要删除和重新分类一下官网下载的文件,也可以不做改动,在KEIL中添加需要的,但由于我思维秉承文件夹和工程一致,方便后续其他开发环境使用,所以做出修改
如下图所示:

可能需要注意的是board.c文件的内容,以及it.c的两个重复的handler需要删除it.c中的。
期间遇到了val_list 错误,在rtconfig.h中添加 #define RT_USING_LIBC便没有了错误。
如下图为KEIL添加完成之后各部分内容包含的文件:


四、添加keil的include
点击魔法棒,c/c++添加include相关内容

五、需要修改的文件
需要修改的文件放到port下面了:board.c和 rtconfig.h
board.c
里面主要是修改 RT_HEAP_SIZE ,根据是否启用内存堆以及芯片内存的大小来决定,注意对齐问题;
rt_os_tick_callback需要放到systick_handler里面去执行,也要注意这个中断的周期,一般为1ms,也就是rtos调度的周期。
板子初始化,主要是在前面加入时钟的初始化以及打印串口的初始化。
consel相关设置
板子初始化,主要是在前面加入时钟的初始化以及打印串口的初始化。
#include <rthw.h>
#include <rtthread.h>
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
/*
* Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
* the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
*/
#define RT_HEAP_SIZE (1024+1024)
static rt_uint32_t rt_heap[RT_HEAP_SIZE/4];
RT_WEAK void *rt_heap_begin_get(void)
{
return (uint8_t *)rt_heap;
}
RT_WEAK void *rt_heap_end_get(void)
{
return (uint8_t *)rt_heap + RT_HEAP_SIZE;
}
#endif
void rt_os_tick_callback(void)
{
rt_interrupt_enter();
rt_tick_increase();
rt_interrupt_leave();
}
/**
* This function will initial your board.
*/
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.
*/
PLATFORM_Init();
/* 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
}
#ifdef RT_USING_CONSOLE
static int uart_init(void)
{
//#error "TODO 2: Enable the hardware uart and config baudrate."
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."
printf(str);
}
#endif
rtconfig.h
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
#define RT_USING_LIBC
// <<< 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 32
// <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 1
// <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 4
// <o>The stack size of timer thread <0-8192>
// <i>Default: 512
#define RT_TIMER_THREAD_STACK_SIZE 512
// </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_SIGNALS
// </c>
// <c1>Using Signals
// <i>Using Signals
//#define RT_USING_MAILBOX
// </c>
// <c1>Using Message Queue
// <i>Using Message Queue
//#define RT_USING_MESSAGEQUEUE
// </c>
// </h>
// <h>Memory Management Configuration
// <c1>Memory Pool Management
// <i>Memory Pool Management
//#define RT_USING_MEMPOOL
// </c>
// <c1>Dynamic Heap Management(Algorithm: small memory )
// <i>Dynamic Heap Management
#define RT_USING_HEAP
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
// </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>
// <h>FinSH Configuration
// <c1>include finsh config
// <i>Select this choice if you using FinSH
//#include "finsh_config.h"
// </c>
// </h>
// <h>Device Configuration
// <c1>using device framework
// <i>using device framework
//#define RT_USING_DEVICE
// </c>
// </h>
// <<< end of configuration section >>>
#endif
五、运行结果
新建一个plt任务,打印不同的信息
int main(void)
{
plt_init();
create_task_plt();
while (1)
{
rt_thread_mdelay(100);
printf("app-thread run\n");
}
}
void plt_thread_entry(void *parameter)
{
while (1)
{
plt_mainloop();
rt_thread_mdelay(1);
}
}
void create_task_plt(void)
{
rt_thread_t tid;
tid = rt_thread_create("plt", plt_thread_entry, RT_NULL,
512, 1, 20);
if (tid == RT_NULL)
{
rt_kprintf("plt thread create error tid =%d\n", tid);
}
else
{
rt_kprintf("plt thread create success\n");
rt_thread_startup(tid);
}
}
如下图为串口打印的结果:

六、遇到的问题
主要是遇到了一个main任务无法运行的问题。
开始以为是芯片的内存太小的原因导致的,寻找了好久,又查看rtt的运行机制花了很久。
//#define RT_USING_HEAP
//#define RT_USING_SMALL_MEM
如果定义了上方两个函数就会一直在idle.c中,无法跳转到main,最终定位是创建时无法申请到内存,但是明明heap给了2K了还是一样不行,这样的话只能静态创建main了,再深入测试发现是rt_malloc失败。
最后发现必须要使能 RT_USING_SMALL_MEM_AS_HEAP
