CosyOS 发表于 2024-9-8 02:47:03

本帖最后由 CosyOS 于 2024-9-8 02:49 编辑

王锦平 发表于 2024-9-7 03:36
并不是我疏忽,而是我尝试想要在 task_2 中关闭LED,如我上贴中的照片所示,实际效果是LED仍然亮起
正常来 ...
。。。

CosyOS 发表于 2024-9-8 02:48:27

ethantlh 发表于 2024-9-7 10:29
今天使用库函数的时候发现CosyOS例程里的库函数可能因为比较早的缘故,里面PWM部分的PWMx_BKR写成了PWMx_BR ...

{:4_250:}
大家也都注意下!

王锦平 发表于 2024-9-8 14:43:11

本帖最后由 王锦平 于 2024-9-8 14:48 编辑

CosyOS 发表于 2024-9-8 02:36
哦,原来是这样,那证明 task_2 确实没有正常运行。
我也看不出问题出在哪里,
建议开启 任务管理器 辅助 ...
请问,这两句sStartTask_TimQry(OS_TMID_TASKMGR);
      uStartTask(Starter, OS_STATUS_READY);      // 启动任务是不是即便没有启动OS,也是会返回的。现在我自己找问题的时候貌似是OS没有正常嘀嗒,Taskmgr 也没有正常运行。
我也查看了 mSys_INIT 和 init_hook() ,确实已经对定时器0进行了配置与开启了中断{:4_178:}
void init_hook(void)
{
      #define BAUD115200 // 串口波特率
      #define TM2   (65536 - SYSCFG_SYSCLK / 4 / BAUD)
      P0M0 = 0; P0M1 = 0;
      P1M0 = 0; P1M1 = 0;
      P2M0 = 0; P2M1 = 0;
      P3M0 = 0; P3M1 = 0;
      P4M0 = 0; P4M1 = 0;
      P5M0 = 0; P5M1 = 0;
      #if TARGET_8H
      P6M0 = 0; P6M1 = 0;
      P7M0 = 0; P7M1 = 0;
      #endif
      
      AUXR=      0x00;// 允许访问内部xdata
      #if TARGET_8H
      P_SW2 =      EAXFR; // 允许访问扩展RAM区特殊功能寄存器
      #else
      BIT_SET_ONE(P_SW2, 7);// 允许访问扩展RAM区特殊功能寄存器
      #endif
      
      TMOD = 0x00;   // 定时器0、1、2、3、4为16位自动重装载模式
      AUXR = 0x45;   // 定时器1、2为1T模式,串口1用定时器2做波特率发生器
      SCON = 0x40;   // 串口1工作模式为模式1
      S2CON = 0x40;// 串口2工作模式为模式0,串口2用定时器2做波特率发生器
      #if TARGET_8H
      P_SW1 = 0xC0;// 串口1切换至P4.3/P4.4
      #else
      P_SW1 = 0x08;      // 串口1切换至P3.0/P3.1
      #endif
      TI = 1;      // 用于printf
      /* 定时器2 */
      T2L = (unsigned char)TM2;
      T2H = (unsigned char)(TM2 >> 8);
      #if TARGET_8H
      AUXR|= T2R;
      #else
      BIT_SET_ONE(AUXR, 4);
      #endif

      /* UART2中断优先级为1级 */
      #if TARGET_8H
      IP2H &=~PS2H;
      IP2 |= PS2;
      #else
      BIT_SET_ZERO(IP2H, 0);
      BIT_SET_ONE(IP2, 0);
      #endif
      
      /* INT0中断优先级为0级 */
      #if TARGET_8H
      IPH &=~PX0H;
    PX0 = 0;
      #else
      BIT_SET_ZERO(IPH, 0);
      BIT_SET_ZERO(IP, 0);
      #endif
      
      /* 任务管理器 */
      #if SYSCFG_DEBUGGING == 1
      #if TARGET_8H
      S2CON |= S2REN;
      IE2 |= ES2;
      #else
      BIT_SET_ONE(S2CON, 4);// 允许串口2接收中断
      BIT_SET_ONE(IE2, 0);// 允许串口2中断
      #endif
      #endif

      GPIO_setOpenDrainOutput(3, 3);// P0
    GPIO_setPushPullupOutput(0, 0);
}#define mSys_INIT \
do{ \
      s_init_mempool((void _MALLOC_MEM_ *)MCUCFG_MALLOCMEMBPTR, MCUCFG_MALLOCMEMSIZE); \
      OS_NOPx1; \
      AUXR = mSysTick_CLKMOD == 1 ? AUXR | 0x80 : AUXR &~0x80; \
      TMOD &= 0xF0; \
      TL0 = (s_u8_t)(mSysTick_InitValue); \
      TH0 = (s_u8_t)(mSysTick_InitValue >> 8); \
      TR0 = 1; \
      mSysIRQ_Enable; \
      EA = 1; \
}while(false)在进入 Sysidle 不知道后面跑哪去了{:4_177:}
此处操作IO和打印是没有效果的

uCreateTask(Sysidle, 0, MCUCFG_STACKSIZE_SYSIDLE, 0, 0)
{
        P33 = 1;
        P00 = 0;
        printf("----0----");
        #if SYSCFG_SAFERUNTIME == __ENABLED__
        if(true){
                s_tid_t i;
                for(i = 1; i < OS_TASKTOTAL + 1; i++){
                        s_sign_timeout = 0;
                }
        }
        #endif
        #if SYSCFG_SOFTRTC == __ENABLED__
        if(true){
                static s_u8_t year = 0xFF;
                if(year != s_rtc){
                        year = s_rtc;
                        s_month2day = year ? ((year & 3) ? 28 : 29) : ((sDefCentury & 3) ? 28 : 29);
                }
        }
        #endif
        #if SYSCFG_IDLEHOOK == __ENABLED__
        idle_hook();
        #endif
        #if SYSCFG_LOWPOWERMODE == __ENABLED__
        mSys_Idle;
        #endif
        OS_NOPx2;
        uEndTasking;
}
还请楼主为我解惑




CosyOS 发表于 2024-9-9 03:52:27

本帖最后由 CosyOS 于 2024-9-9 04:03 编辑

王锦平 发表于 2024-9-8 14:43
请问,这两句是不是即便没有启动OS,也是会返回的。现在我自己找问题的时候貌似是OS没有正常嘀嗒,Taskmgr ...
1、sStartTask、uStartTask,都会返回错误码;
2、启动任务 都是在 PendSV中断中进行,如果PendSV中断不能进入,则启动任务失败,系统会貌似死机。
3、PendSV默认用INT0,如果你没改动,是不会有问题的。
4、可以先不用考虑 系统滴答,它与 启动任务 无关。


1、你可以多搞一些 printf, 看能输出哪些内容,从而判断 程序 走到了哪里。

2、注意 Starter、start_hook 能否进入,这能说明 PendSV中断是否正常进入。
3、建议你 任务管理器 先用默认的UART2,可以进行串口切换操作。
   应设法先让 任务管理器 正常运行,它会成为你的好帮手。
   默认所有有关UART2的设置都与 任务管理器 相关,包括 init_hook、syscfg.h -> DEBUG接口设置。
   还有 \User\Taskmgr.c,应反复核对。
你给我的程序就有误:
看其它地方的代码,你还是要用UART2,但
#define SYSCFG_DEBUGSEND               SCON |= 1 << 1
就不对了,应
#define SYSCFG_DEBUGSEND               S2CON |= S2TI

4、注意 syscfg.h、mcucfg_8051.h 中的配置,可以对比原有的设置,没必要的先不要改动。

我用你给我的程序,即使 #define TARGET_8H 0,用 STC8H8K 测试也是正常的。
但我手里没有 STC8C 的板子。

你先设法让 任务管理器 正常输出,并关注 printf 的信息,我再帮你分析问题出在哪里。


王锦平 发表于 2024-9-9 09:07:43

本帖最后由 王锦平 于 2024-9-9 23:26 编辑

CosyOS 发表于 2024-9-9 03:52
1、sStartTask、uStartTask,都会返回错误码;
2、启动任务 都是在 PendSV中断中进行,如果PendSV中断不能 ...
现在我可以确认,系统确确实实是死机了,中断没有进入,OS_tick 没有起来。这个我不知道要怎么解决,只能等楼主你喂饭。
Starter、start_hook 确实也是没有进去的,并不是我最一开始说的能设置 GPIO_mode 不能设置 GPIO_level {:4_194:}
关于 INT0 ,我仅在 init_hook() 里面按照注释修改了中断优先级( 只是因为8H可直接寻址的寄存器在8C不可直接寻址才修改的 )。
我之前发到贴子上的那个工程,问题应该也是一样的,中断没有进入,OS_tick 没有起来。
关于这个
#define SYSCFG_DEBUGSEND SCON |= 1<<1
是因为我现在这个板子上只保留了 UART1 可用,别的IO都连接到LED去了,没得改{:4_184:}

CosyOS 发表于 2024-9-10 01:55:31

王锦平 发表于 2024-9-9 09:07
现在我可以确认,系统确确实实是死机了,中断没有进入,OS_tick 没有起来。这个我不知道要怎么解决,只能 ...

你在 os_handler.c 中,点一个灯吧,或 printf,以判断 是否能成功进入 INT0中断 一次。


估计是不能进入,如果不能再找原因。

PendSV的替代中断需满足一个条件,
在关闭该中断的前提下,置中断标志位后再开启中断,得能响应中断。

你在裸机下自己测试下,INT0能否满足条件?
void main()
{
   ...
   EA = 1;
   IE0 = 1;
   EX0 = 1;
   while(1);
}

void INT0_Isr() interrupt 0
{
   点灯或printf等,以判断能否进入中断;
}

如果不能进入,说明 INT0 不满足条件;
如果能进入,说明INT0的相关配置可能还有误。

先不用管定时器0中断能否进入。

王锦平 发表于 2024-9-10 10:15:38

CosyOS 发表于 2024-9-10 01:55
你在 os_handler.c 中,点一个灯吧,或 printf,以判断 是否能成功进入 INT0中断 一次。




如图所示,INT0 能正常进入,配置确实也是直接copy你这几句,我也看了OS里头关于 INT0 的宏定义,配置也没有问题

CosyOS 发表于 2024-9-10 23:04:05

王锦平 发表于 2024-9-10 10:15
如图所示,INT0 能正常进入,配置确实也是直接copy你这几句,我也看了OS里头关于 INT0 的宏定义,配置也 ...
必须 先 IE0 = 1; 再 EX0 = 1; 如果能进入 INT0 才算正常。
IE0 = 1 时,要先确保 EX0 = 0。

我再给你写一个更准确的测试程序:
void main()
{
   ...
   EA = 1;
   while(1){
      IE0 = 1;
      EX0 = 1;
      _nop_();
      _nop_();
      EX0 = 0;
      delay_ms(1000); // 你自己搞个软件延时
   }
}

void INT0_Isr() interrupt 0
{
   static unsigned int i = 0;
   printf("INT0: %u\r\n", ++i);
}


如果能每隔1s钟 打印输出次数,
INT0:1
INT0:2
INT0:3
...
...
...
才算正常,证明INT0满足条件。


王锦平 发表于 2024-9-11 04:35:45

本帖最后由 王锦平 于 2024-9-11 23:59 编辑

CosyOS 发表于 2024-9-10 23:04
必须 先 IE0 = 1; 再 EX0 = 1; 如果能进入 INT0 才算正常。
IE0 = 1 时,要先确保 EX0 = 0。


试了一个多小时,确认是进不了 INT0 中断。。。在 while(1) 循环之前还能进一下,但是一进到循环里头延时以后就卡死了。

若只是延时后,打印输出却是没有问题的{:4_177:}
现在我不知道如何确认是什么问题导致 INT0 中断在循环里头进不去

在此之前,我还尝试了使用 timer0 来用作延时,但也出现了无法进入中断的情况。甚至我一旦打印 timer0 相关寄存器的值,就会出现卡死的情况{:4_199:}还出现了先初始化了 timer1 作为波特率发生器后,timer0 无法初始化的情况{:4_260:}


或许这可以解释为什么我移植了OS以后 OS_tick 没有起来

CosyOS 发表于 2024-9-12 22:27:29

王锦平 发表于 2024-9-11 04:35
试了一个多小时,确认是进不了 INT0 中断。。。在 while(1) 循环之前还能进一下,但是一进到循环里头延时 ...

如果是先 EX0 = 1; 再 IE0 = 1; 自然是能进INT0中断的;
但 PendSV中断 必须满足的条件是:
在 EX0 = 0; 的前提下,先 IE0 = 1; 再 EX0 = 1; 得能进入INT0中断。
STC8C 的 INT0 能否满足条件,我不知道,但感觉应该是可以的。
你重新整理一下代码,把 点灯的、printf 的都取消,保留 IO模式设置,
而后在 os_handler.c 中,PendSV中断中点灯,


如果灯能亮,证明 INT0 满足条件。
要注意,INT0 对应 IO 不能再使用了。

建议你先用 STC8H的板子,如 开天斧 或 试验箱,先好好熟悉一下 CosyOS。


如果还搞不定,你可以考虑把板子寄给我,加我QQ:2146166599。
或者你自己慢慢搞吧!



页: 80 81 82 83 84 85 86 87 88 89 [90] 91 92 93 94 95 96 97 98 99
查看完整版本: 全局不关总中断的 RTOS,CosyOS-III-V1.2.0, 送 擎天柱-AI8051U转89C52核心板