blueprince

    1. 求助晶振 8/12633 PCB设计 2007-06-27
      如果是时钟震荡器,电压又是多少?
    2. 求助晶振 8/12633 PCB设计 2007-06-27
      是普通晶体,还是时钟震荡器?
    3. [转帖]UCOSII AVR移植全过程及心得 12/15945 实时操作系统RTOS 2007-06-27
      ************************************************************** _OSCtxSw:: PUSH_ALL PUSH_SREG PUSH_SP lds r30, _OSTCBCur //Save software sp in the current TCB lds r31, _OSTCBCur+1 st Z+, r28 st Z, r29 _OSIntCtxSw:: rcall _OSTaskSwHook// lds r30, _OSTCBHighRdy //OSTCBCur=OSTCBHighRdy lds r31, _OSTCBHighRdy+1 sts _OSTCBCur, r30 sts _OSTCBCur+1, r31 lds r16, _OSPrioHighRdy//OSPrioCur=OSPrioHighRdy sts _OSPrioCur, r16 ld r28, Z+//restore the software sp_Y to be used ld r29, Z POP_SP POP_SREG POP_ALL ret ******************************************************** _OSTickISR:: PUSH_ALL PUSH_SREG PUSH_SP ldi R19, 0xf1;0xb2 out TCNT, R19 lds R16, _OSIntNesting //OSIntNesting++; inc R16 sts _OSIntNesting, R16 cpi R16, 1 brne NO_SAVE_Y lds r30, _OSTCBCur lds r31, _OSTCBCur+1 st Z+, r28 st Z, r29 NO_SAVE_Y: rcall _OSTimeTick rcall _OSIntExit POP_SP POP_SREG POP_ALL reti 编译、下载、运行~!哈哈,孔子笑了………………………… 三、 结束语 ucos的移植相对还是比较简单的,但由于第一次做这样的移植,难免会走一些弯路(尤其是忽略了编译器的一些编译机制),我想一定也有不少朋友遇到和我类似的问题。我把移植全过程及“勘误表”都列出来,希望能对大家有所帮助,少走些弯路。 同时一个良好的系统需要经过严格的测试,我移植后的OS只做了一些简单的测试,所以可能有一些BUG,我也希望大家能对把使用过程中发现的问题提出来一起讨论, 多交流、指教! 音乐乐乐 时钟中断程序中 _OSTickISR:: PUSH_ALL PUSH_SREG PUSH_SP ............ 错误分析: 由于在进中断时avr清了SREG中的I位,所以PUSH_SREG保存的SREG是错误的 改正方法: .macro PUSH_SREG_INT IN R16, 0x3f ORI R16, 0x80 ;恢复SREG中的I位再保存! ST -Y, R16 .endmacro _OSTickISR:: PUSH_ALL PUSH_SREG_INT PUSH_SP ........ 修改部分很简单,之所以把它定义成宏是考虑到以后写其他的中断服务程序会用到。
    4. [转帖]UCOSII AVR移植全过程及心得 12/15945 实时操作系统RTOS 2007-06-27
      编译完后下载程序(我高喊:同学们,激动人心的时刻到啦~~~!),100%完成,哇,有了,显示USE 04(我狂喜)。。。。。 恩?怎么回事,LED偶尔会闪烁,闪烁瞬间显示的04左移了两位!哎呀郁闷ING(这时候电脑说话了——节哀顺便吧.晕!)~~~! 没办法,调试吧!因为数字会突然的瞬间左移,这说明I值和对应的buff不相应,很可能是I的值被改变了, LED_DAT=buff[i]; OSTimeDly(1); 只可能是在调用OSTimeDly()的过程中变的,于是单步执行这个函数,果然!有时候执行后I的值会变,而且超出了6!!?? 还是小米加步枪好啊,关键的时候还是要靠老古董——汇编。跟踪调用OSTimeDly以后的反汇编,噢~~~~~~~~~~!恍然大悟! 重大错误:在函数第一次调用OSTimeDly时,R值由编译器保存到软堆栈,该堆栈是以Y为指针的,由于在移植时用了sp作为任务堆栈指针,而Y始终为软件堆栈即全局堆栈,所以在压进去的R值可能被其他任务修改!!!换句话说,用这种方法(SP为任务指针)保存的任务变量不在自己的任务模块中!! 解决办法:用Y作为任务堆栈指针,SP仅仅作为函数返回地址指针,即硬件指针! 新的contex结构: OSTCB-->Y——> |_________ | SP | SREG | R31 | R30 | R27 …………. |___ R0____ 更改后的移植程序如下(由前面的移植可以看到,由于后来改了一个函数OSTickISR为汇编,宏定义显得很罗嗦,所以干脆我把OSCtxSw,OSIntCtxSw,OSStartHighRdy和OSIntExit函数都用汇编写): TCNT = $32 .macro PUSH_ALL ST -Y,R0 ST -Y,R1 ST -Y,R2 ST -Y,R3 ST -Y,R4 ST -Y,R5 ST -Y,R6 ST -Y,R7 ST -Y,R8 ST -Y,R9 ST -Y,R10 ST -Y,R11 ST -Y,R12 ST -Y,R13 ST -Y,R14 ST -Y,R15 ST -Y,R16 ST -Y,R17 ST -Y,R18 ST -Y,R19 ST -Y,R20 ST -Y,R21 ST -Y,R22 ST -Y,R23 ST -Y,R24 ST -Y,R25 ST -Y,R26 ST -Y,R27 ST -Y,R30 ST -Y,R31 .endmacro .macro POP_ALL LD R31,Y+ LD R30,Y+ LD R27,Y+ LD R26,Y+ LD R25,Y+ LD R24,Y+ LD R23,Y+ LD R22,Y+ LD R21,Y+ LD R20,Y+ LD R19,Y+ LD R18,Y+ LD R17,Y+ LD R16,Y+ LD R15,Y+ LD R14,Y+ LD R13,Y+ LD R12,Y+ LD R11,Y+ LD R10,Y+ LD R9,Y+ LD R8,Y+ LD R7,Y+ LD R6,Y+ LD R5,Y+ LD R4,Y+ LD R3,Y+ LD R2,Y+ LD R1,Y+ LD R0,Y+ .endmacro .macro PUSH_SP IN R16, 0x3d; SPL//Save SPL then SPH ST -Y, R16 IN R16, 0x3e; SPH ST -Y, R16 .endmacro .macro PUSH_SREG IN R16, 0x3f;SREG//Save SREG ST -Y, R16 .endmacro .macro POP_SP LD R16, Y+ OUT 0x3e, R16 LD R16, Y+ OUT 0x3d, R16 .endmacro .macro POP_SREG LD R16, Y+ OUT 0x3f, R16 .endmacro ****************************************************** _OSStartHighRdy:: rcall _OSTaskSwHook //OSTaskSwHook(); lds r16, _OSRunning //OSRunning=1; ldi r16, 1 sts _OSRunning, R16 lds r30, _OSTCBHighRdy //Restore Y,the software SP lds r31, _OSTCBHighRdy+1 ld R28, Z+ ld r29, Z POP_SP POP_SREG POP_ALL ret
    5. [转帖]UCOSII AVR移植全过程及心得 12/15945 实时操作系统RTOS 2007-06-27
      二、 错误纠正 哎呀,光是一个按键,一个LED亮暗多没意思啊,于是乎我做了个稍微有意思一点的测试程序。 程序利用OS的内建任务OSTaskStat统计CPU的利用率,再用6个数码管显示出来,格式为USE ××(以前做好的LED模块是6个LED)。 源程序如下: #i nclude "includes.h" #define LED_ON() PORTB|=0x1 #define LED_OFF() PORTB&=0xfe #define LED_DAT PORTA #define CS_LED PORTB #define key_scan_StkSize 70 #define LED_StkSize 90 OS_STK LEDStk[LED_StkSize]; //OS_STK key_scanStk[key_scan_StkSize]; //OS_STK key_scanStk_1[40]; unsigned char buff[6]; unsigned char key_press; const unsigned char bcd[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// void delay_us(unsigned int i); void LED(void*pdata); void key_scan(void*pdata); //void key_scan_1(void*pdata); void main(void) { OSInit(); OSTaskCreate(LED,(void*)0,&LEDStk[LED_StkSize-1],0); //OSTaskCreate(key_scan,(void*)0,&key_scanStk[key_scan_StkSize-1],8); OSStart(); } void LED(void*pdata) { unsigned char i; pdata=pdata; buff[0]=0b00111111;//U buff[1]=0b1101100;//S buff[2]=0b1111000;//E buff[3]=1;//Black CS_LED=0x1; OSStatInit(); //OSTaskCreate(key_scan_1,(void*)0,&key_scanStk_1[39],9); while(1) { for(i=0;i<6;i++) { LED_DAT=buff[i]; OSTimeDly(1); CS_LED<<=1; if(i==5) CS_LED=0x1; } } } 在OSTaskStatHook函数里修改显示缓存BUFF的值: extern unsigned char buff[]; extern const unsigned char bcd[]; #if OS_CPU_HOOKS_EN > 0 void OSTaskStatHook (void) { buff[4]=(~bcd[OSCPUUsage/10])^1; buff[5]=(~bcd[OSCPUUsage%10])^1; } #endif (取反是因为字模和我的LED相反,异或是因为数码管的第0位驱动坏了,显示值相反,呵呵)
    6. [转帖]UCOSII AVR移植全过程及心得 12/15945 实时操作系统RTOS 2007-06-27
      这样看来,没办法,这个OSTickISR必须用汇编写了。改后的汇编如下: TCNT = $32 .macro PUSH_ALL push R31 push R30 push R27 push R26 push R25 push R24 push R23 push R22 push R21 push R20 push R19 push R18 push R17 push R16 push R15 push R14 push R13 push R12 push R11 push R10 push R9 push R8 push R7 push R6 push R5 push R4 push R3 push R2 push R1 push R0 in R0, 0x3f //Save SREG push R0 .endmacro .macro POP_ALL pop R0 out 0x3f, R0 //Restore SREG pop R0 pop R1 pop R2 pop R3 pop R4 pop R5 pop R6 pop R7 pop R8 pop R9 pop R10 pop R11 pop R12 pop R13 pop R14 pop R15 pop R16 pop R17 pop R18 pop R19 pop R20 pop R21 pop R22 pop R23 pop R24 pop R25 pop R26 pop R27 pop R30 pop R31 .endmacro _OSTickISR:: PUSH_ALL ldi R19, 0xf1;0xb2 out TCNT, R19 lds R16, _OSIntNesting //OSIntNesting++; inc R16 sts _OSIntNesting, R16 cpi R16, 1 brne NO_SAVE_SP in R16, 0x3d //save sp to current tcb in R17, 0x3e sts _OSTCBCur, R16 sts (_OSTCBCur+1),R17 NO_SAVE_SP: rcall _OSTimeTick rcall _OSIntExit POP_ALL reti 重新编译运行。嘿嘿,这次好了,一天也没有死机!本以为这下子可以轻松一下,享受一下OS的快乐了,可没想到。。。。
    7. [转帖]UCOSII AVR移植全过程及心得 12/15945 实时操作系统RTOS 2007-06-27
      我写了个测试程序:其中自己建立了两个任务,LED()用于控制数码管的亮与暗,key_scan()用与判断是否按下了PA0,为了调试程序的方便,没有用OS提供的通讯机制,直接用了一个全局变量 key_press;再任务key_scan里,当检测到按键按下时设置key_press=1,否则设置为0;而任务LED()则根据key_press的值控制LED的亮与暗。 源程序如下: #i nclude "includes.h" #define LED_ON() PORTB|=0x1 #define LED_OFF() PORTB&=0xfe #define key_scan_StkSize 50 #define LED_StkSize 50 OS_STK LEDStk[LED_StkSize]; OS_STK key_scanStk[key_scan_StkSize]; unsigned char key_press; void LED(void*pdata); void key_scan(void*pdata); void main(void) { OSInit(); OSTaskCreate(LED,(void*)0,&LEDStk[LED_StkSize-1],0); OSTaskCreate(key_scan,(void*)0,&key_scanStk[key_scan_StkSize-1],8); OSStart(); } void LED(void*pdata) { pdata=pdata; //OSStatInit(); while(1) { if(key_press) LED_ON(); else LED_OFF(); OSTimeDly(2); } } void key_scan(void*pdata) { while(1) { if(PINA&0x1) key_press=1; else key_press=0; OSTimeDly(1); } } 好,开始把程序下载到双龙SL-DIY02-1开发板上运行,嘿嘿,It works!又是陶醉中…※%……%¥#¥×)(×※……¥#¥◎ 哎呀,完了!死机了!!不到十分钟就死了!按下按键LED死活不动! 再Studio上模拟跟踪反汇编后发现,#pragma ctask 对中断程序不起作用!我们来看看这会引起什么也的后果: 当执行定时器中断的时候,编译器会保存一些寄存器的值,如果再ISR中没有任务切换,那么中断执行完会弹出堆栈,没有什么问题,但是如果再ISR中发生了任务切换,那么这些被保存的寄存器就得不到恢复!使得这个堆栈变的越来越大!最后系统崩溃!!!

最近访客

< 1/1 >

统计信息

已有77人来访过

  • 芯积分:--
  • 好友:--
  • 主题:2
  • 回复:7

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言