zoukankan      html  css  js  c++  java
  • 记录一次因为stack_size太小引起的问题。

    出问题的函数如下:

     1 char *calc_file_md5(const char* fw_name)
     2 {
     3     FRESULT result;
     4     FIL File;
     5     uint32_t BytesRead = 0,offset = 0,file_size = 0;
     6     MD5_CTX context;   //MD5
     7     unsigned char digest[16];
     8     uint8_t i = 0;
     9     
    10     result = f_open(&File,fw_name,FA_OPEN_EXISTING|FA_READ);        //打开文件
    11     if(FR_OK  != result)
    12     {
    13         DEBUG_LOG(DEBUG_FW,("Not Find %s
    ",fw_name));
    14         return 0;
    15     }
    16    file_size = File.obj.objsize;//结束地址为起始地址加上文件大小。
    17    MD5Init(&context);
    18    while(1)
    19    {
    20        f_lseek(&File,offset);
    21        result = f_read(&File,file_buffer,2048,&BytesRead);
    22        if(result || BytesRead==0)
    23        {
    24             DEBUG_LOG(DEBUG_FW,("read %s error!
    ",fw_name));
    25             return 0;
    26        }
    27        MD5Update(&context, file_buffer, BytesRead);
    28        
    29        offset+=BytesRead;
    30        if(offset==file_size)
    31              break;
    32    }
    33     
    34     MD5Final(digest, &context);
    35     f_close(&File);
    36     for (i = 0; i < 16; i++)
    37         rt_sprintf(cal_md5_str+(i*2),"%02X",digest[i]);
    38     
    39     DEBUG_LOG(DEBUG_FW,("cal_md5:%s
    ",cal_md5_str));
    40     
    41     return cal_md5_str;
    42 }
    View Code

    就计算个MD5值的代码,计算不对。不知道问题出在哪里,MD5算法是之前移植好,实验无误的。就吧这个函数有关的,全部弄到我的另一个工程,实验计算正确!这就纳闷了呀。工程本身的问题?玄学?

    于是,(我在这个函数,又添加了些代码,试图读回读出的文件。结果MD5计算值变了,但不对。——以上为胡乱尝试,无头苍蝇,瞎试)。我把第4行 弄到外边 让File作为全局变量,竟然正确了。

    再次弄进来让它作为局部变量,还是错误。立刻认识到可能是Stack_size设置小了,导致File里的数据在入栈出栈的时候发生错误了。于是我把Statck_size由0x400改为0x800,于是就好了。

    还有一次,同事调用了文件系统的API,导致莫名进入硬件错误中断,查找一番,找不到哪里硬件操作不当,于是想到了可能stack不够用,于是把stack_size调大后,就正常了。

    这里引出几个问题:

    1 描述stm32的Stack_Mem,Heap_Mem的作用。

    栈(stack)空间,用于局部变量,函数调时现场保护和返回地址,函数的形参等。
    堆(heap)空间,主要用于动态内存分配,也就是说用 malloc,calloc, realloc 等函数分配的变量空间

    2 怎么在早期意识到Stack_size可能不够用,即怎么估计我最大要用到的Stacks_size的大小?
    首先,使用GUI和文件系统的时候,是要调大stack_size的。这些是定性的经验之谈,那么怎么定量呢?

    工程全编译,且无误后,到obj文件夹找到与工程同名的.htm文件。
    开头就有最大栈深度的大小

     继续往下翻,还可以看到具体的每个函数用到的栈的大小。

    3 用rtos加持的stm32的Stack_Mem,Heap_Size的作用。
    RTOS有自己的任务栈,不再使用这里,仅RTOS启动前和中断以及中断嵌套才使用这里,这里的栈被称为系统栈,而uCOS又略有不同,uCOS把系统栈也接管了。
    Heap_Size作为裸机时,malloc,calloc, realloc 等函数用于分配动态内存。如果RTOS有自己的一套动态内存机制,这不受这个Heap_Size限制,而由那套机制限定。

    懒惰不会让你一下子跌到 但会在不知不觉中减少你的收获; 勤奋也不会让你一夜成功 但会在不知不觉中积累你的成果 越努力,越幸运。
  • 相关阅读:
    css3skew
    github如何使用
    互联网历史
    html知识点
    人类的终极目标是什么?
    如何提高自我学习能力?
    为什么富人越富,穷人越穷?
    关于游戏小说与学习知识的不同
    关于写代码的一点体会
    监听多行文本框字数输入
  • 原文地址:https://www.cnblogs.com/Rainingday/p/14506835.html
Copyright © 2011-2022 走看看