Julian:

OK, I see the issue now; thanks for explaining it. And to state the obvious, 
the order of initialization is indeed important given the task design in this 
example.


> On May 12, 2017, at 2:47 AM, Julian Ingram <julian.ing...@imgtec.com> wrote:
> 
> Hi Will,
> 
> Thanks for your response, and sorry, the priorities were incorrect... "idle" 
> should be a lower priority "proc" but higher than "main". I will also attempt 
> a better explanation: In the example, the code in proc_task should only be 
> executed after `some_event()` returns truthy. If there is a scheduling point 
> after the perhaps poorly named "idle" task is initialised and before the 
> "proc" task is added to the task list, the execution switches to the "idle" 
> task and then even when `some_event()` returns truthy and releases the 
> semaphore, nothing is waiting on it so the task spins forever.
> 
> Corrected priorities:
> 
>>         os_task_init(&idle_task, "idle", idle_task_handler, NULL, 2, 
>> OS_WAIT_FOREVER, idle_stack, IDLE_STACK_SIZE);
>>               os_task_init(&proc_task, "proc", proc_task_handler,  NULL, 1, 
>> OS_WAIT_FOREVER, proc_stack, PROC_STACK_SIZE); }
> 
> Single threaded equivalent (desired) functionality:
> 
>>               while (1) {
>>                               if (some_event()) {
>>                                               //...
>>                               }
>>                }
> 
> It is likely that being careful about the order of initialised tasks is the 
> answer and I just preferred it when I had control over when the OS started!
> 
> Also thanks for the assert advice.
> 
> Julian
> 
> -----Original Message-----
> From: will sanfilippo [mailto:wi...@runtime.io] 
> Sent: 11 May 2017 18:45
> To: dev@mynewt.incubator.apache.org
> Subject: Re: OS starting before main
> 
> Julian:
> 
> Given your example I am a bit confused about some things. I think part of my 
> confusion is that you intialized the idle task to priority 1 and the other 
> task to priority 2. Priority 1 is higher priority than 2. I guess idle task 
> to me is something special but I realize this could just be an example name. 
> So I will go with the presumption that the priorities you have specified are 
> correct: idle_task_handler is the highest priority task and proc_task_handler 
> is a task lower in priority.
> 
> The other part of this example that confuses me is what happens in 
> some_event(). I presume that this function is waiting for some event to occur 
> and it is yielding if no event is available. If it is not, you will never 
> yield and you will be stuck in that task forever (and that does not have 
> anything to do with the order of initialization as far as I can see). If that 
> call does yield, I do not see the problem.
> 
> Anyway, and I probably should have said this first, yes, you have to be 
> careful about the order in which things are initialized. This does indeed get 
> tricky at times but should be possible given that sysinit has stages of 
> initialization and can be used to make sure that data structures are 
> initialized prior to them being called.
> 
> Just an FYI. I realize that you are just showing example code and probably 
> typed this up quickly, but just in caseā€¦ I would not do the following: 
> assert( func_call() == OK ). This is because assert may get defined out and 
> then you are not making that function call. Better to do this:
> 
> rc = func_call();
> assert(rc == OK);
> 
> I have been burnt by this in the past so I wanted to point it out.
> 
>> On May 11, 2017, at 2:41 AM, Julian Ingram <julian.ing...@imgtec.com> wrote:
>> 
>> Hi all,
>> 
>> Having moved the PIC32 port to the newer start-up method where os_start is 
>> called before main, there have been problems with a tick potentially 
>> occurring between task initialisations.
>> 
>> Am I missing something here? If not, what is the standard fix, just be 
>> careful about the order of task initialisation, initialise them a critical 
>> section or?
>> 
>> For example:
>> 
>> void
>> idle_task_handler(void *arg)
>> {
>>               while (1) {
>>                               if (some_event()) {
>>                                               os_sem_release(&sem);
>>                               }
>>                }
>> }
>> 
>> void
>> proc_task_handler(void *arg)
>> {
>>               while (1) {
>> int err = os_sem_pend(&sem, OS_TIMEOUT_NEVER);
>>               // ...
>> }
>> }
>> 
>> int
>> main(int argc, char **argv)
>> {
>>               sysinit();
>>               assert(os_sem_init(&sem, 0) == OS_OK); 
>> os_task_init(&idle_task, "idle", idle_task_handler, NULL, 1, 
>> OS_WAIT_FOREVER, idle_stack, IDLE_STACK_SIZE);
>>               // if a systick happens here I'm stuck in the idle task 
>> forever.
>>               os_task_init(&proc_task, "proc", proc_task_handler, 
>> NULL, 2, OS_WAIT_FOREVER, proc_stack, PROC_STACK_SIZE); }
>> 
>> Thanks,
>> 
>> Julian Ingram
>> Software Design Engineer
>> MIPS Platforms
>> Imagination Technologies Limited
>> t: +44 (0)113 2429814
>> www.imgtec.com<http://www.imgtec.com/>
>> 
> 

Reply via email to