久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

UCOS操作系統堆棧淺談

作者:佚名   來源:本站原創   點擊數:  更新時間:2014年03月12日   【字體:

1 聲明堆棧大小

在uc/os-ii操作系統的任務切換和中斷處理過程中,需要保存處理器的內部寄存器和變量的值,這就
要求每個任務都有自己的堆?臻g。堆棧必須聲明為OS_STK類型,并且由連續的內存空間組成,可以靜態
分配空間(在編譯時分配),也可以動態分配堆棧空間(在運行時分配)。由于采用動態分配方式,會導致
內存中含有大量內存碎片,因此不推薦使用動態分配方式。其兩種聲明方式如下:
靜態分配方式:
static OS_STK TaskStk[StkSize];
或者
OS_STK TaskStk[StkSize];
動態分配方式:
OS_STK *pstk;
pstk = (OS_STK*)malloc(StkSize);
if(pstk != (OS_STK*)0) //判斷堆棧分配是否成功
{
printf("Create TaskStk Success");
}
2 設置堆棧生產方向
uc/os-ii操作系統支持2中堆棧生長方向。即可從高地址往低地址生長,也可以由低地址往高地址生長。
在調用OSTaskCreate()或者OSTaskCreateExt()創建任務的時候由于必須知道堆棧的生長方向,所以要在OS_CPU.H
文件中設置任務堆棧的生長方向。
#define OS_STK_GROWTH 1 //設置堆棧是從上往下長的
OSTaskCreate(Task,pdata,&TaskStk[StkSize - 1],prio);
或者
#define OS_STK_GROWTH 0 //設置堆棧是從下往上長的
OSTaskCreate(Task,pdata,&TaskStk[0],prio);

當然也可以這樣編寫創建任務的以支持堆棧的從上往下和從下往上生長
#if OS_STK_GROWTH == 1
OSTaskCreate(Task,pdata,&TaskStk[StkSize - 1],prio);
#else
OSTaskCreate(Task,pdata,&TaskStk[0],prio);
#endif

3 堆棧檢驗
為控制產品成本,有時需要確定任務實際需要的堆?臻g的大小,避免為任務分配過多的對戰空間,從而
減少應用程序代碼所需的RAM數量。uc/os-ii系統提供OSTaskStkChk()函數用以確定任務實際需要的堆?臻g。
使用堆棧檢驗功能必須做一下幾點:
1.在OS_CFG.H文件中設置OS_TASK_CREATE_EXT為 1
2.使用OSTaskCreateExt()創建任務,并且賦予任務比實際需要多一點的空間?梢栽谌魏稳蝿罩姓{用STaskStkChk()函數,對任何用OSTaskCreateExt()建立的任務進行堆棧檢驗。
3.在OSTaskCreateExt()中,將參數opt設置為:OS_TASK_OPT_STK_CHK + OS_TASK_OPT_STK_CLR
4.把需要進行檢測的任務的優先級作為OSTaskStkChk()的參數并調用
應使自己的應用程序運行足夠長的時間,并且經歷最壞的堆棧使用情況,這樣才能得到正確的樹木。一旦得到所需要的對單需求,就可以重新設置堆棧的最終大小了。在堆棧檢驗中,所得到的只是一個大智的堆棧使用情況,并不能說明堆棧的使用全部實際情況。
4 堆棧溢出
在實際的項目中,由于產品的升級需要可能一個任務會經常修改,所需要的實際堆棧大小并不能很好的確定,即便使用堆棧檢驗功能后,在后續產品的升級過程中變量的增加會導致堆棧不夠用。而在調試的過程中,如果沒有堆棧溢出的報警機制,一旦堆棧出現溢出,這個問題是很難一時被發現的。在這里,我建議在系統開始運行前,把每個任務的堆棧棧頂初始化一個值,每次出現任務切換的時候就讀取對應棧頂的值,如果和初始化棧頂值相同的話就說明沒有問題,如果值出現改變的話那么出現堆棧溢出的概率至少達到90%以上,這樣可以避免出現堆棧溢出而不能發現的尷尬。下面是個項目的一部分,刪了一些,可供參考。

#include "user/lc_sqce_aj.h"
#include "include_all.h"

 

/* size of each task's stacks (# of WORDs) */
#define TASK_START_STK_SIZE 128
#define BUZZER_STK_SIZE 128
#define CTRLMSG_STK_SIZE 128
#define STORDEV_MOUNT_STK_SIZE 512
#define MODE_SWITCH_STK_SIZE 512
#define MODE_EXE_STK_SIZE 2000
#define TWO_CHANNEL_REC_SIZE 512
#define ALARM_STK_SIZE 128
#define TASK_STK_SIZE 512

 

/* application tasks */
#define TASK_START_ID 0
#define TASK_1_ID 1
#define TASK_2_ID 2
#define TASK_3_ID 3
#define TASK_4_ID 4
#define TASK_5_ID 5
#define TASK_6_ID 6
#define TASK_7_ID 7
#define TASK_8_ID 8
#define TASK_9_ID 9
#define TASK_10_ID 10
#define TASK_11_ID 11
#define TASK_12_ID 12
#define TASK_13_ID 13
#define TASK_14_ID 14
#define TASK_15_ID 15

 

/* application tasks priorities */
#define TASK_START_PRIO 0
#define TASK_1_PRIO 1
#define TASK_2_PRIO 2
#define TASK_3_PRIO 3
#define TASK_4_PRIO 4
#define TASK_5_PRIO 5
#define TASK_6_PRIO 6
#define TASK_7_PRIO 7
#define TASK_8_PRIO 8
#define TASK_9_PRIO 9
#define TASK_10_PRIO 10
#define TASK_11_PRIO 11
#define TASK_12_PRIO 12
#define TASK_13_PRIO 13
#define TASK_14_PRIO 14
#define TASK_15_PRIO 15

 

/*see task stacks*/
OS_STK TaskStartStk[TASK_START_STK_SIZE];
OS_STK BuzzerStk[BUZZER_STK_SIZE];
OS_STK CtrlmsgStk[CTRLMSG_STK_SIZE];
OS_STK StorDevStk[STORDEV_MOUNT_STK_SIZE];
OS_STK ModeSwitchStk[MODE_SWITCH_STK_SIZE];
OS_STK ModeExeStk[MODE_EXE_STK_SIZE];


static void TaskStart(void *p_arg); //函數聲明
static void TaskStartCreateTasks(void);
void InitStackMark(void);

//************************************************************************************
//* 函數名 :main
//* 返回值 :N/A
//* 參數 :N/A
//* 函數說明:主函數
//* 作 者:啊呆
//***********************************************************************************

void main(void)
{
  INT8U err;

  // initialize uC/OS-II
  OSInit();
  // install uC/OS-II's context switch vector
  IRQSetVect(uCOS, OSCtxSw);

  OSTaskCreateExt(TaskStart,
  (void *)0,
  &TaskStartStk[TASK_START_STK_SIZE - 1],
  TASK_START_PRIO,
  TASK_START_ID,
  &TaskStartStk[0],
  TASK_START_STK_SIZE,
  (void *)0,
  OS_TASK_OPT_STK_CLR + OS_TASK_OPT_STK_CHK);

  OSTaskNameSet(TASK_START_PRIO, "Start Task", &err);
  // start multitasking
  OSStart();

}

//*********************************************************************************
//* 函數名 :TaskStart
//* 返回值 :N/A
//* 參數 :void *p_arg
//* 函數說明:創建TaskStart任務
//* 作 者:啊呆
//********************************************************************************
static void TaskStart(void *p_arg)
{
  #if OS_CRITICAL_METHOD == 3
   OS_CPU_SR cpu_sr;
  #endif
  // prevent compiler warning
  p_arg = p_arg;

  // install uC/OS-II's clock tick ISR
  OS_ENTER_CRITICAL();
  IRQSetVect(TMR1_VEC, OSTickISR);
  OSSetTickRate(lc_clk_get_freq(CLK_SYS_SEL), OS_TICKS_PER_SEC);
  OS_EXIT_CRITICAL();
  // initialize uC/OS-II's statistics
  OSStatInit();

  TaskStartCreateTasks();

  for (;;)
  {
  // clear the context switch counter
  OSCtxSwCtr = 0;
  // wait one second
  OSTimeDly(OS_TICKS_PER_SEC);
  }
}

//*******************************************************************************
//* 函數名 :TaskStartCreateTasks
//* 返回值 :N/A
//* 參數 :N/A
//* 函數說明:創建任務
//* 作 者:啊呆
//******************************************************************************
static void TaskStartCreateTasks(void)
{
//初始化,創建每個任務對應需要的信號量
  init_buzzer_proc();
  init_ModeEXE_proc();
  init_ctrlmsg_get_proc();
  init_twoChRec_proc();
  InitStackMark();

  //創建任務
  OSTaskCreate(buzzer_proc, (void *)0, &BuzzerStk[BUZZER_STK_SIZE-1], TASK_3_PRIO);
  OSTaskCreate(ctrlmsg_get_proc, (void *)0, &CtrlmsgStk[CTRLMSG_STK_SIZE-1], TASK_5_PRIO);
  OSTaskCreate(stordev_mount_proc, (void *)0, &StorDevStk[STORDEV_MOUNT_STK_SIZE-1], TASK_6_PRIO);
  OSTaskCreate(mode_switch_proc, (void *)0, &ModeSwitchStk[MODE_SWITCH_STK_SIZE-1], TASK_7_PRIO);
  OSTaskCreate(ModeEXE_proc, (void *)0, &ModeExeStk[MODE_EXE_STK_SIZE-1], TASK_11_PRIO);
}

//**************************************************************************
//* 函數名 :InitStackMark
//* 返回值 :N/A
//* 參數 :N/A
//* 函數說明:初始化堆棧棧頂
//* 作 者:啊呆
//**************************************************************************
void InitStackMark(void)
{
//初始化每個堆棧棧頂
  BuzzerStk[0]=0x5153;
  BuzzerStk[1]=0xAA55;
  CtrlmsgStk[0]=0x5153;
  CtrlmsgStk[1]=0xAA55;
  StorDevStk[0]=0x5153;
  StorDevStk[1]=0xAA55;
  ModeSwitchStk[0]=0x5153;
  ModeSwitchStk[1]=0xAA55;
  ModeExeStk[0]=0x5153;
  ModeExeStk[1]=0xAA55;
}

//*****************************************************************************
//* 函數名 : CheckStkOverFlow
//* 返回值 :BOOLEAN
//* 參數 :INT8U TaskName
//* 函數說明:初檢測堆棧溢出
//* 作 者:啊呆
//******************************************************************************
BOOLEAN CheckStkOverFlow(INT8U TaskName)
{
//判斷是否堆棧溢出
  if(TaskName==buzzer)
  {
      if(BuzzerStk[0]==0x5153 && BuzzerStk[1]==0xAA55)
         return FALSE;
  }
  else if(TaskName==ctrlmsg)
  {
     if(CtrlmsgStk[0]==0x5153 && CtrlmsgStk[1]==0xAA55)
        return FALSE;
  }
  else if(TaskName==stordev_mount)
  {
     if(StorDevStk[0]==0x5153 && StorDevStk[1]==0xAA55)
        return FALSE;
  }
  else if(TaskName==mode_switch)
  {
     if(ModeSwitchStk[0]==0x5153 && ModeSwitchStk[1]==0xAA55)
        return FALSE;
  }
  else if(TaskName==ModeEXE)
  {
     if(ModeExeStk[0]==0x5153 && ModeExeStk[1]==0xAA55)
        return FALSE;
   }
   return TRUE;
}

關閉窗口

相關文章

主站蜘蛛池模板: 国产精品国产 | 亚洲国产成人精品女人久久久野战 | 成人一区在线观看 | 韩国成人在线视频 | 亚洲精品黄色 | 欧美日韩在线综合 | 欧美精品一区二区三区在线 | 国产精品亚洲综合 | 91亚洲国产亚洲国产 | 亚洲免费视频网址 | h肉视频 | 男人的天堂视频网站 | 国产目拍亚洲精品99久久精品 | 欧产日产国产精品v | 亚洲精品成人 | 99精品欧美一区二区三区综合在线 | 91中文视频| 一区二区三区欧美 | 日本成人在线观看网站 | 婷婷综合网 | 久草在线视频中文 | 亚洲区一区二 | 久草视| 男女视频在线免费观看 | 天天爽夜夜操 | 国产a区| 国产一区二区成人 | 欧美午夜视频 | 日本午夜网站 | 天天曰夜夜 | 亚洲视频一区二区三区 | 综合精品久久久 | 日本精品一区二区三区视频 | 黄视频国产| 91精品久久久久 | 91五月婷蜜桃综合 | 丝袜美腿一区 | 在线精品国产 | 99久久婷婷国产综合精品首页 | 欧美日韩精品亚洲 | 欧美日韩一区在线播放 |