Is this the right way to create and delete tasks dynamically in freertos? - freertos

I have some rookie questions on how to port an existing application on ESP32 to freeRTOS. I have a first setup running but am hitting some roadblocks.
We have built a test device that exercises a unit under test by stepping through several steps. The proof-of-concept is running freeRTOS on an ESP32 with an LCD display, user buttons, and all the needed I/O circuits. In general, the procedure for each measurement step is:
Set up HW (open/close relays)
Measure values (voltages, currents)
Wait for readings to stabilize
Validate if readings are correct for given stage
Determine pass/fail, eventually upload results to server
We have 12 different steps as outlined above plus some extra ones to select the test protocol and configure the WiFi interface.
We reasoned (wrongly?) that we want to create individual tasks on the fly when needed and not create them at the start and kept in suspended mode. This is as safety measure since we want to avoid that (inadvertently) two different tasks would be running simultaneously when they shouldn't: that might create the danger of messing up the relays that control AC power.
So, we want to create two tasks for each test step:
Task1: with an infinite loop that reads the corresponding values
CheckTask1: waits x seconds then should delete Task1, determine pass/fail and then delete itself
The problem I have is that the for(;;) that is in the function that creates Task1 never ends, so we can´t fire off TaskCheck1.
The abbreviated code is below:
/************************************************************************
*
* MAIN LOOP
*
************************************************************************/
void loop()
{
// We keep the main loop always running and firing off the different tasks.
if (some_condition_to_create_task_1){
startTask1(); // Creates a task that shows an analog reading on the display
startCheckTask1(); // Creates a task that waits x secs, then deletes Task1 and deletes itself
// --> PROBLEM: startCheckTask1() is never executed, the for(;;) in startTask1() never exits
}
// Similar code to above for additional tasks to create when their turn comes
}
/************************************************************************
*
* TASKS
*
************************************************************************/
void Task1(void *pvParameters) // Reads analog value and shows on display
{
(void) pvParameters;
for(;;){
readAnalogValue();
showOnDisplay();
vTaskDelay(500); // Update reading every 0,5 sec to avoid flicker
}
}
void startCheckTask1(void *pvParameters) // Waits for 5 seconds, then deletes Task1, interprets results and shows
// passed/failed on screen
{
(void) pvParameters;
unsigned long oldTicks, NewTicks;
vTaskDelay(5000); // Allow 5 secs for readings to stabilize
showResultOnDisplay(); // Show passed/failed on the display
// Now delete both tasks
vTaskDelete(hTask1);
vTaskDelete(hCheckTask1);
}
/************************************************************************
*
* FUNCTIONS
*
************************************************************************/
void startTask1(){
xTaskCreatePinnedToCore(Task1,"Task 1", 1024, NULL, 1, &hTask1, 1);
for(;;){ // PROBLEM: This is the loop that prevents creating CheckTask1
}
}
void startCheckTask1(){
xTaskCreatePinnedToCore(CheckTask1,"Check Task 1", 1024, NULL, 1, &hCheckTask1, 1);
for(;;){
}
}
Any ideas how to solve this? Thx!

Related

How to trigger garbage collector to reduce database size?

We use Xodus for a remote probe project in order to store temporary data before sending them to the centralized database. Thus, we have several stores which can grow or decrease accordingly to the environment (traffic, network connection, etc...). Thanks to the garbage collector, we expected to see decrease in the database file size but for the moment, it has only increased.
We tried several garbage collector configurations to trigger it as frequently as possible. For example, we have :
conf.setGcFileMinAge(1);
conf.setGcFilesInterval(1);
conf.setGcMinUtilization(1);
Without visible effects...
After the store has been emptied, we expected to see reducing or deletion of .xd files but the database keeps growing and growing.
EDIT :
I try to see GC effects with a simpler code as below :
Environment exodus = Environments.newInstance(dbPath);
final Transaction xtxn = exodus.beginExclusiveTransaction();
Store store = exodus.openStore("testStore", StoreConfig.WITHOUT_DUPLICATES, xtxn);
xtxn.commit();
Thread.sleep(10 * 1000); // Wait to do actions after first background cleaning cycle
// Fill store, then clear it
exodus.executeInExclusiveTransaction(tx -> {
for(int i = 1; i <= 1000000; i++) {
store.putRight(tx, LongBinding.longToEntry(i), StringBinding.stringToEntry(dbPath));
}
});
clearStore(exodus, store);
exodus.gc();
Thread.sleep(5 * 60 * 1000); // Wait to see GC doing the work
boolean clearStore(final Environment exodus, final Store store) {
Transaction tx = exodus.beginExclusiveTransaction();
try(Cursor cursor = store.openCursor(tx)) {
boolean success = true;
while(cursor.getNext() && success) {
success &= cursor.deleteCurrent();
}
if(success) {
tx.commit();
return true;
} else {
log.warn("failed to delete entry {}", cursor.getKey());
tx.abort();
return false;
}
} catch(Exception e) {
tx.abort();
return false;
}
}
If I remove the first "sleep", Garbage Collector is doing the work, the database file size is reduced as expected, everything is ok.
But if I keep the first "sleep", Garbage Collector never seems to be called.
It's like the first background cleaning cycle is ok, but not the following ones...
I keep default configuration in this example.
There is the Environment.gc() method. The javadoc for the method is as follows:
Says environment to quicken background database garbage collector activity. Invocation of this method doesn't have immediate consequences like freeing disk space, deleting particular files, etc.
I wouldn't recommend modifying default GC settings. EnvironmentConfig.setGcMinUtilization() can be used to keep the database more compact than it would be by default, or to decrease GC load (e.g., in parallel with batch updates). Basically, higher required minimum utilization (less admissible free space) results in higher GC load.
GC cleans the database file by file, selecting files with least utilization first. When a file is cleaned it is not deleted immediately, two conditions should be satisfied:
A delay configured by EnvironmentConfig.getGcFilesDeletionDelay() should pass. It's 5 seconds by default.
Any transaction (even read-only), created before the moment when the file is cleaned, should be finished (committed or aborted).

Queues in FreeRTOS

I'm using Freescale FRDM-KL25Z board with Codewarrior 10.6 software. My goal is to make small program in FreeRTOS, which reads voltage from thermistor by analog/digital converter (0-3,3v) and depends on this voltage I'd like turn on/off led diodes. It worked for me till the moment, when I added second task and queues. I'm thinking that problem might be in stack size, but I have no idea how to configure it.
Code is below:
xQueueHandle queue_led;
void TaskLed (void *p)
{
uint16_t temp_val;
xQueueReceive(queue_led, &temp_val, 1);
if (temp_val<60000)
{
LED_1_Neg();
}
}
void TaskTemp (void *p)
{
uint16_t temp_val;
(void)AD1_Measure(TRUE);
(void)AD1_GetValue16(&temp_val);
xQueueSendToBack(queue_led, &temp_val, 1000);
FRTOS1_vTaskDelay(1000);
}
Code in main():
xTaskCreate(TaskLed, (signed char *)"tl", 200, NULL, 1, NULL);
xTaskCreate(TaskTemp, (signed char *)"tt", 200, NULL, 1, NULL);
vTaskStartScheduler();
return(0);
A task is normally a continuous thread of execution - that is - it is implemented as an infinite loop that runs forever. It is very rare for a task to exit its loop - and in FreeRTOS you cannot run off the bottom of a function that implements a task without deleting the task (in more recent versions of FreeRTOS you will trigger an assert if you try). Therefore the functions that implement your tasks are not valid.
FreeRTOS has excellent documentation (and an excellent support forum, for that matter, which would be a more appropriate place to post this question). You can see how a task should be written here: http://www.freertos.org/implementing-a-FreeRTOS-task.html
In the code you post I can't see that you are creating the queue that you are trying to use. That is also documented on the FreeRTOS.org website, and the download has hundreds of examples of how to do it.
If it were a stack issue then Google would show you to go here:
http://www.freertos.org/Stacks-and-stack-overflow-checking.html
You should create the queue and then check that the returned value is not zero (the queue is successfully created)

Is it possible to check that main thread is idle / to drain a main run loop?

I've just read the following post and have tried to implement the approach described there:
Writing iOS acceptance tests using Kiwi - Being Agile
All the stuff described there does work perfectly. But! there is one thing that breaks determinism when I am running my acceptance tests.
Here is the repo on Github where author of the post pushed his experiments (it can be found on the bottom of the page in the comments): https://github.com/moredip/2012-Olympics-iOS--iPad-and-iPhone--source-code/tree/kiwi-acceptance-mk1
Consider this code he uses for tapping a view:
- (void) tapViewViaSelector:(NSString *)viewSelector{
[UIAutomationBridge tapView:[self viewViaSelector:viewSelector]];
sleepFor(0.1); //ugh
}
...where sleepFor has the following definition behind itself:
#define sleepFor(interval) (CFRunLoopRunInMode(kCFRunLoopDefaultMode, interval, false))
It is a naive attempt ('naive' is not about the author, but about the fact that it is the first thing that comes into a head) to wait for a tiny period of time until all the animations are processed and soak all the possible events that were(or could be) scheduled to a main run loop (see also this comment).
The problem is that this naive code does not work in a deterministic way. There are a bunches of UI interactions which cause fx next button tap to be pressed before the current edited textfield's keyboard is disappeared and so on...
If I just increase the time from 0.1 to fx 1 all the problems disappear, but this leads to that every single interaction like "fill in textfield with a text..." or "tap button with title..." become to cost One second!
So I don't mean just increasing a wait time here, but rather a way to make such artificial waits guarantee that I do can proceed my test case with a next step.
I hope that it should be a more reliable way to wait enough until all the stuff caused by current action (all the transitions/animations or whatever main run loop stuff) are done.
To summarize it all to be a question:
Is there a way to exhaust/drain/soak all the stuff scheduled to a main thread and its run loop to be sure that main thread is idle and its run loop is "empty"?
This was my initial solution:
// DON'T like it
static inline void runLoopIfNeeded() {
// https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFRunLoopRef/Reference/reference.html
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource);
// DON'T like it
if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource) runLoopIfNeeded();
}
you can try this
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource);
this will run until no more things in the run loop. you can try to change the time interval to 0.1 if 0 is not working.
To check on the status of a run loop associated with a thread and register callbacks for separate phases, you may use a CFRunLoopObserverRef. This allows for extremely fine grained control over when the callbacks are invoked. Also, you don't have to depend on hacky timeouts and such.
One can be added like so (notice I am adding one to the main run loop)
CFRunLoopObserverRef obs = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, true, 0 /* order */, handler);
CFRunLoopAddObserver([NSRunLoop mainRunLoop].getCFRunLoop, obs, kCFRunLoopCommonModes);
CFRelease(obs);
Depending on the activities you register for, your handler will get invoked appropriately. In the sample above, the observer listens for all activities. You probably only need kCFRunLoopBeforeWaiting
You handler could look like this
id handler = ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
switch (activity) {
case kCFRunLoopEntry:
// About to enter the processing loop. Happens
// once per `CFRunLoopRun` or `CFRunLoopRunInMode` call
break;
case kCFRunLoopBeforeTimers:
case kCFRunLoopBeforeSources:
// Happens before timers or sources are about to be handled
break;
case kCFRunLoopBeforeWaiting:
// All timers and sources are handled and loop is about to go
// to sleep. This is most likely what you are looking for :)
break;
case kCFRunLoopAfterWaiting:
// About to process a timer or source
break;
case kCFRunLoopExit:
// The `CFRunLoopRun` or `CFRunLoopRunInMode` call is about to
// return
break;
}
};
Here is my current solution, I will add some comments and explanations to the code a bit later, if nobody tell me I am wrong or suggests a better answer first:
// It is much better, than it was, but still unsure
static inline void runLoopIfNeeded() {
// https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFRunLoopRef/Reference/reference.html
__block BOOL flag = NO;
// http://stackoverflow.com/questions/7356820/specify-to-call-someting-when-main-thread-is-idle
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
flag = YES;
});
});
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource);
if (flag == NO) runLoopIfNeeded();
}
Right now I don't have any ideas how this could be made more effective.

Basic concept of message loop in directx

Well I find weird point of message loop.
first, lock this code below
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render(); // Do some rendering
}
}
It is a tutorial of directx and this part is part of message loop.
If I click a mouse, It goes to queue as Message.
So Input like this should be process in proc function of win api.
Now that peekMessage return true, render() will not be called in frame when I clicked.
I think code be changed if~else to if~if for render when I click.
Can you explain this??
Your understanding is close, but not quite right. The loop isn't run once per frame. Rather, what happens is that for every iteration of the loop, either a single message is processed or Render is called. Effectively this makes rendering the lowest priority, but keeps your application responsive. The loop may be run many times or few times for each frame drawn, depending on how much work there is to do.
Does Render directly call Present? Or does it invalidate the window? If it invalidates the window, you would not want to change to always calling Render like you mentioned, because you'd risk not redrawing the window between renders.
Essentially this loop will process any pending Win32 messages for your window, and if there aren't any, it will render a frame. If it sees a WM_QUIT message, it exits the loop to quit the app.
There's no need for a 'throttle' because DirectX Present will block the thread (i.e. suspend it) if there are already 3 frames pending to render.
This model assumes you are doing one frame 'Update' per 'Render' call which isn't that realistic for a game, but it is simple for the tutorial. Extending the tutorial loop with StepTimer would look something like:
#include “StepTimer.h
DX::StepTimer g_timer;
...
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
g_timer.Tick([&]()
{
Update(g_timer); // Update world/game state
});
Render(); // Do some rendering
}
}
...
void Render();
void Update(DX::StepTimer& timer);
StepTimer defaults to using variable step updates which means Update is called once per frame with whatever time delta and then Render is called once.
You can use a fixed-step update (say 60 times a second) like this:
g_timer.SetFixedTimeStep(true);
g_timer.SetTargetElapsedSeconds(1.f / 60.f);
In this mode, you'll have all pending Win32 messages processed, and then Update is called as any times as needed to keep up an average of 60 fixed-step updates per second, and then Render is called once.
The Render() inside the else basically gives preference to handling messages in the queue over rendering. Moving the mouse over the directx rendered window will add messages quickly to the message queue, but not fast enough to cause rendering to be delayed to any degree you'd ever see it. There is no advantage to rendering with each iteration because the iterations happen much faster than each frame is generated in your swapchain and much faster than a new message could swamp your queue. Most computers today will run this loop more than once per millisecond and even mouseover events happen less often than this. You wouldn't be wrong to render with every iteration, it's just unnecessary. With the example running, moving your mouse over the directx window as quickly as you can will cause fewer than 10% of the iterations of this loop to handle a message and delay rendering.
This message loop is executed as quickly as possible and has no facility to detect when the swapchain is ready to render. The PeekMessage checks to see if there's a message in the queue. If there is, it processes it, if not it Renders. What you're worried about is that a sequence of window events will cause the render to be delayed, but that's practically impossible. No matter how fast messages are sent to the queue, the swapchain is rendered more than 10 times faster than it needs to even for 60fps. This loop is the cause of high CPU utilization. The reason for it may be to simplify the tutorial, but as it's an inherently complicated environment. You might modify the swap chain in a separate thread if you're worried about the message queue delaying frame rendering.
To improve the CPU efficiency of the example program, just add a Sleep(8); at the bottom of the Render() routine. This will cause the message handler/render thread to pause between cycles handling messages and rendering at about 120 times per second. You can improve upon this by using high resolution timers and a modulus based sleep between cycles.
A good source of information to improve this example can be found here.

Multiple Thread access the same code in multithread application

I am in the middle of the windows service multithread project where I need some inputs from you guys to run it successfully. below is the code and describe what I am trying to do and problem.
// I created a new thread and call MyTimerMethod() from the Main method.
private void MyTimerMethod()
{
timer = Timers.Timer(5000)
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Start();
// make this thread run every time.
Application.Run();
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
for(int i = 0; i < SomeNum; i++) //SomeNum > 0
ThreadPool.QueueUserWorkItem(WaitCallback(MyWorkingMethod),null);
}
private void MyWorkingMethod(object state)
{
// each thread needs to go and check the status and print if currentStatus = true.
// if currentStautus = true then that jobs is ready to print.
// FYI ReadStatusFromDB() from the base class so I cannot modify it.
ReadStatusFromDB(); // ReadStatusFromDB() contains jobs to be printed.
// after doing some work store procedure update the currentStatus = false.
//do more stuff.
}
Long story in short, program runs every five seconds and check if there is more work to do. If there is then create a new thread from the threadpool and push into the queue. Now my problem is when there is more than one threads in the queue. Even the currentStatus = false multiple threads grab the same jobs and tries to print.
let me know if you need further information.
I would suggest creating a BlockingCollection of work items, and structure your program as a producer/consumer application. When a job is submitted (either by the timer tick, or perhaps some other way), it's just added to the collection.
You then have one or more persistent threads that are waiting on the collection with a TryTake. When an item is added to the collection, one of those waiting threads will get and process it.
This structure has several advantages. First, it prevents multiple threads from working on the same item. Second, it limits the number of threads that will be processing items concurrently. Third, the threads are doing non-busy waits on the collection, meaning that they're not consuming CPU resources. The only drawback is that you have multiple persistent threads. But if you're processing items most of the time anyway, then the persistent threads isn't a problem at all.

Resources