单片机 基于rt-thread 系统 使用 CCM内存

发布于:2025-07-08 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、开发环境

开发板:野火stm32f407
系统:rt-thread V4.1.1

二、链接脚本配置

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {  ; RW data
   *(.CCM_RAM)
  
  }
}

具体配置可参考文章链接

https://mp.weixin.qq.com/s/s_CHsM7ykF6-n2dVwfaGUQ

三、测试代码

使用单片机的CCNM内存创建变量和线程,打印变量和线程的地址信息,使用指令查看主RAM的信息。直接贴测试代码,如下:

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-06     SummerGift   first version
 * 2018-11-19     flybreak     add stm32f407-atk-explorer bsp
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

/* defined the LED0 pin: PF7 */
#define LED0_PIN    GET_PIN(F, 7)


/* 定义在CCM RAM里面的变量 */ 
//__attribute__((section (".CCM_RAM"))) uint32_t BufInfo[10];
//__attribute__((section (".CCM_RAM"))) uint16_t Count=5;//可以定义初值

 uint32_t BufInfo[10] __attribute__((section (".CCM_RAM")));
 uint16_t Count __attribute__((section (".CCM_RAM"))) =5;//可以这样定义初值

  uint16_t CNT __attribute__((section(".CCM_RAM"), used));//使用 __attribute__((used)) 确保变量不被优化掉
__attribute__((section (".CCM_RAM"),used)) uint16_t NUM=5;//使用 __attribute__((used)) 确保变量不被优化掉

/* 定义在CCM RAM里面的线程 */ 
#if defined(RT_VERSION_CHECK) && (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1))
    rt_align(RT_ALIGN_SIZE)
#else
    ALIGN(RT_ALIGN_SIZE)
#endif
//__attribute__((section (".CCM_RAM"))) static char thread1_stack[1024*60];
//__attribute__((section (".CCM_RAM"))) static struct rt_thread thread1;

 static char thread1_stack[1024*2] __attribute__((section (".CCM_RAM")));
 static struct rt_thread thread1 __attribute__((section (".CCM_RAM")));
 
 #if defined(RT_VERSION_CHECK) && (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1))
    rt_align(RT_ALIGN_SIZE)
#else
    ALIGN(RT_ALIGN_SIZE)
#endif
 static char thread2_stack[1024*2] __attribute__((section (".CCM_RAM")));
 static struct rt_thread thread2 __attribute__((section (".CCM_RAM")));




/* 定义在CCM RAM里面的信号量 */ 
__attribute__((section (".CCM_RAM"))) static struct rt_semaphore test_sem;

/* 线程 1 入口 */
static void thread1_entry(void *param)
{
    rt_uint32_t count = 0;
    rt_kprintf("count_addr= %x\r\n",&count);
    rt_uint32_t buf[10];
    for(int i=0;i<10;i++)
    {
        rt_kprintf("buf[%d]_addr= %x\r\n",i,&buf[i]);
    }
    /* 线程 1 拥有较高的优先级,以抢占线程 1 而获得执行 */
    static rt_err_t result;
    for (;;)
    {
        
        
        /* 永久方式等待信号量,获取到信号量,则执行 number 自加的操作 */
        result = rt_sem_take(&test_sem, RT_WAITING_FOREVER);
        if ( result == RT_EOK)
        {
            /* 线程 1 打印计数值 */
            rt_kprintf("thread1 count: %d\n", count++);
        }
        else
        {
            rt_kprintf("thread 1 result is %d\n", result);
        }
    }
    /* 线程 1 运行结束后也将自动被系统脱离 */
    
    
}


/* 线程 2 入口 */
static void thread2_entry(void *param)
{
    rt_uint32_t count = 0;
    rt_kprintf("count_addr2= %x\r\n",&count);
    rt_uint32_t buf[10];
    for(int i=0;i<10;i++)
    {
        rt_kprintf("buf[%d]_addr2= %x\r\n",i,&buf[i]);
    }

    for (;;)
    {
        /* 线程 1 打印计数值 */
        rt_kprintf(" release test_sem.\n");
        rt_sem_release(&test_sem);
        rt_thread_mdelay(10000);
    }
    /* 线程 1 运行结束后也将自动被系统脱离 */
    
    
}


int main(void)
{
    /* set LED0 pin mode to output */
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
    
    Count++;
    
    for(int i=0;i<10;i++)
    {
        rt_kprintf("BufInfo[%d]_addr= %x\r\n",i,&BufInfo[i]);
    }
    
    BufInfo[0] = Count;
    rt_kprintf("CCMBuf1_addr= %x, BufInfo[0] = %d\r\n",BufInfo,BufInfo[0]);
    
    rt_kprintf("CCMCount_addr= %x, Count = %d\r\n",&Count,Count);   
    rt_kprintf("CNT= %x, CNT = %d\r\n",&CNT,CNT);  
    rt_kprintf("NUM= %x, NUM = %d\r\n",&NUM,NUM);  
    
    rt_thread_mdelay(5000);  
    
    rt_kprintf("intput free\r\n");  
    rt_thread_mdelay(10000);
    
    
    rt_sem_init(&test_sem, "testSem",     0,      RT_IPC_FLAG_PRIO);
    rt_kprintf("test_sem_addr= %x\r\n",&test_sem); 
    rt_thread_mdelay(10000);
    
    /* 初始化线程 1,名称是 thread1,入口是 thread1_entry */
    rt_thread_init(&thread1,
                   "thread1",
                   thread1_entry,
                   RT_NULL,
                   &thread1_stack[0],
                   sizeof(thread1_stack),
                   25, 
                   5);
    rt_thread_startup(&thread1);
    
    
    rt_kprintf("thread1_addr= %x\r\n",&thread1);  
    rt_kprintf("thread1_stack_addr= %x\r\n",thread1_stack);   
    
    rt_thread_mdelay(10000);
                   
        /* 初始化线程 2,名称是 thread2,入口是 thread2_entry */
    rt_thread_init(&thread2,
                   "thread2",
                   thread2_entry,
                   RT_NULL,
                   &thread2_stack[0],
                   sizeof(thread2_stack),
                   25, 
                   5);
    rt_thread_startup(&thread2);
    
    
    rt_kprintf("thread2_addr= %x\r\n",&thread2);  
    rt_kprintf("thread2_stack_addr= %x\r\n",thread2_stack);                  
                   
    rt_thread_mdelay(10000);                

    rt_kprintf("intput free\r\n"); 
                   
    rt_thread_mdelay(10000);
        
                    
                   
    while (1)
    {
        rt_pin_write(LED0_PIN, PIN_HIGH);
        rt_thread_mdelay(500);
        rt_pin_write(LED0_PIN, PIN_LOW);
        rt_thread_mdelay(500);

    }
}

测试结果:
打印变量的信息
在这里插入图片描述

打印线程的信息
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到