using the uvision IDE for STM32 development, I want to have some timer variables not initialized at startup. I have tried:
volatile unsigned int system_time __attribute__((section(".noinit")));
and
__attribute__((zero_init)) volatile int system_timer;
but nothing seems to work. Following the hints from elswhere, I have additionally checked NoInit at options/target/IRAM1.
Still, the variables are set to zero after reset.
Can anybody help?
You need to follow these steps.
declare your variable as follows:
volatile unsigned int system_time __attribute__((section(".noinit"),zero_init));
Then you have to use a scatter file to declare the execution section with the NOINIT attribute and use it with the linker.
example scatter file:
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 UNINIT 0x00000100 { ;no init section
*(.noinit)
}
RW_IRAM2 0x20000100 0x0000FFF0 { ;all other rw data
.ANY(+RW +ZI)
}
}
You have to check the address of that variable from .MAP file and use the The at keyword
allows you to specify the address for uninitialized variables in your C source files. The
following example demonstrates how to locate several different variable types using the at keyword.for example......
struct link {
struct link idata *next;
char code *test;
};
struct link idata list _at_ 0x40; /* list at idata 0x40 */
char xdata text[256] _at_ 0xE000; /* array at xdata 0xE000 */
int xdata i1 _at_ 0x8000; /* int at xdata 0x8000 */
char far ftext[256] _at_ 0x02E000; /* array at xdata 0x03E000 */
void main ( void ) {
link.next = (void *) 0;
i1 = 0x1234;
text [0] = 'a';
ftext[0] = 'f';
}
I hope it helps for solving your problem.
Related
I have a microblaze instantiated with 16 stream interfaces with a custom IP attached to two. What is the correct header file or function to communicate over these interfaces in Vitis (Not HLS)?
Based on the full example that you can find here, I am going to provide a general idea:
Include the mb_interface.h in your C source
Use the putfsl and getfsl macros to write and read from the stream.
Such macros are wrapper around special assembly instructions that the microblaze will execute by writing the data on the axi stream interface. The ìd is the stream id. Here you can find all the possible functions and here you can explore the ISA.
#define putfsl(val, id) asm volatile ("put\t%0,rfsl" stringify(id) :: "d" (val))
The fundamental issue is that
#include "mb_interface.h"
/*
* Write 4 32-bit words.
*/
static void inline write_axis(volatile unsigned int *a)
{
register int a0, a1, a2, a3;
a3 = a[3]; a1 = a[1]; a2 = a[2]; a0 = a[0];
putfsl(a0, 0); putfsl(a1, 0); putfsl(a2, 0); putfsl(a3, 0);
}
int main()
{
volatile unsigned int outbuffer[BUFFER_SIZE] = { 0x0, 0x1, 0x2, 0x3 }
};
/* Perform transfers */
write_axis(outbuffer);
return 0;
}
I am creating a project in Swift. I want to display the modelName. I am following below link to get the modelName
http://myiosdevelopment.blogspot.co.uk/2012/11/getting-device-model-number-whether-its.html
The code in the link is written in objective-c. But I am not sure how to import this in Swift.
#import <sys/utsname.h>
Please someone help
sys/utsname.h is imported into Swift by default, so you don't really need to import it from the bridging header. But using utsname from Swift is really painful though, as Swift imports fixed length C array as tuples. If you look into utsname.h, you see that the C struct members of utsname are all char array of 256 length:
#define _SYS_NAMELEN 256
struct utsname {
char sysname[_SYS_NAMELEN]; /* [XSI] Name of OS */
char nodename[_SYS_NAMELEN]; /* [XSI] Name of this network node */
char release[_SYS_NAMELEN]; /* [XSI] Release level */
char version[_SYS_NAMELEN]; /* [XSI] Version level */
char machine[_SYS_NAMELEN]; /* [XSI] Hardware type */
};
Which gets imported into Swift like this:
var _SYS_NAMELEN: Int32 { get }
struct utsname {
var sysname: (Int8, Int8, /* ... 254 more times "Int8, " here ... */) /* [XSI] Name of OS */
var nodename: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Name of this network node */
var release: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Release level */
var version: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Version level */
var machine: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Hardware type */
}
Yes, they're tuples with 256 Int8s. Which cases this hilarious autocompletion in Xcode:
Currently, there is no way to initialize an tuple in Swift without writing out all value, so initializing it as a local variable would be rather verbose, as you see above. There is also no way to convert the tuple to an array, so that huge tuple is also not very useful.
The easiest solution would be to implement it in Objective-C.
If you're dead set on using Swift, you can do this, but it's not pretty:
// Declare an array that can hold the bytes required to store `utsname`, initilized
// with zeros. We do this to get a chunk of memory that is freed upon return of
// the method
var sysInfo: [CChar] = Array(count: sizeof(utsname), repeatedValue: 0)
// We need to get to the underlying memory of the array:
let machine = sysInfo.withUnsafeMutableBufferPointer { (inout ptr: UnsafeMutableBufferPointer<CChar>) -> String in
// Call uname and let it write into the memory Swift allocated for the array
uname(UnsafeMutablePointer<utsname>(ptr.baseAddress))
// Now here is the ugly part: `machine` is the 5th member of `utsname` and
// each member member is `_SYS_NAMELEN` sized. We skip the the first 4 members
// of the struct which will land us at the memory address of the `machine`
// member
let machinePtr = advance(ptr.baseAddress, Int(_SYS_NAMELEN * 4))
// Create a Swift string from the C string
return String.fromCString(machinePtr)!
}
In Swift 4 you can just use the UIDevice model property:
func getPhoneModel() -> String {
return UIDevice.current.model
}
my 2 cents for Swift 5 if You want to call utsname:
func platform() -> String {
var systemInfo = utsname()
uname(&systemInfo)
let size = Int(_SYS_NAMELEN) // is 32, but posix AND its init is 256....
let s = withUnsafeMutablePointer(to: &systemInfo.machine) {p in
p.withMemoryRebound(to: CChar.self, capacity: size, {p2 in
return String(cString: p2)
})
}
return s
}
The code shown in that blog post looks like C and not Objective C - however I think you can write a wrapper around that in Objective-C
In order to enable bridging between Objective-C and swift just add a new Objective-C file to your project - Xcode will prompt you whether to create a bridging header
Just answer yes, and Xcode will automatically create a <appname>-Bridging-Header.h file. Open it and #include any objective-c header file that you want to use from swift.
In swift 2.0:
var sysInfo: [CChar] = Array(count: sizeof(utsname), repeatedValue: 0)
let deviceModel = sysInfo.withUnsafeMutableBufferPointer { (inout ptr: UnsafeMutableBufferPointer<CChar>) -> String in
uname(UnsafeMutablePointer<utsname>(ptr.baseAddress))
let machinePtr = ptr.baseAddress.advancedBy(Int(_SYS_NAMELEN * 4))
return String.fromCString(machinePtr)!
}
print(deviceModel)
In every example I saw that tries to use a dynamic size for an array in a struct uses global constants at some point. What I am trying to do is pass an integer variable that is decided by the user to a structure that I create storing an array of that size, thus dynamic. Obviously the code below doesn't work, but it gives you an idea of what I plan on accomplishing
struct Node {
char input;
int playingBoard[size];
Node* pNext;
};
int main(){
cout<<"enter board size"<<endl;
cin>>size;
int playingBoard[size];
}
struct Node
{
int countr;
int playingBoard[];
};
int countr;
...
struct Node *p = malloc(offsetof(Node, playingBoard) +
countr* sizeof *p->playingBoard);
p->countr= countr;
...
or an independent dynamically-allocated array
struct Node
{
int countr;
int *playingBoard;
};
Node holder;
...
holder.playingBoard =
malloc(holder.countr * sizeof *holder.playingBoard);
I'm looking for a programatic way to find the powerpc cpu type on Linux. Performing some google searches associated an answer suggesting the mfpvr instruction I found that this is available in the ELF AUX header, and sure enough I can obtain the POWER5 string for the machine I'm running on with the following:
#include <stdio.h>
#include <elf.h>
int main( int argc, char **argv, char **envp )
{
/* walk past all env pointers */
while ( *envp++ != NULL )
;
/* and find ELF auxiliary vectors (if this was an ELF binary) */
#if 0
Elf32_auxv_t * auxv = (Elf32_auxv_t *) envp ;
#else
Elf64_auxv_t * auxv = (Elf64_auxv_t *) envp ;
#endif
char * platform = NULL ;
for ( ; auxv->a_type != AT_NULL ; auxv++ )
{
if ( auxv->a_type == AT_PLATFORM )
{
platform = (char *)auxv->a_un.a_val ;
break;
}
}
if ( platform )
{
printf( "%s\n", platform ) ;
}
return 0 ;
}
In the shared library context where I want to use this info I have no access to envp. Is there an alternate programatic method to find the beginning of the ELF AUX header?
You can get if from /proc/self/auxv file
According to man proc /proc/self/auxv is available since kernel level 2.6.0-test7.
Another option - get some (existing) environment variable - let say HOME,
or PATH, or whatever. Please note that you'll get it's ADDRESS. From here you can go back and find previous env variable, then one before it, etc. After that you can likewise skip all argv arguments. And then you get to the last AUXV entry. Some steps back - and you should be able find your AT_PLATFORM.
EDIT: It looks like glibc now provides a programatic method to get at this info:
glibc-headers-2.17-106: /usr/include/sys/auxv.h : getauxinfo()
Example:
#include <sys/auxv.h>
#include <stdio.h>
int main()
{
unsigned long v = getauxval( AT_PLATFORM ) ;
printf( "%s\n", (char *)v ) ;
return 0 ;
}
I am trying to code an alternative to LoadLibrary function, based on the idea of calling the function LdrLoadDll from ntdll.
This function needs as a parameter the dll file to load, in a UNICODE_STRING format.
I really can't get what I am doing wrong here (string seems to be correctly initialized), but when LdrLoadDll is called, I get the following error:
Unhandled exception in "Test.exe" (NTDLL.DLL): 0xC0000005: Access Violation.
I use Visual C++ 6.0 for this test, and I am using Windows 7 64 bit.
I post full code here, thanks in advance for any help:
#include <Windows.h>
typedef LONG NTSTATUS; //To be used with VC++ 6, since NTSTATUS type is not defined
typedef struct _UNICODE_STRING { //UNICODE_STRING structure
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef NTSTATUS (WINAPI *fLdrLoadDll) //LdrLoadDll function prototype
(
IN PWCHAR PathToFile OPTIONAL,
IN ULONG Flags OPTIONAL,
IN PUNICODE_STRING ModuleFileName,
OUT PHANDLE ModuleHandle
);
/**************************************************************************
* RtlInitUnicodeString (NTDLL.#)
*
* Initializes a buffered unicode string.
*
* RETURNS
* Nothing.
*
* NOTES
* Assigns source to target->Buffer. The length of source is assigned to
* target->Length and target->MaximumLength. If source is NULL the length
* of source is assumed to be 0.
*/
void WINAPI RtlInitUnicodeString(
PUNICODE_STRING target, /* [I/O] Buffered unicode string to be initialized */
PCWSTR source) /* [I] '\0' terminated unicode string used to initialize target */
{
if ((target->Buffer = (PWSTR) source))
{
unsigned int length = lstrlenW(source) * sizeof(WCHAR);
if (length > 0xfffc)
length = 0xfffc;
target->Length = length;
target->MaximumLength = target->Length + sizeof(WCHAR);
}
else target->Length = target->MaximumLength = 0;
}
NTSTATUS LoadDll( LPCSTR lpFileName)
{
HMODULE hmodule = GetModuleHandleA("ntdll.dll");
fLdrLoadDll _LdrLoadDll = (fLdrLoadDll) GetProcAddress ( hmodule, "LdrLoadDll" );
int AnsiLen = lstrlenA(lpFileName);
BSTR WideStr = SysAllocStringLen(NULL, AnsiLen);
::MultiByteToWideChar(CP_ACP, 0, lpFileName, AnsiLen, WideStr, AnsiLen);
UNICODE_STRING usDllFile;
RtlInitUnicodeString(&usDllFile, WideStr); //Initialize UNICODE_STRING for LdrLoadDll function
::SysFreeString(WideStr);
NTSTATUS result = _LdrLoadDll(NULL, LOAD_WITH_ALTERED_SEARCH_PATH, &usDllFile,0); //Error on this line!
return result;
}
void main()
{
LoadDll("Kernel32.dll");
}
in
_LdrLoadDll(NULL, LOAD_WITH_ALTERED_SEARCH_PATH, &usDllFile,0);
last parameter can't be zero
you can't call SysFreeString before you call _LdrLoadDll,
since the usDllFile.buffer parameter points to this string