This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Can't build with conf_tny.a51 in project

I get the error

CONF_TNY.A51(1): error A43: RESPECIFIED PRIMARY CONTROL

for the 1st line the file which is
$DEBUGPUBLICS


TIA
Andy

Parents
  • Unfortuntately all my tasks never exits and each task does call a set of shared functions (although never at the same time). What is the proper way to implement tasks if say a task needs to be blocked at the middle of its excution to allow other tasks to run, but all tasks share a set of functions? (maybe that's a bad practice anyway..)
    I'm thinking if I can somehow fix the call tree so that it looks like this

    Init --> Task1CallTree --> Task2CallTree ... etc..

    Then it might work? Sorta like call by stack? Is there a way to fix the tree that way?

    Andy

Reply
  • Unfortuntately all my tasks never exits and each task does call a set of shared functions (although never at the same time). What is the proper way to implement tasks if say a task needs to be blocked at the middle of its excution to allow other tasks to run, but all tasks share a set of functions? (maybe that's a bad practice anyway..)
    I'm thinking if I can somehow fix the call tree so that it looks like this

    Init --> Task1CallTree --> Task2CallTree ... etc..

    Then it might work? Sorta like call by stack? Is there a way to fix the tree that way?

    Andy

Children
  • There is no proper way of doing that, at the heart of it. For the context of C51, what you're trying to do is, indeed, rather bad practice.

    You'ld have to make all "shared" functions reentrant, but that could cause such a large performance hit that it may blow up your whole project.

    I suggest you try hard to find another way of doing that.

  • If your tasks need to yield the processor in the middle of their execution -- that is, when you're some way down the stack, rather than at the top level of the task -- then you will need independent stacks for each task. The fact that you don't actually preempt might save you from having to store registers in your task context, but you still need to preserve the state of execution represented by the task stack. You'll still want each task to be the root of its own call tree.

    Assuming we're trying to avoid making the routines re-entrant, we're down to some ugly choices. You could say "programmer knows best", and just ignore the warning since you know the functions in question can't be called reentrantly. Unfortunately, I don't think you can suppress the warning on a function-by-function basis.

    If the functions are small, and naturally reentrant (that is, they require no auto variables or temporaries outside of registers, and all the parameters fit into registers for the call), then declaring them reentrant costs you nothing.

    You could also do the surgery on the call tree in reverse. That is, pull the function calls out of their proper place and assign them to one top level call (main, or C_INITSEG). They're not really called from there, but this will cause the compiler to generate only one set of addresses for locals and parameters. This bit of hackery will of course be completely mysterious six months down the road when you change the code and it starts acting flaky.

    Another way to achieve the same goal would be to re-architect the program so that the shared functions are their own tasks, little servers that do a job at the request of other tasks. Depending on your existing architecture, this might be a lot of work, and probably only worthwhile for major functions, but at least would have the benefit of making it explicit in the code that these functions cannot be called reentrantly, both the to the compiler and the programmer.

  • They're ugly choices indeed. I think I'll just have to think of a way to not block my tasks in the middle of excution by maybe introducing some kind of busy states into the tasks.