打印
[MM32生态]

【灵动微电子MM32F0121测评】-002-移植RTT-NANO

[复制链接]
94|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
letchgo|  楼主 | 2025-6-22 15:20 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

KEIL+MM3F0121_RTT-NANO的移植

一、概述:

本次任务主要是移植RTT-NANO到MM32上运行,由于只有8K RAM,因此移植NANO版本的rt-thread,编译环境为keil。

二、官网下载rtt-nano的包

从官网下载软件包,打开后如下图所示:

image.png

bsp:保留board.c和rtconfig.h,其他的删了。

include:头文件目录

components:组件文件夹

libcpu:处理器相关的启动文件(mm32f0120属于cortex-m0系列,只要保留cortex-m0文件夹即可,其他都可以删除)

src:内核源码

三、KEIL添加源文件

我们需要删除和重新分类一下官网下载的文件,也可以不做改动,在KEIL中添加需要的,但由于我思维秉承文件夹和工程一致,方便后续其他开发环境使用,所以做出修改

如下图所示:

image.png

可能需要注意的是board.c文件的内容,以及it.c的两个重复的handler需要删除it.c中的。

期间遇到了val_list 错误,在rtconfig.h中添加 #define RT_USING_LIBC便没有了错误。

如下图为KEIL添加完成之后各部分内容包含的文件:

image.pngimage.png

四、添加keil的include

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

image.png

五、需要修改的文件

需要修改的文件放到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);
  }
}

如下图为串口打印的结果:

image.png

六、遇到的问题

主要是遇到了一个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

image.png

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

38

帖子

1

粉丝