C4SX: taskswitch library
Attached are updated libraries. The library Task.h allows to run
up to 5 tasks in the background on a regular interval. These tasks exexute outside the
interrupt routine with interrupts enabled. When a task subroutine is executed,
the mainline code is not executed, but interrupt code continues.
You can compare it to the BASIC feature ON TIMER GOSUB.
The task subroutine must return to allow the mainline code to continue.
The test program declares 5 tasks (simply updating a memory location)
that run continuesly while the mainloop code does nothing (while(1) [noparse];)[/noparse]
You can run it directly with sxsim. Uncheck 'run isr' and uncheck 'check reti'
If you set a breakpoint at the end (the while(1) loop) and then hit run
the initialization is done fast. Then remove the breakpoint and hit walk.
Observe the memory locations 0x50-0x54 and 0x70, as these are updated
by the tasks.
cc1b throws a warning about Task.h line 436. You can ignore that.
Since the test file is for sx28, make sure to·comment out any CLRB 4.FSR_7
in the generated .src file (this bug is fixed in the next cc1b release).
The attached .src has the CLRB 4.FSR_7 already commented out.
To make it work I had to use
#pragma unlockISR
so I could place the interrupt routine anywhere.
At origin 0, I inserted
/*<?asm
······· JMP·· @iServer
······· JMP·· @TaskSchedule
?>*/
so there is a fixed address (0x002) for calling TaskSchedule.
cc1b does not allow us to use function names as constants (which it could because
function names are labels). The workaround is not too bad.
regards peter
up to 5 tasks in the background on a regular interval. These tasks exexute outside the
interrupt routine with interrupts enabled. When a task subroutine is executed,
the mainline code is not executed, but interrupt code continues.
You can compare it to the BASIC feature ON TIMER GOSUB.
The task subroutine must return to allow the mainline code to continue.
The test program declares 5 tasks (simply updating a memory location)
that run continuesly while the mainloop code does nothing (while(1) [noparse];)[/noparse]
You can run it directly with sxsim. Uncheck 'run isr' and uncheck 'check reti'
If you set a breakpoint at the end (the while(1) loop) and then hit run
the initialization is done fast. Then remove the breakpoint and hit walk.
Observe the memory locations 0x50-0x54 and 0x70, as these are updated
by the tasks.
cc1b throws a warning about Task.h line 436. You can ignore that.
Since the test file is for sx28, make sure to·comment out any CLRB 4.FSR_7
in the generated .src file (this bug is fixed in the next cc1b release).
The attached .src has the CLRB 4.FSR_7 already commented out.
To make it work I had to use
#pragma unlockISR
so I could place the interrupt routine anywhere.
At origin 0, I inserted
/*<?asm
······· JMP·· @iServer
······· JMP·· @TaskSchedule
?>*/
so there is a fixed address (0x002) for calling TaskSchedule.
cc1b does not allow us to use function names as constants (which it could because
function names are labels). The workaround is not too bad.
regards peter
Comments
Because the taskswitch modifies M, this needs to be saved during interrupt.
I aliased a register _IsrMode to DDRDCOPY (@0xF8) which is valid because
the SX48/52 automatically save M during interrupts.
I added·conditional statements to the interrupt routine,
to save and restore M in case of·SX18/20/28.
regards peter
I converted my running SX/B beta test program to cc1b.
This uses the taskswitch library on a SX48 with a simple
RS232 interface on pins RA.1 and RA.2
/*
·* CONNECTION diagram
·*
·*································ | +5V
·*······························· /
·*· RA.1
[noparse][[/noparse]4k7]
|· PNP
·*······························· \
·*······························· +
SOUT···
>··· To PC comport receive
·*····························· [noparse][[/noparse]4k7]
·*······························· |
·*· RA.2
[noparse][[/noparse]33k]
+
SIN···
<··· From PC comport transmit
·*/
I programmed a serial receive task, serial transmit task, enqueu task, dequeue task and rtc task.
So the serial in and serial out are both buffered (queues). Note that these uart routines are not
the installable vpUart virtual peripherals, but simple tasks (only 1200baud 8N1).
They show the tasks are pretty deterministic as long as you follow some rules.
The attached SX_TaskSwitch_Diagram.pdf visualizes these rules.
I also attached a picture of a debug window, showing the serial in/out.
The debug window used is the Basic Stamp debug window that lets you filter
out the hardware echoes, which are due to the above interface.
The test program only uses the odd rambanks which means you can simply
change the device to sx28 and then the program should also run. (not tested)
Next step is to combine the tasks with the vpUarts to have buffered serial I/O
for fully featured uarts (higher baudrates, 7/8 databits, parity none/odd/even).
regards peter
Post Edited (Peter Verkaik) : 8/29/2007 8:04:00 AM GMT
In looking through the code, I was curious about the use of the "@[noparse][[/noparse]I]address[noparse][[/noparse]/i]" codes when defining memory variables. For example:
I can see the need for the first one, although it makes more sense to me if there was a pragma so that the code would be more like regular C, but the second one really seems like it should be unnecessary. Doesn't the compiler know that the next free space is after the prior one?
It's a minor point, I was just curious. What is important is that C programs that actually work and are readable to C programmers (if not exactly pure C) can be poured into an SX.
I hope someone is collecting these libraries, sample programs, and so on into one package for others to download and use.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
cc1b gives proirity to variables located at a fixed address (eg. with @),
then to local variables, and finally to global variables.
You can imagine that when omitting the second @, that space would be used
for locals, meaning serialout[noparse][[/noparse]12] has to be moved (which might work or not,
depends on how fragmented memory is). For clarity I choose to locate it
at a fixed address too, although I could have used a #pragma.
regards peter
Could you post the SX/B program that you converted to create the task_serial_test.c file ?
Just to give the others a taste of how the task switching will work in SX/B.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The first rule to being successful is "Learn from your mistakes",
The second rule is "Be willing to make mistakes"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.hittconsulting.com
·
Here it is.
As you will see, it is almost a 1-to-1 translation.
The only thing I changed is the 4th parameter from TASKS SET.
I removed it from the definition and set the task start times for ALL slots
during TaskInit(). This 'starttime' is fully maintained by the taskswitch code
and it is really not necessary for the task to manipulate that.
regards peter
The CC1B author·has posted a new release, release 0.7.· I have tested it against ALL·known bugs and against all of my test programs.· It is looking VERY·good.· So far, I have found only one small loose end (having to do with a new feature: commenting out some of the unneeded EQU statements -- more on this later....).
This CC1B version includes a fix for the PAGE bug you hit.
Also, it has a new ' #pragma asmDir: <whatever> ' capability to replace the /*<?asm· <whatever? ?>*/ we have been using.· I've attached a sample program that uses this new feature.
Could you try this new CC1B?· Feedback very welcome.
If this holds up, and it is currently looking very good, I'll release a new C4SX ASAP.· This new C4SX will contain any and all information I can find about the new CC1B release (new features, etc.).· This new pragma option·is the main new feature -- the others are aimed at removing the need for the CC1B2SX converter.
Please let me know that you think.· I can't make any of the known CC1B·bugs, from the current CC1B (which is 0.6I),·occur.....
Thanks,
RW Senser
This is great. The missing bank instruction that I detected·in RomCopy() is resolved.
I will update the memory.h library.
The #pragma asmDir:
is great. It also allows us to write normal sasm assembly, although that is hardly
necessary. You can use C statements that compile 1-to-1 into assembly.
I checked if a #pragma asmDir: would be executed if it is placed in the body
of a library function that is not used. It does not execute which is good.
The /*<?asm - ?>*/ blocks are always executed by your conversion, so if such a block exists
in a library function that is not used, it is consuming code space.
regards peter