硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4269|回复: 12
收起左侧

[有问必答] 如何把UCOSIII系统内存放到STM32F429的CCM空间

[复制链接]

98

主题

340

回帖

634

积分

金牌会员

积分
634
发表于 2017-10-10 17:57:46 | 显示全部楼层 |阅读模式
如题,192K的内存现在有点儿捉襟见肘了,想到充分利用CCM内存,所以想把UCOSIII系统内存放到CCM里面.
网上看别人的例子试着在.sct文件里面定义,但试了一遍,只有一下几个系统文件可以包含
sct文件总新增以下代码

  CCM_IRAM 0x10000000 0x00010000{
  os_cpu_c.o(+RW +ZI)   
  os_prio.o(+RW +ZI)   
  os_var.o(+RW +ZI)   
  os_cfg_app.o(+RW +ZI)   
  lib_mem.o(+RW +ZI)   
  }
MAP文件中会有以下变化

    Execution Region CCM_IRAM (Base: 0x10000000, Size: 0x00001ec0, Max: 0x00010000, ABSOLUTE)


    Base Addr    Size         Type   Attr      Idx    E Section Name        Object


    0x10000000   0x00000004   Data   RW        13820    .data               lib_mem.o
    0x10000004   0x00000004   Data   RW        14624    .data               os_prio.o
    0x10000008   0x000000c4   Data   RW        15176    .data               os_var.o
    0x100000cc   0x00000004   Data   RW        15203    .data               os_cpu_c.o
    0x100000d0   0x00000c14   Zero   RW        13819    .bss                lib_mem.o
    0x10000ce4   0x00000d80   Zero   RW        14127    .bss                os_cfg_app.o
    0x10001a64   0x0000045c   Zero   RW        15175    .bss                os_var.o

确实是定义到CCM里面了,但空间明显很少啊,才7K左右,应该还有大把的系统内存没定义过来,
随便又加了一个os_cfg_app.o文件,会有一下报警,其它的os打头的文件也都是提示以下报警:
.\Output\FTU_F429.sct(20): warning: L6314W: No section matches pattern os_cfg_app.o(RW).
.\Output\FTU_F429.sct(20): warning: L6314W: No section matches pattern os_cfg_app.o(ZI).
KEIL官网的解答如下
It seems that one linker directive specifies a module which either does not exist or it does not contain the RO/RW/ZI data which you are trying to locate into a specific memory area.
文件肯定是存在的,但说里面没有RW.ZI变量也不对啊,MAP文件中提示是有文件的啊

不知硬汉哥是否研究过这方面,在此先谢过.
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107527
QQ
发表于 2017-10-10 18:20:22 | 显示全部楼层
我不是用的分散加载,我是直接修改代码,主要是任务栈和TCB控制块,其它改不改意义不大。这个综合的示波器例子就是用的CCM。
http://www.armbbs.cn/forum.php?mod=viewthread&tid=3886

=======================
友情提示:
1. 主要修改os_cfg_app.c文件
(1) DATA STORAGE 部分
(2) CONSTANTS 部分
(3) TOTAL SIZE OF APPLICATION CONFIGURATION 部分
2. os.h文件从1505行开始地方
3. 修改后,全部任务栈和用户TCB(任务控制块)使用CCM RAM。
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 09:22:03 | 显示全部楼层
修改UCOSIII源码?用__attribute__指定?可怎么有效的分配内存呢?
比如按照顺序都排列好任务堆栈内存空间了,后期中间有一个堆栈想扩大内存,那它后面的变量地址岂不都要往后面移动?
任务栈也用CCM的话,在任务里面定义的变量就不能用DMA访问了吧.
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 09:37:26 | 显示全部楼层
2. os.h文件从1505行开始地方
3. 修改后,全部任务栈和用户TCB(任务控制块)使用CCM RAM。


你这句话的意思是修改了os.h文件后,所有的任务栈和TCB都会默认定义到CCM空间吗?
可我看了os.h文件,1505行以后没啥要修改的啊,都是一些结构体类型和函数的声明.
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 09:38:17 | 显示全部楼层
QQ截图20171011093312.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107527
QQ
发表于 2017-10-11 09:56:03 | 显示全部楼层
在main.c文件里面呢,剩下自己看下即可。
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: Stack_Init
  4. *    功能说明: 任务和系统堆栈全部使用CCM,任务控制块也使用CCM空间。
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. static void Stack_Init(void)
  10. {
  11.     CPU_STK *STK_Temp;
  12.     OS_TCB *TCB_Temp;
  13. /***********用户任务控制块,共6个任务的TCB*********************/   
  14.     TCB_Temp = (OS_TCB *)0x10000000;
  15.     AppTaskStartTCB = TCB_Temp;
  16.     TCB_Temp ++;
  17.     AppTaskUpdateTCB = TCB_Temp;
  18.     TCB_Temp ++;
  19.     AppTaskCOMTCB = TCB_Temp;
  20.     TCB_Temp ++;
  21.      
  22.     AppTaskUserIFTCB = TCB_Temp;
  23.     TCB_Temp ++;
  24.     AppTaskGUITCB = TCB_Temp;
  25.     TCB_Temp ++;
  26.     AppTaskGUIRefreshTCB = TCB_Temp;
  27.     TCB_Temp ++;
  28. /***********系统任务控制块**os.h 1133行修改变量*******************/
  29. //#if (OS_CFG_TMR_EN > 0u)   
  30. //    OSTmrTaskTCB = TCB_Temp;/***os_tmr***/
  31. //    TCB_Temp ++;
  32. //#endif
  33. //      
  34. //    OSTickTaskTCB = TCB_Temp;/***os_stick***/
  35. //    TCB_Temp ++;
  36. //
  37. //#if OS_CFG_STAT_TASK_EN > 0u
  38. //    OSStatTaskTCB = TCB_Temp;/***os_stat***/
  39. //    TCB_Temp ++;
  40. //#endif
  41. //
  42. //#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
  43. //    OSIntQTaskTCB = TCB_Temp;/***os_int***/
  44. //    TCB_Temp ++;
  45. //#endif
  46. //
  47. //    OSIdleTaskTCB = TCB_Temp;/***os_core 817行*/
  48. //    TCB_Temp ++;
  49. /***********用户任务堆栈空间*************************************/
  50.     STK_Temp = (CPU_STK *)TCB_Temp;
  51.     AppTaskStartStk = STK_Temp;
  52.     STK_Temp = STK_Temp + APP_CFG_TASK_START_STK_SIZE;     
  53.     AppTaskUpdateStk = STK_Temp;
  54.     STK_Temp = STK_Temp + APP_CFG_TASK_UPDATE_STK_SIZE;     
  55.     AppTaskCOMStk = STK_Temp;
  56.     STK_Temp = STK_Temp + APP_CFG_TASK_COM_STK_SIZE;     
  57.     AppTaskUserIFStk = STK_Temp;
  58.     STK_Temp = STK_Temp + APP_CFG_TASK_USER_IF_STK_SIZE;     
  59.     AppTaskGUIStk = STK_Temp;
  60.     STK_Temp = STK_Temp + APP_CFG_TASK_GUI_STK_SIZE;
  61.     AppTaskGUIRefreshStk = STK_Temp;
  62. /**********下面的6个是UCOS-III的内核服务程序*****************/
  63.     STK_Temp = STK_Temp + APP_CFG_TASK_GUIRefresh_STK_SIZE;
  64.     OSCfg_IdleTaskStk = STK_Temp;
  65.     OSCfg_IdleTaskStkBasePtr = OSCfg_IdleTaskStk;
  66.     STK_Temp = STK_Temp + OS_CFG_IDLE_TASK_STK_SIZE;
  67. /***************中断队列任务*********************************/
  68. #if (OS_CFG_ISR_POST_DEFERRED_EN > 0u)
  69.    
  70.     OSCfg_IntQTaskStk = STK_Temp;
  71.     OSCfg_IntQTaskStkBasePtr = OSCfg_IntQTaskStk;
  72.     STK_Temp = STK_Temp + OS_CFG_INT_Q_TASK_STK_SIZE;
  73. #else
  74.     OSCfg_IntQTaskStkBasePtr = (CPU_STK *)0;
  75. #endif
  76. /****************ISR堆栈*************************************/
  77. #if (OS_CFG_ISR_STK_SIZE > 0u)
  78.     OSCfg_ISRStk = STK_Temp;
  79.     OSCfg_ISRStkBasePtr = OSCfg_ISRStk;
  80.     STK_Temp = STK_Temp + OS_CFG_ISR_STK_SIZE;
  81. #else
  82.     OSCfg_ISRStkBasePtr = (CPU_STK *)0;
  83. #endif
  84. /**************统计任务*************************************/
  85. #if (OS_CFG_STAT_TASK_EN > 0u)
  86.     OSCfg_StatTaskStk = STK_Temp;
  87.     OSCfg_StatTaskStkBasePtr = OSCfg_StatTaskStk;
  88.     STK_Temp = STK_Temp + OS_CFG_STAT_TASK_STK_SIZE;
  89. #else
  90.     OSCfg_StatTaskStkBasePtr = (CPU_STK *)0;
  91. #endif
  92. /****************滴答任务**********************************/   
  93.     OSCfg_TickTaskStk = STK_Temp;
  94.     OSCfg_TickTaskStkBasePtr = OSCfg_TickTaskStk;
  95.     STK_Temp = STK_Temp + OS_CFG_TICK_TASK_STK_SIZE;
  96. /*****************定时器任务*******************************/
  97. #if (OS_CFG_TMR_EN > 0u)
  98.     OSCfg_TmrTaskStk = STK_Temp;
  99.     OSCfg_TmrTaskStkBasePtr = OSCfg_TmrTaskStk;
  100.     STK_Temp = STK_Temp + OS_CFG_TMR_TASK_STK_SIZE;
  101. #else
  102.     OSCfg_TmrTaskStkBasePtr = (CPU_STK *)0;
  103. #endif
  104. }
复制代码
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107527
QQ
发表于 2017-10-11 10:11:45 | 显示全部楼层

回 云琴箫龙 的帖子

云琴箫龙:修改UCOSIII源码?用__attribute__指定?可怎么有效的分配内存呢?
比如按照顺序都排列好任务堆栈内存空间了,后期中间有一个堆栈想扩大内存,那它后面的变量地址岂不都要往后面移动?
任务栈也用CCM的话,在任务里面定义的变量就不能用DMA访问了吧.
 (2017-10-11 09:22) 
任务栈和TCB使用CCM才是CCM最大的价值所在,因为任务栈和TCB才是需要频繁操作的对象。
任务栈的消耗最大的存在形式就是局部变量,我们的程序中基本不会用局部变量做DMA数据传输的。所以这点大可放心。
这点一定要理解到。
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 10:21:51 | 显示全部楼层
谢谢硬汉哥,我试着改一下.
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 11:23:24 | 显示全部楼层
1.屏蔽之前的定义
//static  OS_TCB   AppTaskStartTCB;
//static  CPU_STK  AppTaskStartStk[APP_TASK_START_STK_SIZE];
2.新增以下代码
OS_TCB   *AppTaskStartTCB;
CPU_STK  *AppTaskStartStk;

void Stack_Init(void)
{
    CPU_STK *STK_Temp;
    OS_TCB *TCB_Temp;
   
/***********用户任务控制块TCB*********************/   
    TCB_Temp = (OS_TCB *)0x10000000;
    AppTaskStartTCB = TCB_Temp;
    TCB_Temp ++;     
   
    STK_Temp = (CPU_STK *)TCB_Temp;
    AppTaskStartStk = STK_Temp;   
    STK_Temp = STK_Temp + APP_TASK_START_STK_SIZE;     
}
3.Stack_Init();添加到main第一行
其它的暂时都不动,没问题吧,为何一启动 OSStart(&err);就到HardFault_Handler中断呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107527
QQ
发表于 2017-10-11 11:33:52 | 显示全部楼层

回 云琴箫龙 的帖子

云琴箫龙:1.屏蔽之前的定义
//static  OS_TCB   AppTaskStartTCB;
//static  CPU_STK  AppTaskStartStk[APP_TASK_START_STK_SIZE];
2.新增以下代码
OS_TCB   *AppTaskStartTCB;
....... (2017-10-11 11:23) 
没问题,多试试。
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 11:55:00 | 显示全部楼层
定位到问题原因了,刚才新增的代码都额外放到了一个c文件里,放到main文件里就没问题了,看来是头文件包含出了问题.
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 12:07:45 | 显示全部楼层
新建了一个干净的C文件,还是会进错误中断,怪异吧!


#include "CcmCfg.h"
#include  "os.h"
#include  "app_cfg.h"

OS_TCB   *AppTaskStartTCB;
CPU_STK  *AppTaskStartStk;


void Stack_Init(void)
{
    CPU_STK *STK_Temp;
    OS_TCB *TCB_Temp;
   
/***********用户任务控制块TCB*********************/   
    TCB_Temp = (OS_TCB *)0x10000000;
    AppTaskStartTCB = TCB_Temp;
    TCB_Temp ++;     
   
    STK_Temp = (CPU_STK *)TCB_Temp;
    AppTaskStartStk = STK_Temp;   
    STK_Temp = STK_Temp + APP_TASK_START_STK_SIZE;     
}

#ifndef _CCMCFG_H_
#define _CCMCFG_H_

#include  "os.h"




extern OS_TCB   *AppTaskStartTCB;
extern CPU_STK  *AppTaskStartStk;

void Stack_Init(void);

#endif

int  main (void)
{
    OS_ERR  err;
   
    Stack_Init();
.......
回复

使用道具 举报

98

主题

340

回帖

634

积分

金牌会员

积分
634
 楼主| 发表于 2017-10-11 14:19:40 | 显示全部楼层
新增任务发现TCB和堆栈地址总被莫名的修改为0,今天出师不利,回头有时间再找原因吧!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-4 19:52 , Processed in 0.288539 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表