I am using VisualGFX to develop a user interface for my STM32F429i-Discovery board. VisualGFX has built in freeRTOS usage with a GUITask being created to handle the GUI operations. I am then trying to create a new task called ControllerTask with the xTaskCreate API function from freeRTOS, same function as is used to create the GUITask.
However, as soon as I create this second Task the GUITask displays some weird values on my GUI and there is no functionality.
int main(void){
...
xTaskCreate(GUITask, (TASKCREATE_NAME_TYPE)"GUITask",
configGUI_TASK_STK_SIZE,
NULL,
configGUI_TASK_PRIORITY,
NULL);
xTaskCreate (ControllerTask, (TASKCREATE_NAME_TYPE)"ControllerTask",
configController_TASK_STK_SIZE,
NULL,
configController_TASK_PRIORITY,
NULL);
vTaskStartScheduler();
for (;;);
The above code shows the creation of the two tasks. The priority of the GUITask is higher as that of the ControllerTask. The next piece of code shows the Task implementation.
static void GUITask(void* params)
{
touchgfx::HAL::getInstance()->taskEntry();
}
static void ControllerTask(void* params)
{
while(1)
{
vTaskDelay(3000);
}
}
As can be seen the implementation of the ControllerTask at this moment in time is only Delaying the Task for roughly 3 seconds each time it is switched to.
However, the GUITask gets stuck and no GUI updates or interaction is possible.
Basically what is likely to happen is that your taskEntry() function never returns, and thus never gives back processing time to the kernel by using vTaskDelay or other Queue calls.
void taskEntry ( ) virtual Main event loop. Will wait for VSYNC
signal, and then process next frame. Call this function from your GUI
task.
Note This function never returns! Reimplemented in HALSDL2, and
HALSDL.
If both task has same priority, or if your touchgfx has higher priority, you will get stuck.
To solve that issue, there are two ways.
Is to implement the task with priorities, and set that task with the lowest priority of all.
Enable the Idle task and implement the call on that method.
Related
The view model is given below
class ClickRowViewModel #Inject constructor(
private val clickRowRepository: ClickRowRepository
): ViewModel() {
private val _clickRowsFlow = MutableStateFlow<List<ClickRow>>(mutableListOf())
val clickRowsFlow = _clickRowsFlow.asStateFlow()
fun fetchAndInitialiseClickRows() {
viewModelScope.launch {
_clickRowsFlow.update {
clickRowRepository.fetchClickRows()
}
}
}
}
My test is as follows:
I am using InstantTaskExecutorRule as follows
#get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()
The actual value never resolves to the expected value even though $result seems to have two elements but the actualValue is an empty list. I don't know what I am doing wrong.
Update
I tried to use the first terminal operator as well but the returned output returns an empty list.
Update # 2
I tried async but I got the following error
kotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 60000 ms, the test coroutine is not completing, there were active child jobs: [DeferredCoroutine{Active}#a4a38f0]
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$3$3.invokeSuspend(TestBuilders.kt:342)
Update # 3
This test passes in Android Studio, but fails using CLI
Test failing in CLI
You can't call toList on a SharedFlow like that:
Shared flow never completes. A call to Flow.collect on a shared flow never completes normally, and neither does a coroutine started by the Flow.launchIn function.
So calling toList will hang forever, because the flow never hits an end point where it says "ok that's all the elements", and toList needs to return a final value. Since StateFlow only contains one element at a time anyway, and you're not collecting over a period of time, you probably just want take(1).toList().
Or use first() if you don't want the wrapping list, which it seems you don't - each element in the StateFlow is a List<ClickRow>, which is what clickRowRepository.fetchClickRows() returns too. So expectedValue is a List<ClickRow>, whereas actualValue is a List<List<ClickRow>> - so they wouldn't match anyway!
edit your update (using first()) has a couple of issues.
First of all, the clickRowsFlow StateFlow in your ViewModel only updates when you call fetchAndInitialiseClickRows(), because that's what fetches a value and sets it on the StateFlow. You're not calling that in your second example, so it won't update.
Second, that StateFlow is going to go through two state values, right? The first is the initial empty list, the second is the row contents you get back from the repo. So when you access that StateFlow, it either needs to be after the update has happened, or (better) you need to ignore the first state and only return the second one:
val actualValue = clickRowViewModel.clickRowsFlow
.drop(1) // ignore the initial state
.first() // then take the first result after that
// start the update -after- setting up the flow collection,
// so there's no race condition to worry about
clickRowsViewModel.fetchAndInitialiseClickRows()
This way, you subscribe to the StateFlow and immediately get (and drop) the initial state. Then when the update happens, it should push another value to the subscriber, which takes that first new value as its final result.
But there's another complication - because fetchAndInitialiseClickRows() kicks off its own coroutine and returns immediately, that means the fetch-and-update task is running asynchronously. You need to give it time to finish, before you start asserting any results from it.
One option is to start the coroutine and then block waiting for the result to show up:
// start the update
clickRowsViewModel.fetchAndInitialiseClickRows()
// run the collection as a blocking operation, which completes when you get
// that second result
val actualValue = clickRowViewModel.clickRowsFlow
.drop(1)
.first()
This works so long as fetchAndInitialiseClickRows doesn't complete immediately. That consumer chain up there requires at least two items to be produced while it's subscribed - if it never gets to see the initial state, it'll hang waiting for that second (really a third) value that's never coming. This introduces a race condition and even if it's "probably fine in practice" it still makes the test brittle.
Your other option is to subscribe first, using a coroutine so that execution can continue, and then start the update - that way the subscriber can see the initial state, and then the update that arrives later:
// async is like launch, but it returns a `Deferred` that produces a result later
val actualValue = async {
clickRowViewModel.clickRowsFlow
.drop(1)
.first()
}
// now you can start the update
clickRowsViewModel.fetchAndInitialiseClickRows()
// then use `await` to block until the result is available
assertEquals(expected, actualValue.await())
You always need to make sure you handle waiting on your coroutines, otherwise the test could finish early (i.e. you do your asserting before the results are in). Like in your first example, you're launching a coroutine to populate your list, but not ensuring that has time to complete before you check the list's contents.
In that case you'd have to do something like advanceUntilIdle() - have a look at this section on testing coroutines, it shows you some ways to wait on them. This might also work for the one you're launching with fetchAndInitialiseClickRows (since it says it waits for other coroutines on the scheduler, not the same scope) but I'm not really familiar with it, you could look into it if you like!
I'd like to organize a thread barrier: given a single lock object, any thread can obtain it and continue thread's chain further, but any other thread will stay dormant on the same lock object until the first thread finishes and releases the lock.
Let's express my intention in code (log() simply prints string in a log):
val mutex = Semaphore(1) // number of permits is 1
source
.subscribeOn(Schedulers.newThread()) // any unbound scheduler (io, newThread)
.flatMap {
log("#1")
mutex.acquireUninterruptibly()
log("#2")
innerSource
.doOnSubscribe(log("#3"))
.doFinally {
mutex.release()
log("#4")
}
}
.subscribe()
It actually works well, i can see how multiple threads show log "#1" and only one of them propagates further, obtaining lock object mutex, then it releases it and i can see other logs, and next threads comes into play. OK
But sometimes, when pressure is quite high and number of threads is greater, say 4-5, i experience DEADLOCK:
Actually, the thread that has acquired the lock, prints "#1" and "#2" but it then never print "#3" (so doOnSubscribe() not called), so it actually stops and does nothing, not subscribing to innerSource in flatMap. So all threads are blocked and app is not responsive at all.
My question - is it safe to have blocking operation inside flatMap? I dig into flatMap source code and i see the place where it internally subscribes:
if (!isDisposed()) {
o.subscribe(new FlatMapSingleObserver<R>(this, downstream));
}
Is it possible that thread's subscription, that has acquired lock, was disposed somehow?
You can use flatMap second parameter maxConcurrency and set it to 1, so it does what you want without manually locking
How can I code a method in VB.Net 2012 that waits for a variable number of asynchronous calls to complete, and only when all calls finish will then return a result?
I'm writing an app that retrieves a value from various web pages, and then returns the sum of those values. The number of values to retrieve will be determined by the user at runtime. As web retrieval is asynchronous by nature, I'm trying to make the app more efficient by coding it as such. I've just read about the keywords Async and Await, which seem perfect for the job. I also found this example of how to do it in C#: Run two async tasks in parallel and collect results in .NET 4.5.
But there are two issues with this example: 1) At first glance, I don't know how to make the same thing happen in VB.Net, and 2) I don't know how it could be redesigned to handle a variable number of called tasks.
Here's a pseudo-translation from the example, of what I hope to achieve:
Function GetSumOfValues(n as Integer)
For i = 1 To n
GetValueAsync<i>.Start()
Next i
Dim result = Await Task.WhenAll(GetValueAsync<?*>)
Return result.Sum()
End Function
Note the question mark, as I'm not sure if it's possible to give WhenAll a "wildcarded" group of tasks. Perhaps with an object collection?
You can use this example of using tasks with Task.WaitAll
Now, to collect data asynchronously, you can use a static method with sync lock. Or one of the synchronized collections
I'm trying to force CAN signals to given values using COM interface of CANalyzer. Since there is no COM method to send CAN messages, I'm implementing a workaround using CAPL:
void SendMySignal(int value) {
message MyMessage msg;
msg.MySignal = value;
output(msg);
}
This works fine, however since MyMessage and MySignal are referenced statically (by name) here, I'll have to implement N functions to be able to send N signals (or an N-way switch statement, etc). Is there a way to avoid the hassle and access signals inside a message by string? Something like this:
void SendSignal(int MessageID, char SignalName, int value)
I'm also open to alternative solutions in case I have missed something in the COM interface. If there is a solution which only works for CANoe, I can ask my boss for a license, but of course I'd prefer to do without.
there is such function, but it is restricted to be used only in test nodes
long setSignal(char signalName[], double aValue);
you can find details in:
CAPL Function Overview » Test Feature Set / Signal Access » SetSignal
Special Use Case: Signal is not known before Measurement Start
and take care about not to send for each signal a new message to avoid bus over-flooding. In my opinion it is a better style to set all signals for whole message and to send it on change only when it is not cyclic. Signal updates in cyclic messages mostly have to be sent in next cycle.
My understanding of "reentrant function" is that it's a function that can be interrupted (e.g by an ISR or a recursive call) and later resumed such that the overall output of the function isn't affected in any way by the interruption.
Following is an example of a reentrant function from Wikipedia https://en.wikipedia.org/wiki/Reentrancy_(computing)
int t;
void swap(int *x, int *y)
{
int s;
s = t; // save global variable
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
t = s; // restore global variable
}
void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
I was thinking, what if we modify the ISR like this:
void isr()
{
t=0;
}
And let's say, then, that the main function calls the swap function, but then suddenly an interrupt occurs, then the output would surely get distorted as the swap wouldn't be proper, which in my mind makes this function non-reentrant.
Is my thinking right or wrong? Is there some mistake in my understanding of reentrancy?
The answer to your question:
that the main function calls the swap function, but then suddenly an interrupt occurs, then the output would surely get distorted as the swap wouldn't be proper, which in my mind makes this function non-reentrant.
Is no, it does not, because re-entrancy is (by definition) defined with respect to self. If isr calls swap, the other swap would be safe. However, swap is thread-unsafe, though.
The correct way of thinking depends on the precise definition of re-entrancy and thread-safety (See, say Threadsafe vs re-entrant)
Wikipedia, the source of the code in question, selected the definition of reentrant function to be "if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution".
I have never heard the term re-entrancy used in the context of interrupt service routines. It is generally the responsibility of the ISR (and/or the operating system) to maintain consistency - application code should not need to know anything about what an interrupt might do.
That a function is re-entrant usually means that it can be called from multiple threads simultaneously - or by itself recursively (either directly or through a more elaborate call chain) - and still maintain internal consistency.
For functions to be re-entrant they must generally avoid using static variables and of course avoid calls to other functions that are not themselves re-entrant.