一、开发环境
开发板:野火stm32f407
系统:rt-thread V4.1.1
二、链接脚本配置
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08000000 0x00100000 { ; load region size_regionER_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)
#elseALIGN(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)
#elseALIGN(RT_ALIGN_SIZE)
#endifstatic 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);}
}
测试结果:
打印变量的信息
打印线程的信息