一、开发环境
开发板:野火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);
}
}
测试结果:
打印变量的信息
打印线程的信息