From: Dafni & R. B. <da...@ho...> - 2000-11-10 05:46:27
|
Hi, I ported uCOS to 8051 with a different compiler and to save the task context looks like this: ; Save current task context ; ; PCL, PCH have already been pushed by lcall/interrupt ; push psw push acc push b push dpl push dph ; push ar0 push ar1 push ar2 push ar3 push ar4 push ar5 push ar6 push ar7 ; ; -------------------------------- ; Save CC51 Virtual Stack Pointer ; push __SP push __SP+1 ; -------------------------------- ; push sp For SDCC there should be _SPX instead of __SP. (I don't know if ASXXX supports arx), which takes care about the register banks. It takes the register of the current register bank. I think that the _SPX is still not working 100% (need to make some tests). Besides this I need a decent debugging environment (only NoICE seems to work at this point), which means I need to design some hardware. For NoICE I need to make a tool (or modify SDCC) to insert some NOPs when appropriate to be able to set a breakpoint wherever I want and to single step. Besides this the libraries which come with SDCC are not ANSI C compatible libraries, which needs to be fixed to reuse code. A testsuite is needed therefor. There is (or was) also a bug in SDCC which does not allow a function to have to same name as a variable. So before I will do something about the uCOS porting these issues have to be resolved. I am willing to help you. regards, Robert > -----Original Message----- > From: sdc...@li... > [mailto:sdc...@li...]On Behalf Of J.J. van der > Sande > Sent: Freitag, 10. November 2000 01:47 > To: sdc...@li... > Subject: [Sdcc-user] task switching > > > Hi, > > Some time ago I there was discussion about porting uCOS. Unfortunately, > judging by the radio silence, the efforts have stopped. However, a small > real-time operating system that is suitable for microcontrollers is > extremely useful when developing medium sized and large sized projects. > > I am not familiar with uCOS, however, I have years of experience with > VxWorks (which is not available for 8-bit microcontrollers, unfortu- > nately) and have designed a small real-time operating system. Nothing > fancy, just a bare bones RTOS, since space is limited in a micro- > controller: > > * Priority-based multitasking > The current design does *not* include preemption, i.e. switching > between tasks can occur only when: > 1. a task tries to get a semaphore that is empty and thus blocks > 2. the waiting for an empty semaphore times out > 3. a task gives back a semaphore that another (higher priority) > task was waiting for > > * Semaphores > Since the RTOS does not preempt, all tasks need to synchronise using > semaphores. > > * System clock > Required to generate interrupts at regular intervals in order to > time out a wait-action on an empty semaphore and possibly switch > between tasks. > > * The usual :-) > Serial I/O, dynamic memory allocation, etc. > > I completed the design and have now started to implement it. For now, > I work on the project alone, but when I have made some progress I will > post the design, documentation and source-code to allow others to beta- > test it. I will minimise the amount of inline assembly and isolate > device-specific parts in separate source files, in order to simplify > porting the RTOS to other microcontrollers, such as AVR or Z80. > > However, I have problems determining what information must be saved in a > MCS-51 system when switching between tasks. Besides the usual registers > psw, a, b, and dptr, one also needs to save the stack(s) and the regi- > sterbank(s). That is were I get lost between all the possible compiler > options of SDCC. I have thoroughly studied the (somewhat outdated?) > manual of SDCC and the output generated when compiling small test > programs. Could someone please confirm the following observations: > > 1. In order for programs to be multithreaded-safe, all code needs to be > compiled using the '--stack-auto' option. Both memory models will > result in safe code. > > 2. In the startup code SDCC uses the variable '__stack__start' to > initialise stack pointer 'sp'. This variable always (?) points to the > byte preceeding the stack, even when compiler options such as > --stack-after-data are selected. In other words, the 'sp' register > and all idata bytes at addresses '__stack_start+1' ... 'sp' need to > be saved. > > 3. Reentrant functions (that is, *all* functions when using '--stack- > auto') will use variable '_bp', which therefore needs to be saved. > > 4. Is there a variable I can use to determine which registerbanks have > been used? I know SDCC is aware of this info, since it needs this to > determine where to put the data during linking If this variable is > not available, would it be possible for someone to add this to the > SDCC compiler? > > 5. If the '--xstack' option is used, the '_spx' variable needs to be > saved. I have noticed that SDCC sometimes stores things "ahead" of > the '_spx' stack pointer, therefore it is not safe to only save the > bytes in the xdata area at addresses 0...'_spx'. When studying some > test programs, I encountered for example the following output: > > mov r0,_spx > mov a,r2 > movx @r0,a > inc r0 > mov a,r3 > movx @r0,a > inc r0 > mov a,r4 > movx @r0,a > inc r0 > mov a,r5 > movx @r0,a > inc r0 > mov _spx,r0 > > Is there a maximum number of bytes (presumably 4) that SDCC will run > ahead of '_spx'? If not, I would be forced to save all 256 bytes in > xdata at addresses 0000..00FF which results in a severe performance > penalty, thus rendering the '--xstack' option useless in combination > with my RTOS. > > I'm worried about the overhead of a task switch. On a 32-bit system it > is simply a matter of saving all registers and moving the stack pointer > to a different stack. However, on a small MCS-51 device, we can't move > to a different stack. We have to move the stack *itself* when task- > switching! Don't forget that a task switch also involves restoring the > state of another task, thus doubling the required amount of time. Even > if you apply an advanced scheme (such as task descriptor "cycling", > where you don't save the state into one descriptor and restore the state > from another, but instead XCH the state with a descriptor and only > rename the task descriptors), I estimate that a task switch will take at > least 200 cpu cycles (depending on the amount of data on the stack). > > Thank you for your time, if you have read this rather large mail this > far! Hopefully someone can confirm my observations or point out things I > have misunderstood. > > > Kind regards, > > Joris van der Sande > vd...@pu... > > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > http://lists.sourceforge.net/mailman/listinfo/sdcc-user |