標(biāo)題: 51單片機(jī)嵌入U(xiǎn)COS系統(tǒng) 程序 [打印本頁(yè)]

作者: 51黑tt    時(shí)間: 2016-3-6 13:47
標(biāo)題: 51單片機(jī)嵌入U(xiǎn)COS系統(tǒng) 程序
本帖最后由 51黑tt 于 2016-3-6 13:49 編輯

8位單片機(jī)代表類型是51單片機(jī),
最近正對(duì)51單片機(jī)嵌入U(xiǎn)COS系統(tǒng)很感興趣,
很少人會(huì)對(duì)51嵌入U(xiǎn)COS感冒,原因是51的RAm太少,最近看到一篇《制造自己的操作系統(tǒng),》學(xué)習(xí)了一下午,感覺(jué)不是很強(qiáng)大,我是個(gè)菜鳥,可能還不知道其中的精髓吧,下貼出,留念。
  1. #include <reg51.h>


  2. /*============================以下為任務(wù)管理器代碼============================*/

  3. #define MAX_TASKS 3//任務(wù)槽個(gè)數(shù).在本例中并未考慮任務(wù)換入換出,所以實(shí)際運(yùn)行的任務(wù)有多少個(gè),就定義多少個(gè)任務(wù)槽,不可多定義或少定義

  4. //任務(wù)的棧指針
  5. unsigned char idata task_sp[MAX_TASKS];
  6.          
  7. #define MAX_TASK_DEP 12 //最大棧深.最低不得少于2個(gè),保守值為12.
  8.       //預(yù)估方法:以2為基數(shù),每增加一層函數(shù)調(diào)用,加2字節(jié).如果其間可能發(fā)生中斷,則還要再加上中斷需要的棧深.
  9.       //減小棧深的方法:1.盡量少嵌套子程序 2.調(diào)子程序前關(guān)中斷.
  10. unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP];//任務(wù)堆棧.

  11. unsigned char task_id;//當(dāng)前活動(dòng)任務(wù)號(hào)


  12. //任務(wù)切換函數(shù)(任務(wù)調(diào)度器)
  13. void task_switch(){
  14. task_sp[task_id] = SP;

  15. if(++task_id == MAX_TASKS)
  16.   task_id = 0;

  17. SP = task_sp[task_id];
  18. }

  19. //任務(wù)裝入函數(shù).將指定的函數(shù)(參數(shù)1)裝入指定(參數(shù)2)的任務(wù)槽中.如果該槽中原來(lái)就有任務(wù),則原任務(wù)丟失,但系統(tǒng)本身不會(huì)發(fā)生錯(cuò)誤.
  20. void task_load(unsigned int fn, unsigned char tid){
  21. task_sp[tid] = task_stack[tid] + 1;
  22. task_stack[tid][0] = (unsigned int)fn & 0xff;
  23. task_stack[tid][1] = (unsigned int)fn >> 8;
  24. }

  25. //從指定的任務(wù)開始運(yùn)行任務(wù)調(diào)度.調(diào)用該宏后,將永不返回.
  26. #define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}




  27. /*============================以下為測(cè)試代碼============================*/


  28. unsigned char stra[3], strb[3];//用于內(nèi)存塊復(fù)制測(cè)試的數(shù)組.




  29. //測(cè)試任務(wù):復(fù)制內(nèi)存塊.每復(fù)制一個(gè)字節(jié)釋放CPU一次
  30. void task1(){
  31. //每復(fù)制一個(gè)字節(jié)釋放CPU一次,控制循環(huán)的變量必須考慮覆蓋
  32. static unsigned char i;//如果將這個(gè)變量前的static去掉,會(huì)發(fā)生什么事?
  33. i = 0;

  34. while(1){//任務(wù)必須為死循環(huán),不得退出函數(shù),否則系統(tǒng)會(huì)崩潰
  35.   stra[i] = strb[i];
  36.   if(++i == sizeof(stra))
  37.    i = 0;

  38.   //變量i在這里跨越了task_switch(),因此它必須定義為靜態(tài)(static),否則它將會(huì)被其它進(jìn)程修改,因?yàn)樵诹硪粋(gè)進(jìn)程里也會(huì)用到該變量所占用的地址.
  39.   task_switch();//釋放CPU一會(huì)兒,讓其它進(jìn)程有機(jī)會(huì)運(yùn)行.如果去掉該行,則別的進(jìn)程永遠(yuǎn)不會(huì)被調(diào)用到
  40. }
  41. }

  42. //測(cè)試任務(wù):復(fù)制內(nèi)存塊.每復(fù)制一個(gè)字節(jié)釋放CPU一次.
  43. void task2(){
  44. //每復(fù)制一個(gè)字節(jié)釋放CPU一次,控制循環(huán)的變量必須考慮覆蓋
  45. static unsigned char i;//如果將這個(gè)變量前的static去掉,將會(huì)發(fā)生覆蓋問(wèn)題.task1()和task2()會(huì)被編譯器分配到同一個(gè)內(nèi)存地址上,當(dāng)兩個(gè)任務(wù)同時(shí)運(yùn)行時(shí),i的值就會(huì)被兩個(gè)任務(wù)改來(lái)改去
  46. i = 0;

  47. while(1){//任務(wù)必須為死循環(huán),不得退出函數(shù),否則系統(tǒng)會(huì)崩潰
  48.   stra[i] = strb[i];
  49.   if(++i == sizeof(stra))
  50.    i = 0;

  51.   //變量i在這里跨越了task_switch(),因此它必須定義為靜態(tài)(static),否則它將會(huì)被其它進(jìn)程修改,因?yàn)樵诹硪粋(gè)進(jìn)程里也會(huì)用到該變量所占用的地址.
  52.   task_switch();//釋放CPU一會(huì)兒,讓其它進(jìn)程有機(jī)會(huì)運(yùn)行.如果去掉該行,則別的進(jìn)程永遠(yuǎn)不會(huì)被調(diào)用到
  53. }
  54. }

  55. //測(cè)試任務(wù):復(fù)制內(nèi)存塊.復(fù)制完所有字節(jié)后釋放CPU一次.
  56. void task3(){
  57. //復(fù)制全部字節(jié)后才釋放CPU,控制循環(huán)的變量不須考慮覆蓋
  58. unsigned char i;//這個(gè)變量前不需要加static,因?yàn)樵谒淖饔糜騼?nèi)并沒(méi)有釋放過(guò)CPU

  59. while(1){//任務(wù)必須為死循環(huán),不得退出函數(shù),否則系統(tǒng)會(huì)崩潰
  60.   i = sizeof(stra);
  61.   do{
  62.    stra[i-1] = strb[i-1];
  63.   }while(--i);

  64.   //變量i在這里已完成它的使命,所以無(wú)需定義為靜態(tài).你甚至可以定義為寄存器型(regiter)
  65.   task_switch();//釋放CPU一會(huì)兒,讓其它進(jìn)程有機(jī)會(huì)運(yùn)行.如果去掉該行,則別的進(jìn)程永遠(yuǎn)不會(huì)被調(diào)用到
  66. }
  67. }

  68. void main(){
  69. //在這個(gè)示例里并沒(méi)有考慮任務(wù)的換入換出,所以任務(wù)槽必須全部用完,否則系統(tǒng)會(huì)崩潰.
  70. //這里裝載了三個(gè)任務(wù),因此在定義MAX_TASKS時(shí)也必須定義為3
  71. task_load(task1, 0);//將task1函數(shù)裝入0號(hào)槽
  72. task_load(task2, 1);//將task2函數(shù)裝入1號(hào)槽
  73. task_load(task3, 2);//將task3函數(shù)裝入2號(hào)槽

  74. os_start(0);//啟動(dòng)任務(wù)調(diào)度,并從0號(hào)槽開始運(yùn)行.參數(shù)改為1,則首先運(yùn)行1號(hào)槽.
  75.     //調(diào)用該宏后,程序流將永不再返回main(),也就是說(shuō),該語(yǔ)句行之后的所有語(yǔ)句都不被執(zhí)行到.
  76. }
復(fù)制代碼

看了看其形式就是
void  main (void)
{
while(1)
          {
            task_1();
                task_2();
                    task_3();  
          }  
}
我唯一的目的是想看一下51到底有跑多大,
另外,16位單片機(jī)代表MSP430是典型代表,
我馬上會(huì)學(xué)到,真的希望有電子或是計(jì)算機(jī)專業(yè)的同學(xué)給我教教,楊秀旭,他好像在電子科技大學(xué),我聯(lián)系不上她,但是找他去





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1