cbailjc
发表于 2014-6-3 17:08:58
学习中,加一楼。
sunwei
发表于 2014-6-4 08:48:52
看看,学习学习!
ppdd
发表于 2014-6-6 14:29:08
smset 发表于 2013-10-25 13:24
根据你的描述,总体上你还是在以定时器加状态机的思路在描述需求。
当然,也能用小小调度器任务机制来实 ...
正好解决我的疑问。
ppdd
发表于 2014-6-6 14:42:45
smset 发表于 2014-4-24 17:03
示意代码(统一按20ms去抖的):
子任务调用,记号学习!
ppdd
发表于 2014-6-6 15:21:14
gtzhangzr 发表于 2014-5-20 12:16
头文件,顶一千楼
可否共享下你用的这两个文件供学习下!!
#include <stdint.h>
#include <stdbool.h>
谢谢!!
fancyboy
发表于 2014-6-6 16:24:32
太棒了,用这个比裸跑方便多了
gtzhangzr
发表于 2014-6-6 21:31:35
ppdd 发表于 2014-6-6 15:21
可否共享下你用的这两个文件供学习下!!
#include
#include
标准库里就有啊
ppdd
发表于 2014-6-6 23:59:40
gtzhangzr 发表于 2014-6-6 21:31
标准库里就有啊
keil 里面没有, 不过在AD的Tasking 里面找到。
谢谢!!
u123321
发表于 2014-6-7 17:19:04
支持到1000楼
奮闘ing
发表于 2014-6-7 17:57:55
{:smile:}学习了~~~
lts
发表于 2014-6-9 14:32:57
本帖最后由 lts 于 2014-6-10 13:26 编辑
在pt中有这个函数,作用是Block and wait until condition is true.,感觉非常好用,楼主能不能在小小的上面加上.
参考pt添加:#define WAIT_UNTIL(condition)do {_lc=(__LINE__+((__LINE__%256)==0))%256; }while(0); case (__LINE__+((__LINE__%256)==0))%256: if(!(condition)){return 0 ;}
pt中原函数:
#define PT_WAIT_UNTIL(pt, condition) \
do { \
LC_SET((pt)->lc); \
if(!(condition)) { \
return PT_WAITING; \
} \
} while(0)
yxylxj
发表于 2014-6-11 11:43:43
心里 有个疑问 这个调度器 是按行号 跳转的如果函数分别在不同的.c文件呢? 会出现什么情况
lwang
发表于 2014-6-14 22:21:17
期待楼主出更详细的说明
xiepan2010
发表于 2014-6-15 10:27:29
再填一楼 1000楼有希望 这个调度器我已经用到平衡车上了 目前没出问题
blue1025
发表于 2014-6-15 21:11:34
好东西,下次我也用用,谢谢!
xiepan2010
发表于 2014-6-27 12:39:06
任务函数内的子函数能不能用返回值的?
lxcndz1
发表于 2014-6-28 23:19:32
谢谢分享
rockyyangyang
发表于 2014-6-28 23:37:48
强势mark
hhww8280
发表于 2014-6-29 15:22:28
一直裸奔的mark
lxcndz1
发表于 2014-6-29 21:26:30
unsigned chartask2(){
static unsigned charidata i;
_SS
while(1){
WaitX(2);
// write_data();
//+++++++++++++++++++++++
if(f_delay==1)
{
if(f_v_i==1)
{
dish=disvh;
dism=disvm;
disl=disvl;
}
else
{
dish=disih;
dism=disim;
disl=disil;
}
}
jdqlock;
led_bit_off;
smg_bl_off;
smg_bm_off;
smg_bh_off;
//-----------------
// output();
//------------------
//-----key---------
// i=bakbak;
//dish=(bakbak>>8)&0x0f;
//dism=(bakbak>>4)&0x0f;
// disl=bakbak&0x0f;
//----------------
// dish=bufferh;
// dism=bufferm;
// disl=bufferl;
if(sibit==0)
{
i=0;
if(fover==0)
{
i=table12;
if(f_v_i==0)
{
i=i|0x08;
}//dian liu
else
{
if(dish==0)
{
i=0;
}
}
}
else
{
shaketime++;
if(shaketime>50)
{
shaketime=0;
}
//i=0x00 ;
if(shaketime>25)
{
i=0xa7 ;
}
}
//------------------
// i=table12;
write_59512(i);
//----------------
sibit=1;
smg_bh_on;
}
else if(sibit==1)
{
// dism=(keytemp>>4)&0x0f;
i=table12;
if(f_v_i==1)
{
if(f_dc==1)
i=i|0x08;
}
if(fover==1)
{
i=0;
}
write_59512(i);
smg_bm_on;
sibit=2;
}
elseif(sibit==2)
{
if(fover==1)
{
i=0;
}
else
{
i=table12;
}
write_59512(i);
smg_bl_on;
sibit=3;
}
else if(sibit==3)
{
disled=0;
if(f_v_i==1) //v
{
disled=disled|0x80;
} // v led
else
{
disled=disled|0x20;
} // i led
if(f_dc==1)
{
disled=disled|0x01;
}//zhiliu led
if(f_ac==1)
{
disled=disled|0x40;
} //jiaoliu led
i=disled;
write_59512(i);
led_bit_on;
sibit=4;
}
else
{
if(f_delay==0)
{
adall++;
if(adall>10)
{
f_delay=1; //上电显示表示时间
}
}
if(f_key==0)
{
rejdq++;
if(rejdq>10)
{
f_key=1;
f_pwm=1;
}
}
else
{
rejdq=0;
}
i=0x00;
write_59512(i);
output();
sibit=0;
}
//
//----------------------
//=======================
//+++++++++++++++++++++++
}
_EE
}
void write_59512 (unsigned char data1)
{
static unsigned char i,ledbuffer;
rck595_l;
ledbuffer=data1;
for(i=0;i<8;i++)
{
sck595_l; // SPI_CLK = 0
if( (ledbuffer&0x80)==0x00 )
{
data595_l;
}
else
{
data595_h;
}
ledbuffer <<= 1;
delay1();
sck595_h;
delay1();
}
rck595_l;
rck595_l;
rck595_h;
}
write_59512(i);
output();
这样调用子函数行吗
lxcndz1
发表于 2014-7-1 18:57:25
这是已经做好的小项目,正常运行。改为调度器,极小资源单片机
现只有 RunTaskA(task2,2);//任务2具有低的运行权限 dis
RunTaskA(task1,1);//任务1具有比任务2高的运行权限 key
这两个能运行
RunTaskA(task3,3);//任务2具有低的运行权限 ad,不进入
去掉前面两个中的一个后,ad能进入。
stc5604AD芯片
ppdd
发表于 2014-7-2 00:07:11
希望能用这个调度器 出个 包含串口和18b20的 例子!
fgdzypf
发表于 2014-7-2 09:08:26
再看看,支持再支持
zhongsandaoren
发表于 2014-7-2 13:02:23
玩玩还可以,支持!{:biggrin:}
mute
发表于 2014-7-4 12:43:52
希望早点出教程啊,或者例子,包括那些函数的用法
mute
发表于 2014-7-4 13:12:13
本帖最后由 mute 于 2014-7-5 08:29 编辑
//初始化信号量
#define InitSem(sem) sem=0;
//等待信号量
#define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
//等待信号量或定时器溢出, 定时器tickets 最大为0xFFFE
#define WaitSemX(sem,tickets)do { sem=tickets+1; WaitX(0); if(sem>1){ sem--;return 1;} } while(0);
//发送信号量
#define SendSem(sem)do {sem=0;} while(0);
这几个信号量建议这样修改:
init: sem=1;初始化成无效
waitsem:do{ if (sem >0) {WaitX(0);if (sem>0) return 1;} sem=1;}while(0); 先判断sem,无效就直接返回等待下个tick再检测。如果有效就往下执行,但是要先把sem改成无效。
waitsemx: 也按上面的waitsem修改。do { if(sem>0){sem=tickets+1; WaitX(0);} if(sem>1){ sem--;return 1;}sem=1;} while(0);
sendsem:照旧
就是在wait完成之后,才把sem改成无效。不要在wait时把sem改成无效。
这样即使在wait前,某个中断send了sem,那么在wait时还检测到这个send了的sem。
不会出现中断send早了,wait晚了就会丢失了这个sem。
holts2
发表于 2014-7-4 13:18:28
你说错了, SEM=0 才是无效
mute
发表于 2014-7-4 13:30:59
holts2 发表于 2014-7-4 13:18
你说错了, SEM=0 才是无效
仔细看,sendsem sem=0,0才是有效的
mute
发表于 2014-7-4 13:38:02
不过还是有个临界状态的问题。
比如waitsem获得了信号量,在if判断后和sem=1前的瞬间,触发了中断,中断里send了sem。这样中断里的sendsem就会被丢弃了。
rockyyangyang
发表于 2014-7-4 15:56:34
赞
只为那梦的轮回
发表于 2014-7-4 16:12:53
顶!!!!!
holts2
发表于 2014-7-4 16:16:24
本帖最后由 holts2 于 2014-7-4 16:28 编辑
mute 发表于 2014-7-4 13:38
不过还是有个临界状态的问题。
比如waitsem获得了信号量,在if判断后和sem=1前的瞬间,触发了中断,中断里s ...
你的理解是错误的, WaitSem(sem) 的意思,是你的任务去调用它,调用后,它将sem=1 置为有效, 同时退出你的任务并保存断点,将控制权交操作系统, 注意,这个时候你的任务的后半断还没有执行, 只有当 sem=0 等待无效时,才会执行你的任务中 waitsem(sem)后面的代码,否则后面的代码永远不会执行。
所以
sem = 1等待有效 程序将控制权交回操作系统,你的任务一直在这里等待
sem = 0等待无效 程序不等待,顺次执行你的任务中后面的代码
也不会有你说的临界状态的问题,因为 哪个sem=1 只会执行一次
Frank.Dong
发表于 2014-7-4 16:52:14
学习了。
mute
发表于 2014-7-5 06:25:11
本帖最后由 mute 于 2014-7-5 08:29 编辑
holts2 发表于 2014-7-4 16:16
你的理解是错误的, WaitSem(sem) 的意思,是你的任务去调用它,调用后,它将sem=1 置为有效, 同 ...
wait信号量既然叫等待,当然是等待别人给你发信号量。
没发过来之前,信号量是空的,是无效的,才要等待。
如果你一定要把sem叫做等待,不叫信号量,那么waitx,就应该叫waitstart。sendsem,应该叫waitstop。
不过无论怎么理解,总是存在这个bug。
int
{
sendsem
}
taska
{
init sem
开启int
while(1)
{
worka
waitsem
workb
}
}
在开启int到开始waitsem之间,如果有int产生并sendsem了,这个sem就会被waitsem清掉,丢弃掉。
同样,在执行worka和workb时,如果中断int产生sendsem,sem=0。等运行到waitsem时,又会被sem=1丢弃掉。
只有waitsem时,taska卡在这个sem上的时候,int产生sendsem才会有效。这明显就是个bug
另外一个改进:waitsemx(sem,tickets) 可以添加一个是超时标志
waitsemx(sem,tickets,istimeout) do { if(sem>0){sem=tickets+1; WaitX(0);} if(sem>1){ sem--;return 1;} istimeout=(sem==1); sem=1;} while(0);
当istimeout为true时,是超时。为false时,是等到了信号量。
超时标志对后续的处理代码有很大帮助
lyrics131415
发表于 2014-7-5 07:06:41
学习了,谢谢楼主分享
mute
发表于 2014-7-5 07:34:01
本帖最后由 mute 于 2014-7-5 08:34 编辑
唯一不好的问题就是无法使用内部的临时变量。
如果全改成static,就浪费了很多ram,与这个调度器节省资源的目标背道而驰。
不过用状态机也一样存在这个问题。
这个调度器任务的时间切片可以切得很细,多几个切片对编码来说一点也不麻烦,随便多插几个wait(0)就能把任务切碎。提高任务的响应时间。
我根据各位的代码重新处理了一下,修复了sem问题,并加了sem timeout的flag,大家看看有没有问题
#define SCH_MAX_TICK 0xFFFF
#define SCH_MAX_TASK 16
typedef volatile uint8_t SCH_LC;
typedef volatile uint16_t SCH_TICK;
typedef volatile uint16_t SCH_SEM;
typedef SCH_TICK SCH_TASK_RESULT;
SCH_TICK SCH_TaskTicks;
/******************************* 调度器 **********************************/
#define SCH_LINE_NUM((__LINE__ + ((__LINE__ % 256) == 0)) % 256)
#define SCH_TASK_BEGIN() \
static SCH_LC _sch_lc_ = 0; \
switch (_sch_lc_) \
{ \
default:
#define SCH_TASK_END() \
; \
}; \
_sch_lc_ = 0; \
return SCH_MAX_TICK
#define SCH_DELAY(ticks) \
do \
{ \
_sch_lc_ = SCH_LINE_NUM; \
return ticks; \
} while (0); \
case SCH_LINE_NUM:
#define SCH_RUN_TASK(task, id) \
do \
{ \
if (SCH_TaskTicks == 0) \
{ \
SCH_TaskTicks = task(); \
} \
} while (0)
#define SCH_RUN_TASK_PRIO(task, id) \
do \
{ \
if (SCH_TaskTicks == 0) \
{ \
SCH_TaskTicks = task(); \
continue; \
} \
} while (0)
#define SCH_CALL_SUB_TASK(subtask) \
do \
{ \
{ \
SCH_TICK _sch_sub_task_dt_; \
_sch_lc_ = SCH_LINE_NUM; \
return 0; \
case SCH_LINE_NUM: \
_sch_sub_task_dt_ = subtask(); \
if (_sch_sub_task_dt_ != SCH_MAX_TICK) \
{ \
return _sch_sub_task_dt_; \
} \
} \
} while(0)
#define SCH_INIT() \
{ \
SCH_LC _sch_i_; \
for (_sch_i_ = SCH_MAX_TASK; _sch_i_ > 0; _sch_i_--) \
{ \
SCH_TaskTicks = 0; \
} \
}
#define SCH_UPDATE_TICKS() \
{ \
SCH_LC _sch_i_; \
for (_sch_i_ = SCH_MAX_TASK; _sch_i_ > 0; _sch_i_--) \
{ \
if ((SCH_TaskTicks != 0) && \
(SCH_TaskTicks != SCH_MAX_TICK)) \
{ \
SCH_TaskTicks--; \
} \
} \
}
/********************************** 信号量 *******************************/
#define SCH_SEM_INIT(sem) SCH_SEM sem = 1
#define SCH_SEM_WAIT(sem) \
do \
{ \
if (sem > 0) \
{ \
SCH_DELAY(0); \
if (sem > 0) \
return 1; \
} \
sem = 1; \
} while (0)
#define SCH_SEM_WAIT_TIMEOUT(sem, tick) \
do \
{ \
if (sem > 0) \
{ \
sem = tick + 1; \
SCH_DELAY(0); \
} \
if (sem > 1) \
{ \
sem--; \
return 1; \
} \
sem = 1; \
} while (0)
#define SCH_SEM_WAIT_TIMEOUT_FLAG(sem, tick, istimout) \
do \
{ \
if (sem > 0) \
{ \
sem = tick + 1; \
SCH_DELAY(0); \
} \
if (sem > 1) \
{ \
sem--; \
return 1; \
} \
istimout = (sem != 0); \
sem = 1; \
} while (0)
#define SCH_SEM_SEND(sem) \
do \
{ \
sem = 0; \
} while (0)
fgdzypf
发表于 2014-7-5 08:03:00
高手呀,支持{:smile:}
mute
发表于 2014-7-5 08:13:15
本帖最后由 mute 于 2014-7-5 09:08 编辑
其实main函数的while(1)循环就是调度器,从上到下循环调度任务。每个任务运行完片段后用return交出运行权。
与实时OS有区别的是这个任务必须自行交出运行权,其他任务才有执行的可能。所以任务的运行片段切的越碎越好。这样实时性才好。
唯一可以直接剥夺其他任务运行权的是中断,就是示例里在中断里执行的taska。
至于临时变量的问题,把task里所有功能都切成碎片放到func里,可以避免局部变量被改变的问题,A和B之间的数据传递用静态变量。
这样就能显性地强制临时变量不会跨调度界线使用了,但是有没有可能funcA和B会被编译器优化,嵌到task里去?那样就容易出隐性问题了。
task
{
funcA
waitsem
funcB
}
holts2
发表于 2014-7-5 09:49:24
mute 发表于 2014-7-5 06:25
wait信号量既然叫等待,当然是等待别人给你发信号量。
没发过来之前,信号量是空的,是无效的,才要等待 ...
你的概念不清,并且没有看懂这个程序,在理解看懂的基础上再改程序,好不好? 请重新从开头阅读这个贴子, 按你的思路,纠正下信号的玩法应该是这样玩:
taskb
{
sendsem
}
taska
{
while(1)
{
worka
waitsem
workb
}
}
void main(void)
{
init sem
while (1)
{
taskb();
taska();
}
}
lts
发表于 2014-7-5 09:49:24
在包含调度器的程序中,可以调用其他子程序吗?被调用的子程序的局部变量有什么限制吗?
mute
发表于 2014-7-5 11:00:21
本帖最后由 mute 于 2014-7-5 11:09 编辑
holts2 发表于 2014-7-5 09:49
你的概念不清,并且没有看懂这个程序,在理解看懂的基础上再改程序,好不好? 请重新从开头阅读这个贴子 ...
那按你思路你怎么用semsend和semwait?
我认为没什么歧义,从没听说过限死只能在任务里发信号量的。
中断里收数据,然后send sem是很常见的操作。
如果task在运行worka和b时产生了中断,task就直接错失了中断里的信号量。
holts2
发表于 2014-7-5 11:10:28
mute 发表于 2014-7-5 11:00
那按你思路你怎么用semsend和semwait?
我认为没什么歧义,从没听说过限定只能在任务里发信号量的。 ...
你把 init sem放在任务A里,退出任务A,变量sem不就没有了吗 ? taskb还在眼吧吧的等着sem=0, 你让它去哪找这个 sem ? 所以按你写的哪个逻辑,本身就是行不通的。
mute
发表于 2014-7-5 11:12:15
本帖最后由 mute 于 2014-7-5 11:17 编辑
holts2 发表于 2014-7-5 11:10
你把 init sem放在任务A里,退出任务A,变量sem不就没有了吗 ? taskb还在眼吧吧的等着sem=0, ...
是的,这里写错了,init sem应该是全局变量。
但是这个笔误并不会影响int里的semsend会丢掉的问题
另外我说的是在中断int里semsend,不要提taskb好不好?
就按楼主的代码,我要设计这么一个程序,你说有没有问题?
声明 sem;
中断int
{
收到数据保存到fifo里
sendsem
}
taska
{
while(1)
{
worka
waitsem
workb处理int里fifo收到的数据
}
}
main
{
init sem
开启中断int
runtask(taska)
}
holts2
发表于 2014-7-5 11:16:25
本帖最后由 holts2 于 2014-7-5 11:18 编辑
mute 发表于 2014-7-5 11:12
是的,这里写错了,init sem应该是全局变量。
但是这个笔误并不会影响int里的semsend会丢掉的问题
放在中断里也是一样的,sem应该是全局变量 ,semsend不会丢, 关键是你没有理解Wait(X)是如何将控制权交回给操作系统的,当操作系统第二次进入TASKA时切入点在哪里。
holts2
发表于 2014-7-5 11:25:52
本帖最后由 holts2 于 2014-7-5 11:27 编辑
mute 发表于 2014-7-5 11:12
是的,这里写错了,init sem应该是全局变量。
但是这个笔误并不会影响int里的semsend会丢掉的问题
改成这样会不会更好点 ?
声明 sem;
中断int
{
收到数据保存到fifo里
sendsem
}
taska
{
while(1)
{
worka
waitsem
关中断
workb处理int里fifo收到的数据
开中断
}
}
main
{
init sem
开中断
while(1){
runtask(taska)
}
}
mute
发表于 2014-7-5 11:33:34
holts2 发表于 2014-7-5 11:16
放在中断里也是一样的,sem应该是全局变量 ,semsend不会丢, 关键是你没有理解Wait(X)是如何将控制 ...
是你没懂我意思吧,我没说task要return切出去啊,我说的是task一直在获得运行权的过程。麻烦你仔细看我说的过程好不好?
如果中断int产生第一次sendsem,task得到了sem,开始执行workb,然后完了从while 1头又执行worka,在没有再次运行到waitsem之前,中断int又产生了一次semsend,把sem=0了,然后task运行到了waitsem,把sem=1,再去等sem=0已经等不着了,因为已经被waitsem冲掉了。这第二次的int就被丢弃了。
mute
发表于 2014-7-5 11:39:39
holts2 发表于 2014-7-5 11:25
改成这样会不会更好点 ?
我的修改就是在waitsem等到sem=0之后,立即将sem=1。这样就只会在 if sem==0 和 sem=1,这样一条指令的时间内才可能错失中断int的sem,错失的可能性就很小了。如果完全防止错失,那么加关开中断也可以,毕竟只有几条指令的时间。
如果按原来的程序,你在workb前后加关开中断还不够!必须把worka也包括进去!
holts2
发表于 2014-7-5 11:40:56
本帖最后由 holts2 于 2014-7-5 11:53 编辑
mute 发表于 2014-7-5 11:33
是你没懂我意思吧,我没说task要return切出去啊,我说的是task一直在获得运行权的过程。麻烦你仔细看我说 ...
什么叫 task一直在获得运行权的过程 ? 可能吗 ? 你的操作系统在哪 ?你执行时waitsem就已经退出去了,当操作系统第二次把控制权交回给task时,程序的切入点不是waitsem的第一个语句,而你以为是第一个语句,所以不存在你说的哪些问题。
68336016
发表于 2014-7-5 11:45:20
的确很巧妙,但是好像不能再使用switch了
holts2
发表于 2014-7-5 11:47:22
mute 发表于 2014-7-5 11:39
我的修改就是在waitsem等到sem=0之后,立即将sem=1。这样就只会在 if sem==0 和 sem=1,这样一条指令的时 ...
只要workA 和 WortB的最大执行时间,小于中断周期,每次中断取到的数据都可以确保处理到,但是,如果workA或WortB的执行时间大于中断周期则会丢包,这已经和程序结构没关系了,是任务切分合理不合理的问题
mute
发表于 2014-7-5 11:54:46
本帖最后由 mute 于 2014-7-5 12:00 编辑
holts2 发表于 2014-7-5 11:47
只要workA 和 WortB的最大执行时间,小于中断周期,每次中断取到的数据都可以确保处理到,但是,如果work ...
如果本来的方式无法容忍两次连续中断,现在改了以后能容忍两次(虽然仍旧无法容忍连续的中断),没有代价能提高性能总是好事!
涉及到中断的临界代码段本来就是很麻烦的事,我都恨不得能把判断和赋值放到单条指令里,像这样跨越worka和workb太奇怪了。
况且worka和workb的处理时间经常不是固定的长短。
比如串口中断,收一个字节判断一次。在收全一整个包后要做某些耗时间的处理,这时候占的时间可能就超过一个中断周期了!
但不是每个字节的中断后的workb都是要用这么长的时间。
holts2
发表于 2014-7-5 12:04:26
本帖最后由 holts2 于 2014-7-5 12:05 编辑
mute 发表于 2014-7-5 11:54
如果本来的方式无法容忍两次连续中断,现在改了以后能容忍两次(虽然仍旧无法容忍连续的中断),没有代价 ...
如果你不能确定任务的执行时间,你应该选用可抢占方式的操作系统,而且我也不理解,为什么workA, WorkB你不把它切为两个任务taska,taskb.
holts2
发表于 2014-7-5 12:15:41
mute 发表于 2014-7-5 11:39
我的修改就是在waitsem等到sem=0之后,立即将sem=1。这样就只会在 if sem==0 和 sem=1,这样一条指令的时 ...
不是的,这里前后加关开中断的目的是确保本次处理的数据是一次完整的数据,如果不这样做的话,如果在处理的过程中,又发生中断,则处理的数据则有部份是上次的片断,部份是本次的片断。
你所说的是另一件事,是任务切分大小的问题,这里解决不了。
mute
发表于 2014-7-5 12:37:10
本帖最后由 mute 于 2014-7-5 12:50 编辑
木桶的短板本来就是要加以优化和改善,却以这短板本来就是这桶的缺点,拒绝优化。
数据要求这么高就放fifo之类的解决,却对整个work都去加一个关开中断,每个task都这么去关开中断,你确定你是这样做产品的?
我一直在说workb中间出中断的问题,以及如何在代码里优化这种情况。在一样的work切分大小情况下,能以更小的出错几率难道不值得讨论???
倒是你一直扯到return出去第二次进入的问题,第二次进来当然是wait中间的case!我懂!! 我可没说切出去,我说的是workb和a走完了后,重新开始wait的时候!!!是你自己不理解我的意思扯远了!!!
花花世界大水牛
发表于 2014-7-8 16:51:16
这么好的帖必须顶到一千楼啊,smset大神,请问使用这个调度器之后还能用switch case 语句吗?
chengsong
发表于 2014-7-15 10:19:25
mark,学习学习!
imjacob
发表于 2014-7-15 15:22:07
1000楼,学习
imjacob
发表于 2014-7-15 16:31:29
楼主,有个地方不明白,想请教,你的WaitX 预编译宏 中return了,后面的东西(case __LINE__:)不是执行不到了吗,那还有什么意义呢?
残忆视觉
发表于 2014-7-16 09:09:32
这个不大懂啊,干嘛的
gyd0317
发表于 2014-7-16 10:40:45
看到个简单易用的os诞生
NC_Zyang
发表于 2014-7-16 11:59:53
smset 发表于 2012-12-6 23:58
发布一个更新版本哈,在资源节省度上有所优化:
楼主,相请教下你这个问题,你这行代码是这样的:
#define WaitX(tickets) {lc=__LINE__; timers=tickets;} return ; case __LINE__:
我想问下你这里都return了,那case __LINE__来做什么用呢?而且感觉也不会执行,如果不执行写在这里又做什么呢?
mute
发表于 2014-7-16 12:23:26
NC_Zyang 发表于 2014-7-16 11:59
楼主,相请教下你这个问题,你这行代码是这样的:
#define WaitX(tickets) {lc=__LINE__; timers ...
每个任务的开头都有 _SS,里面就是switch。
碰到了wait,就return了tick回去。
等tick时间完了后,main就会再次进入该任务,自然就从SS直接switch跳到case LINE了,跳过wait里的return。
整个过程就是延迟tick时间。
mculjf
发表于 2014-7-16 12:53:20
学习下,看看能不能用到{:loveliness:}
iwqt1983
发表于 2014-7-16 13:03:41
写的真心不错,有深度的
imjacob
发表于 2014-7-16 15:15:59
dr2001 发表于 2012-12-18 10:14
还没有看你贴出的代码,所以不知道是否是丢自动变量导致的问题,但是对你提出的疑问进行简要的说明。
呃 ...
你好,第一次听说动态变量这个词,想说下我的理解,是不是这样。动态变量 包含动态局部变量,动态全局变量。
动态局部变量 是 函数内的局部变量,动态全局变量是 malloc,freee那种。谢谢
zcan
发表于 2014-7-17 10:42:10
1000楼 !
int main{}
{
while(1);
}
zcan
发表于 2014-7-17 10:44:17
int
[ code]
zcan
发表于 2014-7-17 10:44:39
xx
eddia2012
发表于 2014-7-17 11:21:44
{:smile:}顶楼主到1000楼,加油!
Kwangsi
发表于 2014-7-17 14:36:19
有人成功用到实际的案子中吗
zcan
发表于 2014-7-17 14:56:13
要插入的代码片断
[/ code] //实际使用时去掉方括号里的那个空格
梦中花雨
发表于 2014-7-17 15:00:19
我只能默默的膜拜
ppdd
发表于 2014-7-17 15:04:38
期待综合应用,出个12864+DS1302+18b20+串口配置参数的应用就好了!
mdcao
发表于 2014-7-18 15:02:41
离1000楼越来越近了,楼主可以提前做好准备,{:smile:}
香樟树
发表于 2014-7-22 09:23:59
新人,学习中
yanpenghao
发表于 2014-7-22 10:14:56
太赞啦,mark先,楼主辛苦
frankvos
发表于 2014-7-24 18:21:58
研究ing,感谢楼主分享
freshuman
发表于 2014-7-25 02:57:12
深度,众人叠加才更深。
frankvos
发表于 2014-7-25 10:29:42
本帖最后由 frankvos 于 2014-7-25 16:53 编辑
kentzhtao_top 发表于 2012-11-29 15:18
知道怎么回事了case 语句用法还可以这样 晕啊
voidtask2()
我本来也是这个地方看不明白,非常感谢分享,也为楼主的思路鼓掌
mdcao
发表于 2014-7-28 11:28:25
路过,在顶一帖!
vvi
发表于 2014-7-28 20:26:19
顶到1000楼
corn0329
发表于 2014-7-29 08:32:48
现在还看不懂不要紧,收藏了能看懂再来看
哼嘿哈嘿哈
发表于 2014-7-31 20:57:35
太精妙了,大赞!
four_zhg
发表于 2014-7-31 22:05:18
再顶一下,加一块砖,1000楼还差几楼,后面的跟上
xiepan2010
发表于 2014-7-31 22:50:35
哈哈快到1000楼了 希望楼主记得1000楼之约
fgdzypf
发表于 2014-8-1 07:54:42
再顶一下。。。。
litguy
发表于 2014-8-1 09:31:02
看样子需要我帮你顶到1000楼了
xy-mcu
发表于 2014-8-1 11:01:19
我已经用了,而且出了几百台了。
同时帮老朋友顶贴。
mute
发表于 2014-8-1 12:18:22
可否给点应用的例子? 另外求keil里如何将函数强制设置成不内联的模式。
内联是__inline,不内联不知道是什么
ppdd
发表于 2014-8-1 12:31:11
再顶顶!!
ppdd
发表于 2014-8-1 12:32:03
本帖最后由 ppdd 于 2014-8-1 12:33 编辑
999楼到了!!
ppdd
发表于 2014-8-1 12:32:26
1000楼到了!!
mdcao
发表于 2014-8-1 12:33:43
没抢到,1001
haowei029
发表于 2014-8-1 15:29:04
楼主该兑现承诺 ——> 写个详细教程了!
imjacob
发表于 2014-8-3 16:35:29
本帖最后由 imjacob 于 2014-8-3 16:37 编辑
smset 发表于 2012-12-18 18:29
优化无止境!呵呵,330楼看似不能再优化了,但我再尝试做一次优化:
敬请评测该版本,看是否还能优化:在k ...
东西很好,用起来挺爽的。但是因为楼主很强调 资源的极其省用,所以对移植起来会碰到点问题。譬如2楼的这个代码,delay(255)以上就会有问题。这和 UpdateTimers 函数中 timers!=255这句话有关。当然其实这些都是小问题。关键学习的是楼主的思路。 但无论如何,通用性还是非常重要的,特别是对初学者,拿来想方便移植的朋友。所以,建议楼主写一个 不强调资源,能在现在32位处理器上用起来很爽的版本。那岂不是更好?
ak4s7
发表于 2014-8-5 17:20:32
建议加上邮箱
信号量、邮箱通过宏选择可要或不要达到省资源的目的
队列就没必要了,耗ram。想要的话也可以用邮箱来做
deluyang
发表于 2014-8-5 17:43:55
switch的default用法而已,楼主不必要写的这么神秘晦涩
我说的对吧!!
gy54321
发表于 2014-8-7 02:43:57
smset 发表于 2014-3-27 19:13
{:handshake:} {:handshake:}
bridge_chen_26
发表于 2014-8-8 10:55:12
haowei029 发表于 2014-8-1 15:29
楼主该兑现承诺 ——> 写个详细教程了!
是啊,说话算数哦,{:tongue:}
dqt12
发表于 2014-8-8 16:23:52
等教程啊,新手真是越看越迷糊!
页:
1
2
3
4
5
6
7
8
9
[10]
11
12
13