📄 test.lss
字号:
348: 1f 92 push r1
__asm__ __volatile__("PUSH __tmp_reg__ \n\t"); /*R0 */
34a: 0f 92 push r0
__asm__ __volatile__("IN __tmp_reg__,__SREG__ \n\t"); /*保存状态寄存器SREG */
34c: 0f b6 in r0, 0x3f ; 63
__asm__ __volatile__("PUSH __tmp_reg__ \n\t");
34e: 0f 92 push r0
__asm__ __volatile__("CLR __zero_reg__ \n\t"); /*R0重新清零 */
350: 11 24 eor r1, r1
__asm__ __volatile__("PUSH R18 \n\t");
352: 2f 93 push r18
__asm__ __volatile__("PUSH R19 \n\t");
354: 3f 93 push r19
__asm__ __volatile__("PUSH R20 \n\t");
356: 4f 93 push r20
__asm__ __volatile__("PUSH R21 \n\t");
358: 5f 93 push r21
__asm__ __volatile__("PUSH R22 \n\t");
35a: 6f 93 push r22
__asm__ __volatile__("PUSH R23 \n\t");
35c: 7f 93 push r23
__asm__ __volatile__("PUSH R24 \n\t");
35e: 8f 93 push r24
__asm__ __volatile__("PUSH R25 \n\t");
360: 9f 93 push r25
__asm__ __volatile__("PUSH R26 \n\t");
362: af 93 push r26
__asm__ __volatile__("PUSH R27 \n\t");
364: bf 93 push r27
__asm__ __volatile__("PUSH R30 \n\t");
366: ef 93 push r30
__asm__ __volatile__("PUSH R31 \n\t");
368: ff 93 push r31
0000036a <Int_OSSched>:
__asm__ __volatile__("Int_OSSched: \n\t"); /*当中断要求调度,直接进入这里 */
__asm__ __volatile__("SEI \n\t");
36a: 78 94 sei
/*
开中断,因为如果因中断在任务调度中进行,已经关中断
*/
__asm__ __volatile__("PUSH R28 \n\t"); /*R28与R29用于建立在堆栈上的指针 */
36c: cf 93 push r28
__asm__ __volatile__("PUSH R29 \n\t"); /*入栈完成 */
36e: df 93 push r29
TCB[OSPrioCur].OSTaskStackTop=SP; /*将正在运行的任务的堆栈底保存 */
370: 83 2d mov r24, r3
372: 99 27 eor r25, r25
374: fc 01 movw r30, r24
376: ee 0f add r30, r30
378: ff 1f adc r31, r31
37a: ee 0f add r30, r30
37c: ff 1f adc r31, r31
37e: e8 0f add r30, r24
380: f9 1f adc r31, r25
382: eb 59 subi r30, 0x9B ; 155
384: ff 4f sbci r31, 0xFF ; 255
386: 8d b7 in r24, 0x3d ; 61
388: 9e b7 in r25, 0x3e ; 62
38a: 80 83 st Z, r24
38c: 91 83 std Z+1, r25 ; 0x01
OSPrioCur = OSPrioHighRdy ; /*运行当前就绪表中的最高优先级任务 */
38e: 35 2c mov r3, r5
cli(); /*保护堆栈转换,属于临界代码,要保护 */
390: f8 94 cli
SP=TCB[OSPrioCur].OSTaskStackTop;
392: 85 2d mov r24, r5
394: 99 27 eor r25, r25
396: fc 01 movw r30, r24
398: ee 0f add r30, r30
39a: ff 1f adc r31, r31
39c: ee 0f add r30, r30
39e: ff 1f adc r31, r31
3a0: e8 0f add r30, r24
3a2: f9 1f adc r31, r25
3a4: eb 59 subi r30, 0x9B ; 155
3a6: ff 4f sbci r31, 0xFF ; 255
3a8: 80 81 ld r24, Z
3aa: 91 81 ldd r25, Z+1 ; 0x01
3ac: 9e bf out 0x3e, r25 ; 62
3ae: 8d bf out 0x3d, r24 ; 61
sei();
3b0: 78 94 sei
/*根据中断时的出栈次序*/
__asm__ __volatile__("POP R29 \n\t");
3b2: df 91 pop r29
__asm__ __volatile__("POP R28 \n\t");
3b4: cf 91 pop r28
__asm__ __volatile__("POP R31 \n\t");
3b6: ff 91 pop r31
__asm__ __volatile__("POP R30 \n\t");
3b8: ef 91 pop r30
__asm__ __volatile__("POP R27 \n\t");
3ba: bf 91 pop r27
__asm__ __volatile__("POP R26 \n\t");
3bc: af 91 pop r26
__asm__ __volatile__("POP R25 \n\t");
3be: 9f 91 pop r25
__asm__ __volatile__("POP R24 \n\t");
3c0: 8f 91 pop r24
__asm__ __volatile__("POP R23 \n\t");
3c2: 7f 91 pop r23
__asm__ __volatile__("POP R22 \n\t");
3c4: 6f 91 pop r22
__asm__ __volatile__("POP R21 \n\t");
3c6: 5f 91 pop r21
__asm__ __volatile__("POP R20 \n\t");
3c8: 4f 91 pop r20
__asm__ __volatile__("POP R19 \n\t");
3ca: 3f 91 pop r19
__asm__ __volatile__("POP R18 \n\t");
3cc: 2f 91 pop r18
__asm__ __volatile__("POP __tmp_reg__ \n\t"); /*SERG 出栈并恢复 */
3ce: 0f 90 pop r0
__asm__ __volatile__("OUT __SREG__,__tmp_reg__ \n\t");
3d0: 0f be out 0x3f, r0 ; 63
__asm__ __volatile__("POP __tmp_reg__ \n\t"); /*R0 出栈 */
3d2: 0f 90 pop r0
__asm__ __volatile__("POP __zero_reg__ \n\t"); /*R1 出栈 */
3d4: 1f 90 pop r1
/*中断时出栈完成*/
__asm__ __volatile__("CLI \n\t"); /*关中断 */
3d6: f8 94 cli
__asm__ __volatile__("SBRC R16,1 \n\t");
3d8: 01 fd sbrc r16, 1
/*
SBRC当寄存器位为0则跳过下一条指令
检查系统正在进行任务调度时,是否有中断发生并进行要求任务调度,
如果中断要求调度则重新进行一次任务调度。
0x02是中断要求调度的标志位
*/
__asm__ __volatile__("RJMP OSSched \n\t"); /*重新调度 */
3da: 22 c0 rjmp .+68 ; 0x420
__asm__ __volatile__("LDI R16,0x00 \n\t");
3dc: 00 e0 ldi r16, 0x00 ; 0
/*
清除中断要求任务切换的标志位,清除正在任务切换标志位,
表示任务切换已经完成。
*/
__asm__ __volatile__("RETI \n\t"); /*返回并开中断 */
3de: 18 95 reti
3e0: 08 95 ret
000003e2 <IntSwitch>:
}
/************************************************************************************************************************
函数名称: IntSwitch
函数原型: void IntSwitch(void)
函数功能: 从中断退出并进行调度
入口参数: 无
出口参数: 无
有关说明: 当无中断嵌套并且中断中要求进行任务切换时才进行任务切换。
* 因为从中断到运行下一个任务共调用了两次子函数,所以要弹出四个入栈的PC
创建时间: 2007年3月3日
修改时间:
************************************************************************************************************************/
void IntSwitch(void)
{
if((OSCoreState == 0x02) && (OSIntNesting == 0))
3e2: 02 30 cpi r16, 0x02 ; 2
3e4: 41 f4 brne .+16 ; 0x3f6
3e6: 44 20 and r4, r4
3e8: 31 f4 brne .+12 ; 0x3f6
{
/*
进入中断时,已经保存了SREG和R0,R1,R18~R27,R30,R31,
所以没有必要再保存一次了,直接跳转到Int_OSSched进行下一个调度
*/
__asm__ __volatile__("POP R31 \n\t"); /*去除因调用子程序而入栈的PC*/
3ea: ff 91 pop r31
__asm__ __volatile__("POP R31 \n\t");
3ec: ff 91 pop r31
__asm__ __volatile__("POP R31 \n\t");
3ee: ff 91 pop r31
__asm__ __volatile__("POP R31 \n\t");
3f0: ff 91 pop r31
__asm__ __volatile__("LDI R16,0x01 \n\t");
3f2: 01 e0 ldi r16, 0x01 ; 1
/*
清除中断要求任务切换的标志位,设置正在任务切换标志位
*/
__asm__ __volatile__("RJMP Int_OSSched \n\t"); /*重新调度 */
3f4: ba cf rjmp .-140 ; 0x36a
3f6: 08 95 ret
3f8: 08 95 ret
000003fa <OSFindPrioHighRdy>:
}
}
/************************************************************************************************************************
函数名称: OSSched
函数原型: void OSSched(void)
函数功能: 任务调度器,进行任务调度
入口参数: 无
出口参数: 无
有关说明: 只有有更高优先级的任务就绪时才进行一次任务切换,否则不做切换
创建时间: 2007年3月7日
修改时间:
************************************************************************************************************************/
void OSSched (void)
{
OSFindPrioHighRdy(); /*找出就绪表中优先级最高的任务*/
if(OSPrioHighRdy != OSPrioCur) /*如果不是当前运行的任务,进行任务调度*/
{
OS_TASK_SW(); /*调度任务*/
}
}
/************************************************************************************************************************
函数名称: OSTaskSuspend
函数原型: void OSTaskSuspend(Uint_8bit prio)
函数功能: 挂起任务
入口参数: prio:任务优先级
出口参数: 无
有关说明: 一个任务可以挂起本身也可以挂起其他任务
创建时间: 2007年3月3日
修改时间:
************************************************************************************************************************/
void OSTaskSuspend(Uint_8bit prio)
{
OS_ENTER_CRITICAL();
TCB[prio].OSWaitTick=0;
OSRdyTbl &= ~(0x01<<prio); /*从任务就绪表上去除标志位 */
if(OSPrioCur == prio) /*当要挂起的任务为当前任务 */
{
OS_EXIT_CRITICAL();
OSSched(); /*重新调度 */
return;
}
OS_EXIT_CRITICAL();
}
/************************************************************************************************************************
函数名称: OSTaskResume
函数原型: void OSTaskResume(Uint_8bit prio)
函数功能: 恢复任务 可以让被OSTaskSuspend或 OSTimeDly暂停的任务恢复
入口参数: prio:任务优先级
出口参数: 无
有关说明:
创建时间: 2007年3月3日
修改时间:
************************************************************************************************************************/
void OSTaskResume(Uint_8bit prio)
{
OS_ENTER_CRITICAL();
OSRdyTbl |= 0x01<<prio; /*从任务就绪表上重置标志位 */
TCB[prio].OSWaitTick=0; /*将时间计时设为0,到时 */
if(OSPrioCur > prio) /*当要当前任务的优先级低于重置位的任务的优先级 */
{
OS_EXIT_CRITICAL();
OSSched(); /*重新调度 */
return;
}
OS_EXIT_CRITICAL();
}
/************************************************************************************************************************
函数名称: OSTimeDly
函数原型: void OSTimeDly(Uint_16bit ticks)
函数功能: 任务延时
入口参数: 延时的时间,任务时钟的个数
出口参数: 无
有关说明: 如果延时65535(0xffff)则为无限延时
创建时间: 2007年3月3日
修改时间:
************************************************************************************************************************/
void OSTimeDly(Uint_16bit ticks)
{
if(ticks) /*当延时有效 */
{
OS_ENTER_CRITICAL();
OSRdyTbl &= ~(0x01<<OSPrioCur); /*把任务从就绪表中去掉*/
TCB[OSPrioCur].OSWaitTick=ticks;
OS_EXIT_CRITICAL();
OSSched(); /*重新调度 */
}
}
/************************************************************************************************************************
函数名称: OSSemCreat
函数原型: void OSSemCreat(Uint_8bit Index,Uint_8bit Type)
函数功能: 初始化信号量
入口参数: Index:信号量的序号;Type:信号量类型
出口参数: 无
有关说明: Type为 0 信号量独占型;1 信号量共享型
创建时间: 2007年3月3日
修改时间:
************************************************************************************************************************/
void OSSemCreat(Uint_8bit Index,Uint_8bit Type)
{
Sem[Index].OSEventType=Type;
Sem[Index].OSTaskPendTbl=0; /*初始化时任务等待列表为空*/
Sem[Index].OSEventState=0; /*信号量无效*/
}
/************************************************************************************************************************
函数名称: OSTaskSemPend
函数原型: Uint_8bit OSTaskSemPend(Uint_8bit Index,Uint_16bit Timeout)
函数功能: 任务等待信号量,挂起
入口参数: Index:信号量序号;Timeout:等待时间
出口参数: 无
有关说明: 当Timeout==0xffff时,为无限等待
创建时间: 2007年3月3日
修改时间:
************************************************************************************************************************/
Uint_8bit OSTaskSemPend(Uint_8bit Index,Uint_16bit Timeout)
{
if(Sem[Index].OSEventState) /*信号量有效 */
{
if(Sem[Index].OSEventType == 0) /*如果为独占型 */
{
Sem[Index].OSEventState = 0x00; /*信号量被独占,不可用*/
}
}
else
{ /*加入信号的任务等待表*/
OS_ENTER_CRITICAL();
Sem[Index].OSTaskPendTbl |= 0x01<<OSPrioCur;
TCB[OSPrioCur].OSWaitTick = Timeout; /*定义等待超时 */
OSRdyTbl &= ~(0x01<<OSPrioCur); /*从任务就绪表中去除 */
OS_EXIT_CRITICAL();
OSSched(); /*重新调度 */
if(TCB[OSPrioCur].OSWaitTick==0 ) /*超时,未能拿到资源 */
{
return 0;
}
}
return 1;
}
/************************************************************************************************************************
函数名称: OSSemPost
函数原型: void OSSemPost(Uint_8bit Index)
函数功能: 发送一个信号量,可以从任务或中断发送,
* 发送完了信号量之后不进行任务调度,推荐在中断中调用
入口参数: Index:信号量的序号
出口参数: 无
有关说明: 如果有任务在等待该信号量则将该任务就绪,没有任务等待则仅仅是把信号量置为有效
创建时间: 2007年3月3日
修改时间:
************************************************************************************************************************/
void OSSemPost(Uint_8bit Index)
{
if(Sem[Index].OSEventType) /*当要求的信号量是共享型 */
{
OS_ENTER_CRITICAL();
Sem[Index].OSEventState=0x01; /*使信号量有效 */
OSRdyTbl |=Sem [Index].OSTaskPendTbl; /*使在等待该信号的所有任务就绪*/
Sem[Index].OSTaskPendTbl=0; /*清空所有等待该信号的等待任务*/
OS_EXIT_CRITICAL();
}
else /*当要求的信号量为独占型 */
{
Uint_8bit i;
i=0;
while ((i < OS_TASKS) && (!(Sem[Index].OSTaskPendTbl & (0x01<<i))))
{
i++;
/*
找出信号量等待列表中任务优先级最高的任务
*/
}
if(i < OS_TASKS) /*如果有任务需要 */
{
OS_ENTER_CRITICAL();
Sem[Index].OSTaskPendTbl &= ~(0x01<<i); /*从等待表中去除 */
OSRdyTbl |= 0x01<<i; /*任务就绪 */
OS_EXIT_CRITICAL();
}
else /*没有任务等待该信号量 */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -