Why does the Zynq Ultrascale+ FPD watchdog status remain at zero when it appears to be configured correctly? - xilinx

I've written the following code for the Zynq Ultrascale+ Z106 board and stepped through it examining the registers. They seem to be set correctly. I start the watchdog and then later (not shown) I restart it before entering a loop. But STATUS.WDZ never reaches 1. This is for the APUs and I've verified that it's using the correct base address for the FPD SWDT. I've read through the technical reference manual several times. What am I missing?
This code is part of a C++ class where start() and stop() map to the corresponding Xilinx API functions.
I'm using the most recent version of Vitis.
UPDATE: I changed XPAR_XWDTPS_1_DEVICE_ID to XPAR_XWDTPS_0_DEVICE_ID and WDZ is set after some time has elapsed. My understanding is that this is for the RPUs and LPD however and so, while I appear to be able to configure it from an APU core, the interrupt signal will go to the GIC instance associated with an RPU core and will be of no help.
int status;
auto configuration = XWdtPs_LookupConfig(XPAR_XWDTPS_1_DEVICE_ID);
status = XWdtPs_CfgInitialize(&_wdt, configuration, configuration->BaseAddress);
if (status != XST_SUCCESS)
{
printf("Watchdog: Configuration initialization failed.");
return;
}
status = XWdtPs_SelfTest(&_wdt);
if (status != XST_SUCCESS)
{
printf("Watchdog: Self testing failed.");
return;
}
// Stop / disable the timer before configuring.
stop();
// Set the fields of the control register. The counter reset value is the count value that is
// used when the watchdog is restarted. The counter is 24 bits and this value sets the upper 12
// bits: 0x00NN'NFFF.
XWdtPs_SetControlValue(&_wdt, XWDTPS_COUNTER_RESET, 0);
// Set the initial divider ratio at the smallest value.
XWdtPs_SetControlValue(&_wdt, XWDTPS_CLK_PRESCALE, XWDTPS_CCR_PSCALE_0008);
// Disable the reset output.
output_enabled(RESET_OUTPUT, false);
// Enable the IRQ output.
output_enabled(IRQ_OUTPUT, true);
start();

Related

Is this the right way to create and delete tasks dynamically in 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!

OTA for FreeRTOS for device in deep sleep from AWS

Background
I have a small battery powered system running on freeRTOS. I need to periodically run OTA updates, as per any proper internet connected device. The problem is that, being battery powered, the device spends 99.9% of it's life in deep sleep.
When the device is awake, it's possible to post an OTA update from AWS, by publishing to the device's OTA/update topic. From the console, you can only use QOS = 0. But from inside, say a lambda, I believe it's possible to use QOS = 1.
{
"state": {
"desired": {
"ota_url":"https://s3-ap-southeast-2.amazonaws.com/my.awesome.bucket/signed_binary_v21.bin"
}
}
}
Questions
How can I modify this approach to successfully update a device that sleeps for 15 minutes at a time, and wakes for maybe 10 s. During the waking period, it sends a message. Is there some way of leaving the desired OTA/update in the shadow that somehow is included in the response from AWS. I've not managed to figure out how shadows really work. OR can you specify a retry period and time to keep trying perhaps?
Is this approach essentially consistent with the most recent best practice from a security perspective : signed binary, encrypted flash & secure boot etc.
Many thanks.
IDF comes with an OTA example that is pretty straight forward. As suggested in the comments on your question, the example downloads the firmware update, and it will automatically revert to the previous image if the updated version has errors that cause a reset. This is the operative part of the example:
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
esp_err_t _ota_http_event_handler(esp_http_client_event_t* evt);
#define FIRMWARE_UPGRADE_URL "https://yourserver.com/somefolder/somefirmware.bin"
void simple_ota_task(void* pvParameter)
{
esp_http_client_config_t config = {
.url = FIRMWARE_UPGRADE_URL,
.cert_pem = (char*)server_cert_pem_start,
.event_handler = _ota_http_event_handler,
};
esp_err_t ret = esp_https_ota(&config);
if (ret == ESP_OK)
ESP_LOGW("ota", "Upgrade success");
else
ESP_LOGE(TAG, "Upgrade failure");
esp_restart();
}
void foo()
{
// after initializing WiFi, create a task to execute OTA:
//
xTaskCreate(&simple_ota_task, "ota_task", 8192, NULL, 5, NULL);
}
// event handler callback referenced above, it has no functional purpose
// just dumps info log output
esp_err_t _ota_http_event_handler(esp_http_client_event_t* evt)
{
switch (evt->event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
break;
}
return ESP_OK;
}
To setup embedding the cert, obtain the public key by examining the SSL cert for the site on which the bin file will reside, with a web browser, save it, then convert it to Base64, aka PEM format. (I used some web page.) In my case I created a directory at the same level as the /main directory, called /server_certs, and saved the Base64 conversion in that directory as ca_cert.pem. (That was way too pedantic, wasn't it?)
Then added these lines to CMakeFiles.txt in the /main directory:
# Embed the server root certificate into the final binary
set(COMPONENT_EMBED_TXTFILES ${IDF_PROJECT_PATH}/server_certs/ca_cert.pem)
register_component()
The thing that was unclear to me was how to determine that a newer version is available, if there is a built-in way I couldn't discern it, and did not want to download the update for nothing, ever. So I rolled my own, embedded a version string in the firmware, created a WebAPI entry point on my server that returns the current version (both maintained by hand until I can think of a better way... that I feel like implementing) and call the OTA functionality when the strings don't match. It looks a lot like this:
// The WebAPI returns data in JSON format,
// so if a method returns a string it is quoted.
#define FW_VERSION "\"00.09.015\""
// the HTTP request has just completed, payload stored in recv_buf
//
// tack a null terminator using an index maintained by the HTTP transfer
recv_buf[pos + 1] = 0;
// test for success
if (strncmp(recv_buf, "HTTP/1.1 200 OK", 15) == 0)
{
// find the end of the headers
char *p = strstr(recv_buf, "\r\n\r\n");
if (p)
{
ESP_LOGI("***", "version: %s content %s", FW_VERSION, (p + 4));
if (strcmp((p + 4), FW_VERSION) > 0)
{
// execute OTA task
foo();
}
else
{
// Assumes the new version has run far enough to be
// considered working, commits the update. It doesn't
// hurt anything to call this any number of times.
esp_ota_mark_app_valid_cancel_rollback();
}
}
}
If you're not using the CMake/Ninja build tools, consider checking it out, it's way, way faster than the MingW32-based tool set.
As you have mentioned, you do not fully understand how shadows work, let me explain how using shadows may fit in scenario similar to yours.
Normally, a device that sleeps for long and wakes up for a short duration, usually makes a request to device shadow at wake up. If the shadow contains
{"state": {"desired":{"ota_url": "xxx", "do_ota": true, ...}}},
In this case, device should initiate ota update code inside device.
Further, the approach mentioned here has nothing to do with security and best practices (signed binary, encrypted flash and secure boot). All these three things should be handled by ota update program. Shadows are only used to indicate that there is a ota update available. Using shadow help you avoid making unnecessary GET Request to OTA server, in turn saving precious power and compute resources.

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).

AccountInfo() and SymbolInfo() return 0 on MT4 startup

When I attach a custom indicator to a chart, close MT4 and reopen it, the indicator initialises normally but every instance of AccountInfo() or SymbolInfo() in the first run of start() returns 0.0, causing several functions to throw a 'zero divide' error. When I reinitialise the indicator (without closing MT4), AccountInfo() and SymbolInfo() return the values they usually do.
If I comment out all functions that are dependent on these two, the indicator initialises without throwing errors after restarting MT4.
Has anybody had a similar issue?
To clarify: the problem only arises when I attach the indicator to the chart, close MT4 and reopen it again; when I attach it when MT4 is already open, AccountInfo() and SymbolInfo() return normal values.
Additional information:
using #property strict
using start() instead of OnCalculate() (so I can run the main function manually without waiting for a new tick)
the requested account or symbol property has no influence on the problem
It happens quite often that some data is not available in MT4 at some moment of time. The best thing you can do is to check whether the result is accepted (>0 if you call time, quotes, other data that cannot be zero) or to check the last error, then Sleep(50) and try again. Most likely 2-5th attempt is successful so you need that in a loop.
It is possible that you need to know at least Account Number that cannot be zero. After you receive succesful result, all other data seems to loaded correctly.
int OnInit()
{
if(!initializeAccountInfo())
return(INIT_FAILED);
// ... other checks that you need
return(INIT_SUCCEEDED);
}
bool initializeAccountInfo()
{
int accountNumber=0, attempt=0, ATTEMPTS=50, SLEEP(50);
while(attempt<ATTEMPTS)
{
accountNumber=AccountInfoInteger(ACCOUNT_LOGIN);
attempt++;
if(accountNumber==0)
Sleep(SLEEP);
else
break;
}
return accountNumber>0;
}

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.

Resources