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/> >> >