EmbeddedRelated.com
Forums

Memory Partitioning Problems

Started by Karl-Heinz Rossmann April 12, 2006
Hi all,

I have an embedded system which is required to have memory partitioning
due to safety reasons. Unfortunately there are sporadically bus address
error exceptions. I am using a Motorola M68376 as a
foreground/background system but I think it's no problem of the
microprocessor.
There are three asynchronous interrupt sources. Each of them has a
different ISR assigned. The principle structure of each ISR is as
follows:

void ISR_x(void)
{
    PartCtrl(UNPROTECT_MEMORY);
    Foo();
    PartCtrl(PROTECT_MEMORY);
}

The function PartCtrl() looks like:

unsigned long UnprotectCnt = 0; /* mapped to a memory partition which
is not affected by the memory protect mechanism */
void PartCtrl(char Flag)
{
    switch (Flag)
    {
        case PROTECT_MEMORY:
            if (UnprotectCnt > 0)
            {
                UnprotectCnt--;
            }
            if (UnprotectCnt == 0)
            {
                SetMemoryToReadOnly();
            }
            break;

        case UNPROTECT_MEMORY:
            UnprotectCnt++;
            if (UnprotectCnt == 1)
            {
                SetMemoryToReadAndWrite();
            }
            break;
    }
}

What is wrong with this code?
I tried to disable interrupts while beeing in the function PartCtrl()
but this is no solution because the software has to recognize all
interrupts otherwise different problems arise.

Thanks for your help.

In comp.arch.embedded,
Karl-Heinz Rossmann <karl-heinz.rossmann@liebherr.com> wrote:
> Hi all, > > I have an embedded system which is required to have memory partitioning > due to safety reasons. Unfortunately there are sporadically bus address > error exceptions. I am using a Motorola M68376 as a > foreground/background system but I think it's no problem of the > microprocessor. > There are three asynchronous interrupt sources. Each of them has a > different ISR assigned. The principle structure of each ISR is as > follows: > > void ISR_x(void) > { > PartCtrl(UNPROTECT_MEMORY); > Foo(); > PartCtrl(PROTECT_MEMORY); > } > > The function PartCtrl() looks like: > > unsigned long UnprotectCnt = 0; /* mapped to a memory partition which > is not affected by the memory protect mechanism */ > void PartCtrl(char Flag) > { > switch (Flag) > { > case PROTECT_MEMORY: > if (UnprotectCnt > 0) > { > UnprotectCnt--; > } > if (UnprotectCnt == 0) > { > SetMemoryToReadOnly(); > } > break; > > case UNPROTECT_MEMORY: > UnprotectCnt++; > if (UnprotectCnt == 1) > { > SetMemoryToReadAndWrite(); > } > break; > } > } > > What is wrong with this code? > I tried to disable interrupts while beeing in the function PartCtrl() > but this is no solution because the software has to recognize all > interrupts otherwise different problems arise. >
But did disabling the interrupts in PartCtrl() solve your problem? The problem seems to be that your increment/decrement plus tests are not atomic operations. Disabling interrupts will solve this. But why can't you disable the interrupts for even a short while? This will normally ( but I am not familiar with your sustem) not result in loosing interrupts, it just delays them a little. -- Stef (remove caps, dashes and .invalid from e-mail address to reply by mail)
Stef schrieb:

> In comp.arch.embedded, > Karl-Heinz Rossmann <karl-heinz.rossmann@liebherr.com> wrote: > > Hi all, > > > > I have an embedded system which is required to have memory partitioning > > due to safety reasons. Unfortunately there are sporadically bus address > > error exceptions. I am using a Motorola M68376 as a > > foreground/background system but I think it's no problem of the > > microprocessor. > > There are three asynchronous interrupt sources. Each of them has a > > different ISR assigned. The principle structure of each ISR is as > > follows: > > > > void ISR_x(void) > > { > > PartCtrl(UNPROTECT_MEMORY); > > Foo(); > > PartCtrl(PROTECT_MEMORY); > > } > > > > The function PartCtrl() looks like: > > > > unsigned long UnprotectCnt = 0; /* mapped to a memory partition which > > is not affected by the memory protect mechanism */ > > void PartCtrl(char Flag) > > { > > switch (Flag) > > { > > case PROTECT_MEMORY: > > if (UnprotectCnt > 0) > > { > > UnprotectCnt--; > > } > > if (UnprotectCnt == 0) > > { > > SetMemoryToReadOnly(); > > } > > break; > > > > case UNPROTECT_MEMORY: > > UnprotectCnt++; > > if (UnprotectCnt == 1) > > { > > SetMemoryToReadAndWrite(); > > } > > break; > > } > > } > > > > What is wrong with this code? > > I tried to disable interrupts while beeing in the function PartCtrl() > > but this is no solution because the software has to recognize all > > interrupts otherwise different problems arise. > > > But did disabling the interrupts in PartCtrl() solve your problem?
Disabling did solve the problem with the partitioning but then I had a problem with counters of the microprocessor because some interrupts where not recognized.
> The problem seems to be that your increment/decrement plus tests are not > atomic operations. Disabling interrupts will solve this. But why can't > you disable the interrupts for even a short while? This will normally ( > but I am not familiar with your sustem) not result in loosing interrupts, > it just delays them a little.
The user manual of the microcontroller says that the occurence of interrupts lower or equal to the IP mask are not recognized.
> > -- > Stef (remove caps, dashes and .invalid from e-mail address to reply by mail)
Do you have any other idea. Is there any "standard" algorith for tasks like this?
In comp.arch.embedded,
Karl-Heinz Rossmann <karl-heinz.rossmann@liebherr.com> wrote:
> Stef schrieb: >> > >> But did disabling the interrupts in PartCtrl() solve your problem? > > Disabling did solve the problem with the partitioning but then I had a > problem with counters of the microprocessor because some interrupts > where not recognized. > >> The problem seems to be that your increment/decrement plus tests are not >> atomic operations. Disabling interrupts will solve this. But why can't >> you disable the interrupts for even a short while? This will normally ( >> but I am not familiar with your sustem) not result in loosing interrupts, >> it just delays them a little. > > The user manual of the microcontroller says that the occurence of > interrupts lower or equal to the IP mask are not recognized. >
Not immediately, but they will be recognised as soon as the higer priority interrupt is finished or this is a very weird processor indeed. But how fast are your interrupts coming and can you keep up?
> > Do you have any other idea. Is there any "standard" algorith for tasks > like this? >
It's been a while since I used a MC683xx type processor. IIRC they can output the current function code. So if you only need (write) access to the memory in supervisor mode, you could do the protection in hardware. You may also want to do something with the bus monitor so that you will get an exception when false accesses are attempted. -- Stef (remove caps, dashes and .invalid from e-mail address to reply by mail)
Karl-Heinz Rossmann wrote:
> Hi all, > > I have an embedded system which is required to have memory partitioning > due to safety reasons. Unfortunately there are sporadically bus address > error exceptions.
The part about bus address error exceptiions doesn't sound good. My concern here is that you may be attempting to mask a hardware problem with a software bandaid. Have you investigated the nature and cause of the errors and are you satisfied that there isn't an underlying problem that can and will bite you?
Stef schrieb:

> In comp.arch.embedded, > Karl-Heinz Rossmann <karl-heinz.rossmann@liebherr.com> wrote: > > Stef schrieb: > >> > > >> But did disabling the interrupts in PartCtrl() solve your problem? > > > > Disabling did solve the problem with the partitioning but then I had a > > problem with counters of the microprocessor because some interrupts > > where not recognized. > > > >> The problem seems to be that your increment/decrement plus tests are not > >> atomic operations. Disabling interrupts will solve this. But why can't > >> you disable the interrupts for even a short while? This will normally ( > >> but I am not familiar with your sustem) not result in loosing interrupts, > >> it just delays them a little. > > > > The user manual of the microcontroller says that the occurence of > > interrupts lower or equal to the IP mask are not recognized. > > > Not immediately, but they will be recognised as soon as the higer > priority interrupt is finished or this is a very weird processor indeed. > > But how fast are your interrupts coming and can you keep up? >
The one which is problematic comes rather slow (30 ms) but the corresponding ISR has to catch a timer value. So if I miss one interrupt the timer value is lost. The timer value of the next interrupt is to far away from the missed one. Furthermore I am not able to reconstruct the missing timer value.
> > > > Do you have any other idea. Is there any "standard" algorith for tasks > > like this? > > > It's been a while since I used a MC683xx type processor. IIRC they can > output the current function code. So if you only need (write) access to > the memory in supervisor mode, you could do the protection in hardware. > You may also want to do something with the bus monitor so that you will > get an exception when false accesses are attempted. >
Unfortunately the function code pins are already used as chip selects.
> -- > Stef (remove caps, dashes and .invalid from e-mail address to reply by mail)
Noway2 schrieb:

> Karl-Heinz Rossmann wrote: > > Hi all, > > > > I have an embedded system which is required to have memory partitioning > > due to safety reasons. Unfortunately there are sporadically bus address > > error exceptions. > > The part about bus address error exceptiions doesn't sound good. My > concern here is that you may be attempting to mask a hardware problem > with a software bandaid. Have you investigated the nature and cause of > the errors and are you satisfied that there isn't an underlying problem > that can and will bite you?
I have reinvestigated the cause of the problem and suddenly I saw the solution: I have to the the UnprotectCnt for beeing greater equal to 1: case UNPROTECT_MEMORY: UnprotectCnt++; if (UnprotectCnt >= 1) { SetMemoryToReadAndWrite(); } break; The reason is that increasing the UnprotectCnt and changing memory access can be interrupted it's possible for a different ISR to unprotect the memory too. If this happens with the old code the changing of memory access fails. Thanks to all for your help!
"Karl-Heinz Rossmann" <karl-heinz.rossmann@liebherr.com> wrote in message 
news:1144846745.392795.248660@i40g2000cwc.googlegroups.com...
> Stef schrieb: > >> But how fast are your interrupts coming and can you keep up? >> > > The one which is problematic comes rather slow (30 ms) but the > corresponding ISR has to catch a timer value. So if I miss one > interrupt the timer value is lost. The timer value of the next > interrupt is to far away from the missed one. Furthermore I am not able > to reconstruct the missing timer value.
You might have already considered and discounted this, but in situations where an interrupt has to catch a timer value, you can (usually) make it latency-independent by using a capture register - i.e. use the input transition to capture the timer value to an associated register *as well as* triggering an interrupt. So long as you service the interrupt before the counter rolls over, you're in business. (Note: this does presuppose that you're using a timer capture pin as an interrupt, rather than a GP interrupt.) Steve http://www.fivetrees.com
"Karl-Heinz Rossmann" <karl-heinz.rossmann@liebherr.com> wrote in message 
news:1144849594.462292.194570@j33g2000cwa.googlegroups.com...
> > I have reinvestigated the cause of the problem and suddenly I saw the > solution: > I have to the the UnprotectCnt for beeing greater equal to 1: > > case UNPROTECT_MEMORY: > UnprotectCnt++; > if (UnprotectCnt >= 1) > { > SetMemoryToReadAndWrite(); > } > break; > > The reason is that increasing the UnprotectCnt and changing memory > access can be interrupted it's possible for a different ISR to > unprotect the memory too. If this happens with the old code the > changing of memory access fails.
Just to add some paranoia: make sure that the increment/decrement instructions cannot be interrupted somewhere in the middle. There may still be a minute chance of messing up the actual value of the UnprotectCnt variable and ending up with corrupt values. Andrew