大叶子
发表于 2025-4-27 08:42:55
TASK_Test.hex文件。文件时间显示,没有同时编译成功呢
这算问题吗?
是不能更改内容了吗?
Rebuild target 'Target 1'
User command #1: .\Auto_Keil.exe
compiling main.c...
compiling set_task.c...
compiling set_io.c...
compiling set_timer.c...
linking...
L251 LINKER/LOCATER V4.66.93.0 - SN: Eval Version
COPYRIGHT ARM Germany GmbH 1995 - 2018
@.\HEXFIL~1\TASK_T~1.LNP ".\Hex File\main.obj",
".\AI8051U_32_MDU32.LIB",
".\AI8051U_32_TFPU.LIB",
".\Hex File\set_task.obj",
".\Hex File\set_io.obj",
".\Hex File\set_timer.obj"
TO ".\Hex File\TASK_Test"
PRINT(".\Listings\TASK_Test.map") CASE DISABLEWARNING (16,57,30)
REMOVEUNUSED
CLASSES (EDATA (0x0-0x7FF),
HDATA (0x0-0x7FF))
******************************************************************************
* RESTRICTED VERSION WITH 0800H BYTE CODE SIZE LIMIT; USED: 122EH BYTE (227%) *
******************************************************************************
Program Size: data=8.0 edata+hdata=452 xdata=0 const=191 code=6811
*** ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED
LIMIT: 0800H BYTES
Target not created.
Build Time Elapsed:00:00:01
angmall
发表于 2025-4-27 09:16:45
大叶子 发表于 2025-4-27 08:42
TASK_Test.hex文件。文件时间显示,没有同时编译成功呢
这算问题吗?
是不能更改内容了吗?
你的Keil C251 还没有注册。
Keil软件要注册才行。不注册只能编译小于2KByte。
和谐一下,找下注册机
大叶子
发表于 2025-4-28 08:55:07
我也奇怪,原先注册过了,一直用好好的,原来,
C251,过期了。
已经重新注册。
感谢,提醒!
明月清风
发表于 2025-5-6 14:37:39
例程是在C251下运行的8051U吗?
王昱顺
发表于 2025-5-6 14:58:58
明月清风 发表于 2025-5-6 14:37
例程是在C251下运行的8051U吗?
是的哩, 实际上只要是c语言环境都可以使用
Yang.Lian
发表于 2025-5-19 18:09:36
Protothreads
urada
发表于 2025-5-29 10:31:13
也可以看看这个: https://dunkels.com/adam/pt/, 原理是一样的, 都是无堆栈协程, 这个通用库功能多一点
dashuai
发表于 2025-5-30 15:55:03
可以的
fanxsp
发表于 2025-6-6 11:14:57
hhh402 发表于 2025-4-24 16:05
翻译了楼主首页的协程2:
_this_task=2;
if(task_num
这段代码确实没问题,有点令人意外,case 是可以放在 switch 中的代码块里面的。
Duff's device
The famous "Duff's device" in C makes use of the fact that a `case` statement is still legal within a sub-block of its matching `switch` statement. Tom Duff used this for an optimised output loop:
switch (count % 8)
{
case 0: do {*to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while ((count -= 8) > 0);
}
```
We can put it to a slightly different use in the coroutine trick. Instead of using a `switch` statement to decide which `goto` statement to execute, we can use the `switch` statement to perform the jump itself:
int function(void)
{
static int i, state = 0;
switch (state)
{
case 0: /* start of function */
for (i = 0; i < 10; i++)
{
state = 1; /* so we will come back to "case 1" */
return i;
case 1:; /* resume control straight after the return */
}
}
}
Now this is looking promising. All we have to do now is construct a few well chosen macros, and we can hide the gory details in something plausible-looking:
```
#define crBegin static int state=0; switch(state) { case 0:
#define crReturn(i,x) do { state=i; return x; case i:; } while (0)
#define crFinish }
int function(void)
{
static int i;
crBegin;
for (i = 0; i < 10; i++)crReturn(1, i);
crFinish;
}
```
(note the use of `do ... while(0)` to ensure that `crReturn` does not need braces around it when it comes directly between `if` and `else`)
This is almost exactly what we wanted. We can use `crReturn` to return from the function in such a way that control at the next call resumes just after the return. Of course we must obey some ground rules (surround the function body with `crBegin` and `crFinish`; declare all local variables `static` if they need to be preserved across a `crReturn`; *never* put a `crReturn` within an explicit `switch` statement); but those do not limit us very much.
The only snag remaining is the first parameter to `crReturn`. Just as when we invented a new label in the previous section we had to avoid it colliding with existing label names, now we must ensure all our state parameters to `crReturn` are different. The consequences will be fairly benign - the compiler will catch it and not let it do horrible things at run time - but we still need to avoid doing it.
Even this can be solved. ANSI C provides the special macro name `__LINE__`, which expands to the current source line number. So we can rewrite `crReturn` as
```
#define crReturn(x) do { state=__LINE__; return x; \
case __LINE__:; } while (0)
```
and then we no longer have to worry about those state parameters at all, provided we obey a fourth ground rule (never put two `crReturn` statements on the same line).