stm32是怎么获取堆和栈大小的+ucos iii
小弟现在用CodeSourcery+jlink+openocd开发stm32
平台:stm32f103zet6
flash:内置512K(大容量)
sram:内置64K+外部512K
启动文件:startup_stm32f10x_hd.c
链接脚本:stm32f10x_flash_extsram.ld
1、没用ucos iii之前是可以正常运行的,
2、用了ucos iii之后不能正常运行,
ucosiii是能在KEIL UV4上成功运行的,初步怀疑是堆和栈的分配有问题(因为ucosiii中要用malloc动态分配内存),所以我想知道stm32是如何获取堆和栈的信息的,我怎么才能让它知道堆和栈的大小以及地址空间。
补充:栈的最高地址可以通过启动文件的下面部分知道,即stm32启动之后先要从flash的起始处取出栈的最高地址和复位向量,那堆是怎么知道的呢,我不知道IDE在这方面是怎么处理的,我想充分利用内置64K+外部512K的SRAM,不知道怎么做,谢谢
void (* const g_pfnVectors[])(void) =
{
(void *)Initial_spTop, /* The initial stack pointer */
Reset_Handler, /* Reset Handler */
NMI_Handler, /* NMI Handler */
HardFault_Handler, /* Hard Fault Handler */
}
ucos3 不倚赖于malloc,任务栈以及内核对像可以在静态或动态分配。ucos3管理了中断栈(msp),栈大小由一个配置宏来设置。
系统启动之前创建一个起启任务,如果能运行到起始任务则IDE栈配置没有问题,若运行到启动任务之后死机,则需检查任务栈、中断栈是否溢出,
总之,问题应当很简单,也很容易找。
关键是我没用IDE开发,创建起始任务后一运行到OSStart(&err);就会死
这跟IDE没关系的.上面都说了,在OS跑起来之前随便干点什么,如果能做得到那就是OS的问题而不是配置问题.
void Reset_Handler(void)
{
/* FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
required, then adjust the Register Addresses */
// SystemInit_ExtMemCtl();
SystemInit();
/* restore original stack pointer */
// asm(" LDR r0, =_estack");
// asm(" MSR msp, r0");
/* Initialize data and bss */
__Init_Data();
/* Call the application's entry point.*/
main();
}
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
//SystemInit_ExtMemCtl();
fsmc_Init(); //初始化外部SRAM (1)
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
int main(void)
{
OS_ERR err;
//err = 0;
CPU_IntDis();
SYS_InitSystem();
OSInit(&err);
OSQCreate((OS_Q *)&OS_Q_Save,
(CPU_CHAR *)"OS Q Save",
(OS_MSG_QTY)20,
(OS_ERR *)&err);
OSTaskCreate((OS_TCB *)&Task_StartTCB,
(CPU_CHAR *)"Task1 Start",
(OS_TASK_PTR)Task_Start,
(void *)0,
(OS_PRIO)TASK_PRIO_START,
(CPU_STK *)&Task_StartStk[0],
(CPU_STK_SIZE)TASK_START_STACK_SIZE / 10,
(CPU_STK_SIZE)TASK_START_STACK_SIZE,
(OS_MSG_QTY)0,
(OS_TICK)TASK_START_TICK,
(void *)0,
(OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)&err);
OSStart(&err); //如果有这一句的话运行到上面 SystemInit 中的(1)处就死了,如果在这句前面加个死循环while(1);就能运行到 while(1)处。这是什么情况
return (0);
}
调试stm32时运行一条语句后进入硬中断HardFault_Handler
typedef struct _PARA_SET
{
#if STRING_STORE_USE_ARRAY
char name[NAME_STRING_MAX];
char alias[ALIAS_STRING_MAX];
char unit[UNIT_STRING_MAX];
char strValue[LINE_STRING_MAX];
#else
char *name;
char *alias;
char *unit;
char *strValue;
#endif
tParaType type;
FLOAT32 value;
FLOAT32 MaxValue;
FLOAT32 MinValue;
FLOAT32 DefValue;
}tParaSet;
tParaSet DevCommSets[3];
static void DEV_ReadCommSets(void)
{
UINT32 i, value;
tParaSet *pSets = DevCommSets;
DF_ReadMainMemoryPage(SAVE_DEV_COMM_SETS_PAGE,
DEV_ReadData, COMM_MAX_SETS * 4 + 4);
for (i = 0; i < COMM_MAX_SETS; i++)
{
value = BytesToDword(&DEV_ReadData[i * 4]);
pSets->value = value;
if ((pSets->value > pSets->MaxValue) || (pSets->value < pSets->MinValue))
{
pSets->value = pSets->DefValue;
}
pSets++;
}
DEV_CommSetsCrc = BytesToDword(&DEV_ReadData[i * 4]);
}
调试过程如下:
(gdb) n
Reset_Handler () at startup_stm32f10x_hd.c:262
262 SystemInit();
(gdb) n
268 __Init_Data();
(gdb) n
271 main();
(gdb) n
Breakpoint 1, DEV_ReadCommSets () at device.c:980
980 for (i = 0; i < COMM_MAX_SETS; i++)
(gdb) n
982 value = BytesToDword(&DEV_ReadData[i * 4]);
(gdb) n
984 pSets->value = value; //运行这条语句后进入硬中断void HardFault_Handler(void){ while(1){} }中,不知道为什么?
(gdb) n
HardFault_Handler () at stm32f10x_it.c:61
61 {
(gdb) n
64 {}
看看 虽然我不懂
....
刚学stm32,被你的问题吓着了,
说说个人的看法
既然是运行 pSets->value = value;导致的硬件异常,问题就一定在这上面有迹可循
这一句可以看出pSets这个指针异常才会硬件异常,在执行之前,可不可以把指针的内存地址打印出来看看
如果pSets异常,那么看看定义
tParaSet DevCommSets[3];
static void DEV_ReadCommSets(void)
{
UINT32 i, value;
tParaSet *pSets = DevCommSets;
......
咋一看,直接指向一个全局数组DevCommSets
既然是全局数组,那就要看编译器与装载的配置了
一般来说,使用C语言,变量和函数的地址有编译器自行分配,但编译前需要指定必要的内存范围
检查你的stm32f10x_flash_extsram.ld