STM32 IAP Boot + Two Applications - in-app-purchase

I have the following setup on my STM32F4xx
Flash Start
Boot
Reserved Area
Application 1 Region
Application 2 Region
Flash End
Boot can program to App1 and App2 regions using IAP (bluetooth).
App1 can program to Boot and App2 regions using IAP (bluetooth).
App2 can program to Boot and App1 regions using IAP (bluetooth).
This works fine, but App1 and App2 are compiled knowing in which region will be programmed.
In the link script I have to place the address where the app will be and the size of the region.
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = FLASH_ADDRESS_APP, LENGTH = APPLICATION_LENGTH
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
}
Also I have to know where the ISR Table will be, in my case I have set the first region:
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
So I have set SCB->VTOR = FLASH_ADDRESS_APP
Is there a way to compile in the same way two applications without knowing in which region will be?

Related

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

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();

Would the startup code still be accessible after an address remap on an RZ/A1L in boot mode 0?

According to the "Address Remapping" section of the "RZ/A1L Group, RZ/A1LU Group, RZ/A1LC Group manual", a remap operation on this MCU causes the address range 0x20000000 - 0x204FFFFF to be allocated to 0x00000000 - 0x004FFFFF. The manual also states in section 3.5.1 that, in boot mode 0, "program execution is started from H'0000_0000". Thus, in boot mode 0, the reset/boot vector must be placed at 0x00000000.
So, if the MCU is booted in boot mode 0 and an address remap is issued shortly after during startup, would the startup code (and reset handler) be accessible after the remap? (Assuming it's linked/downloaded to the start of the CS0 space) Put in another way, would the startup code still run in between 0x00000000 and 0x004FFFFF? Or would it rather run in the CS0 mirror space (0x40000000 - 0x43FFFFFF)?
I was under the understanding that, after the remap, accesses to the 0x00000000 - 0x004FFFFF range would be interpreted by the MMU as accesses to the range 0x20000000 - 0x204FFFFF, which is ultimately why it is advantageous for the vector table to be remapped.
Thanks to user #old_timer's comments, I was able to identify a misunderstanding on my part with respect to the concept of memory mapping. After "connecting the dots" and resolving this misunderstanding, it gave way to the answer to this question.
What I was (embarrassingly) not understanding before was that the whole purpose of a remap operation is to reconfigure a set of addresses that are associated with a specific memory device/interface (e.g. SPI, flash, SRAM, etc.) with a different one.
With this in mind, at bootup (and before a remap operation), the CS0 space is mapped to a specific device: SRAM with byte selection or burst ROM (asynchronous or
synchronous), as specified on page 181 of the User Manual). In boot mode 0, the startup code would subsequently need to be loaded into that same device, whatever it may be (either SRAM or burst ROM). In boot mode 1, the startup code would need to reside in the SPI multi-I/O bus space (serial flash memory); in boot mode 2, SD controller (NAND flash memory); etc.
After a remap, the CS0 address space is subsequently mapped to the on-chip RAM. The code that was executing before the remap still resides in and executes from where it was loaded.

non deterministic behaviour when using jungo driver to communicate with a PCI device

I have a PCI based Device, more specifically based on tms320c6000 DSP, I am trying to communicate (reading some registers) with this device through the Jungo WinDriver. Surprisingly it sometimes work and sometimes doesn't, when it doesn't system hang and I have to restart the system.
this is the snipped code which I used to read EMIF Registers, for example.
WD_TRANSFER tt[9];
BZERO(tt);
for (unsigned i = 0; i < 9; i++) {
tt[i].cmdTrans = RM_DWORD;
tt[i].dwPort = mmr + (i * 4);
}
WD_MultiTransfer(hDevice, &tt, 9);
mmr came from WD_CardRegister function which gave information about the PCI BARs and their mapped address (mmr is non prefechtable mapped memory).
I would be very grateful if someone could give me some hint about what might cause this problem.
Thanks
I am answering my question in case the problem happened to someone else.
there are sequence of actions which should be taken before using this device.
Warm reset through HDCR Register (set WARMRESET bit).
then the EMIF registers should be initialised, these are the values I used.
struct emif emif_val = {
0x00052078, //GBLCTL;
0x73a28e01, //CE1 Flash/FPGA;
0xffffffd3, //CE0 SDRAM;
0x00000000, //Reserved;
0x22a28a22, //CE2 Daughtercard 32-bit async
0x22a28a42, //CE3 Daughtercard 32-bit sync
0x63115000, //SDRAM contral, 4 banks
0x0000081b, //SDRAM timing
0x001faf4d //SDRAM extended control
};
and then you are able to access all address space of the device without any problem.
and for more information this linux source code could be very helpful

Azure guaranteed memory

We're currently preparing our Azure role (standard Web Role) for an expected massive load, and we need to know how much memory the current setup consumes. To accomplish this, we're using load tests while measuring the consumed memory with GC.GetTotalMemory.
The page http://technet.microsoft.com/en-us/cloud/gg663909.aspx lists the Compute Instance Guaranteed Memory for each instance size (for example, 0.768 GB for the Extra-Small Instance and 3.5 GB for the Medium Instance).
Are the values of GC.GetTotalMemory comparable to the values in these list? In other words, if GC.GetTotalMemory is staying significantly below the listed limit, can we be sure that there won't be any sudden perfomance loss due to memory swapping?
If we hit the limit, is our assumption correct that there will be some memory swapping (writing memory content to the virtual harddisk), or will there be more severe implications like repeated App Pool recycling?
(the last question comes up because most shared hosters will recycle your App Pool if you hit some memory limit, but frankly we don't expect anything like this from Windows Azure)
This method will only give you the currently allocated bytes by your process. The 0.768 GB includes the memory availble to the operating system, and there can be virtual memory as well.
system.gc.gettotalmemory
To get the total system memory you can use:
Add a Reference to System.Management.
private static void DisplayTotalRam()
{
string Query = "SELECT MaxCapacity FROM Win32_PhysicalMemoryArray";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(Query);
foreach (ManagementObject WniPART in searcher.Get())
{
UInt32 SizeinKB = Convert.ToUInt32(WniPART.Properties["MaxCapacity"].Value);
UInt32 SizeinMB = SizeinKB / 1024;
UInt32 SizeinGB = SizeinMB / 1024;
Console.WriteLine("Size in KB: {0}, Size in MB: {1}, Size in GB: {2}", SizeinKB, SizeinMB, SizeinGB);
}
}
Source for code
To answer your last question, Windows Azure will stay out of the way, and paging will happen like on any Windows server.
Whether IIS recycles your app pool probably depends on your IIS settings, but those are under your control. (You can, for example, run appcmd in a startup task if you want to change a default.)

Which event tells you that the device is successfully started

I am making an application that auto starts when the phone restarts. I want to run some events when the phone complets its restart. The UiApp is running even before the device finishes his reset cause I configured the app as an auto start app.
What event should I listen too and that starts when the phone completes the reboot, not in between?
Thanks
It is possible to know if the system is in startup by using :
ApplicationManager.isStartup()
You will need to poll this using a timer till it returns false. However it must be borne in mind that this means that the OS has booted and the system is able to run the application. It does not mean that the entire environment for your application to run is set up completely. For example (as noted by Michael) microSD card might not have been mounted, network connectivity might not been established, or some other service on which your application might depend is not yet available. It's up to you to verify they are available before you begin working of your application.
The approach you need to take is:
Poll if isStartup returns false (System is not in startup phase)
Implement FileSystemListener to check if microSD card is mounted.
Note that mount name for a microSD card is "SDCard".
class FileSystemListenerImpl implements FileSystemListener
{
final static String SDCARD_NAME ="SDCard/";
public FileSystemListenerImpl( )
{
}
public void rootChanged( int state, String rootName )
{
if( state == FileSystemListener.ROOT_ADDED)
{
if( SDCARD_NAME.equals(rootName))
{
_isMicroSDReady=true;
scheduleApplicationStart();
removeFileSystemListener(this);
}
}
else if( state == FileSystemListener.ROOT_REMOVED)
{
}
}
}

Resources