Using Microchip C18 compiler with a pic18f, I want to create a "big" buffer of 3000 bytes in the program data space.
If i put this in the main() (on stack):
char tab[127];
I have this error:
Error [1300] stack frame too large
If I put it in global, I have this error:
Error - section '.udata_main.o' can not fit the section. Section '.udata_main.o' length=0x0000007f
How to create a big buffer? Do you have tutorial on how to manage big buffer on pic18f with c18?
Here's a tutorial on exactly this: http://www.dwengo.org/tips-tricks/large-variables
Basically, you declare your variable in a special section, and a pointer to it in the default section:
#pragma udata DATA // section DATA
int large_table[768];
#pragma udata // return to default section
int *table_ptr = &large_table[0];
Next, you update the linker script to define the large section by adding something like this:
DATABANK NAME=data START=0x200 END=0x7FF PROTECTED
SECTION NAME=DATA RAM=data
Note that there usually isn't any unmapped memory in which you can just put your DATA section, but the USB buffers are usually my first choice to canibalize (unless you need USB in the same project of course...)
Related
I am currently trying my first dynamic parallelism code in CUDA. It is pretty simple. In the parent kernel I am doing something like this:
int aPayloads[32];
// Compute aPayloads start values here
int* aGlobalPayloads = nullptr;
cudaMalloc(&aGlobalPayloads, (sizeof(int) *32));
cudaMemcpyAsync(aGlobalPayloads, aPayloads, (sizeof(int)*32), cudaMemcpyDeviceToDevice));
mykernel<<<1, 1>>>(aGlobalPayloads); // Modifies data in aGlobalPayloads
cudaDeviceSynchronize();
// Access results in payload array here
Assuming that I do things right so far, what is the fastest way to access the results in aGlobalPayloads after kernel execution? (I tried cudaMemcpy() to copy aGlobalPayloads back to aPayloads but cudaMemcpy() is not allowed in device code).
You can directly access the data in aGlobalPayloads from your parent kernel code, without any copying:
mykernel<<<1, 1>>>(aGlobalPayloads); // Modifies data in aGlobalPayloads
cudaDeviceSynchronize();
int myval = aGlobalPayloads[0];
I'd encourage careful error checking (Read the whole accepted answer here). You do it in device code the same way as in host code. The programming guide states: "May not pass in local or shared memory pointers". Your usage of aPayloads is a local memory pointer.
If for some reason you want that data to be explicitly put back in your local array, you can use in-kernel memcpy for that:
memcpy(aPayloads, aGlobalPayloads, sizeof(int)*32);
int myval = aPayloads[0]; // retrieves the same value
(that is also how I would fix the issue I mention in item 2 - use in-kernel memcpy)
so, i was trying to read a DLL file, everything was fine till i reach the Optional Header Data Directories, specifically its first member, the Export Table.
My problem is that i can't move the offset of my reader because the virtual address member is based on memory VA, and my reader is based on file offset. May a visual example helps:
As you can see, the loaded virtual address that this PE viewer reads at the Export Table Address from the Data Directory(Optional Header) is the value 0x00002630(lets refer to it as hex1 from now on).
However, when i click on the Export Table to see the actual content, the program does the conversion of this address from memory to file offset, redirecting me to this address as the result:
The address that it redirects me is the 0x00001a30(lets refer to it as hex2 from now on).
I did some tests on my own like dividing the hex1 per 8 because i thought it could be the transition from memory alignment which is 4096 and the file alignment which is 512 but it didn't gave me the same result as hex2. I also did some weird stuff to try to get that formula, but it gave me even more bizarre results.
So, my question would be, how could i get/calculate that file offset(hex2) if i only know the memory offset at the Data Directory(hex1)?
Assuming you are using MSVC C/C++, you first need to locate the array of IMAGE_SECTION_HEADER structures following the Optional Header. The SDK has a macro called IMAGE_FIRST_SECTION(pNtHeaders) in which you just pass the pointer of your PE header to make this process easier. It basically just skips past the optional header in memory which is where the section headers start. This macro will also work on either 32-bit or 64-bit Windows PE files.
Once you have the address of the IMAGE_SECTION_HEADER array, you loop through the structures up to FileHeader.NumberOfSections using pointer math. Each of the structures describe the relative starting of a memory address (VirtualAddress) for each of the named PE sections along with the file offset (PointerToRawData) to that section within the file you have loaded.
The size of the section WITHIN the file is SizeOfRawData. At this point, you now have everything you need to translate any given RVA to a file offset. First range check each IMAGE_SECTION_HEADER's VirtualAddress with the RVA you are looking up. I.e.:
if (uRva >= pSect->VirtualAddress && (uRva < (pSect->VirtualAddress + pSect->SizeOfRawData))
{
//found
}
If you find a matching section, you then subtract the VirtualAddress from your lookup RVA, then add the PointerToRawData offset:
uFileOffset = uRva - pSect->VirtualAddress + pSect->PointerToRawData
This results in an offset from the beginning of the file corresponding to that RVA. At this point you have translated the RVA to a file offset.
NOTE: Due to padding, incorrect PE files, etc., you may find not all RVAs will map to a location within the file at which point you might display an error message.
im producing 100 remote controls using pic16f1823 and i need unique id for each remote but it should be constant over time so i think its better to generate a random before programming in mplab compiler and then compile these 100 remotes
i want not to change the remote_id manually
#include "mcc_generated_files/mcc.h"
#define remote_id 33800
char col;
uint24_t data_out;
void Reset_state(void);
int Key(void);
int Key_prime(void);
void main(void)
{...
please help me in this problem
It should be possible to use SQTP mode with the IPE as described here.
http://microchipdeveloper.com/ipe:serial-quick-turn-programming-sqtp-settings
Can you have a script in production that alters the ihex file so
that your serial number would appear different in EEPROM (EE) as most pics have 1k of internal EE for data storage ?
Then the remote would read its unique serial number from EE locations.
This would be a simple job for `gawk' say...
Use the SQTP functionality in the MPLAB IPE. You need to enter 'advanced mode' and sign into the IPE first.
In the SQTP tab, set it to save the values in EEPROM, as 'Raw Data', at memory address 0x00. Press 'Generate' and it will write an sqtp file for you.
Select the SQTP file in the 'operate' tab, under the field where you select your .hex file.
Every time you flash a new mcu, the IPE will increment to the next value in the SQTP file, and will even keep track between sessions.
you can use this in your code to retrieve the data:
unsigned char EEPROM_ReadByte(unsigned char eepromAddress)
{
while(RD || WR); // check the WR&RD bit to see if a RD/WR is in progress
EEADR=eepromAddress; // Write the address to EEADR.
RD = 1; // Set the RD bit to trigger the eeprom read operation.
return(EEDATA); // Return the data read form eeprom.
}
Call EEPROM_ReadByte, passing in 0x00, and it will return one char from your data. Increment eepromAddress and it will return the second char, etc.
Note that your data will be in reverse order, I am not sure why, it is perhaps due to the way SQTP files are encoded.
I have some firmware built with GCC that runs on an ARM Cortex M0 based microcontroller. The build currently generates a single binary image that can be written into the program memory of the microcontroller.
For reasons to do with field update, I need to split this image into two parts that can be updated separately. I'll call these Core and App.
Core: contains the interrupt vector table, main() routine, and various drivers and library routines. It will be located in the first half of the program memory.
App: contains application-specific code. It will be located in the second half of the program memory. It will have a single entry point, at a known address, which is called by the core to start the application. It will access functions and data in the core via known addresses.
There are some obvious limitations here, which I'm well aware of:
When building the app, the addresses of symbols in the core will need to be known. So the core must be built first, and must be available when linking the app.
An app image will only be compatible with the specific core image it was built against.
It will be possible to update the app without updating the core, but not vice versa.
All of that is OK.
My question is simply, how can I build these images using GCC and the GNU binutils?
Essentially I want to build the core like a normal firmware image, and then build the app image, with the app treating the core like a library. But neither shared linking (which would require a dynamic linking mechanism) or static linking (which would copy the core functions used into the app binary) are applicable here. What I'm trying to do is actually a lot simpler: link against an existing binary using its known, fixed addresses. It's just not clear to me how to do so with the tools.
We have this working now so I am going to answer my own question. Here is what was necessary to do this, starting from a normal single image build, turning that into the "core" and then setting up the build for the "app".
Decide how to split up both the flash and the RAM into separate areas for the core and the app. Define the start address and size of each area.
Create a linker script for the core. This will be the same as the standard linker script for the platform except that it must only use the areas reserved for the core. This can be done by changing the ORIGIN and LENGTH of the flash & RAM entries in the MEMORY section of the linker script.
Create a header file declaring the entry point for the app. This just needs a prototype e.g.:
void app_init(void);.
Include this header from the core C code and have the core call app_init() to start the app.
Create a symbol file declaring the address of the entry point, which will be the start address of the flash area for the app. I'll call this app.sym. It can just be one line in the following format:
app_init = 0x00010000;
Build the core, using the core linker script and adding --just-symbols=app.sym to the linker parameters to give the address of app_init. Retain the ELF file from the build, which I'll call core.elf.
Create a linker script for the app. This will again be based on the standard linker script for the platform, but with the flash & RAM memory ranges changed to those reserved for the app. Additionally, it will need a special section to ensure that app_init is placed at the start of the app flash area, before the rest of the code in the .text section:
SECTIONS
{
.text :
{
KEEP(*(.app_init))
*(.text*)
Write the app_init function. This will need to be in assembly, as it must do some low level work before any C code in the app can be called. It will need to be marked with .section .app_init so that the linker puts it in the correct place at the start of the app flash area. The app_init function needs to:
Populate variables in the app's .data section with initial values from flash.
Set variables in the app's .bss section to zero.
Call the C entry point for the app, which I'll call app_start().
Write the app_start() function that starts the app.
Build the app, using the app linker script. This link step should be passed the object files containing app_init, app_start, and any code called by app_start that is not already in the core. The linker parameter --just-symbols=core.elf should be passed to link functions in the core by their addresses. Additionally, -nostartfiles should be passed to leave out the normal C runtime startup code.
It took a while to figure all this out but it is now working nicely.
First of all... if this is just for field updating, you don't need to rely on the interrupt vector table in the core space for the app. I think ARM M0 parts always have the ability to move it. I know it can be done on some (all?) the STM32Fx stuff, but I believe this is an ARM M-x thing, not an ST thing. Look into this before committing yourself to the decision to make your application ISRs all be hooks called from the core.
If you plan on having a lot of interaction with your core (btw, I always call the piece that does self-updating a "bootloader" on MCUs), here's an alternate suggestion:
Have the Core pass a pointer to a struct / table of functions that describes its capabilities into the App entry point?
This would allow complete separation of the code for the app vs core except for a shared header (assuming your ABI doesn't change) and prevent name collisions.
It also provides a reasonable way to prevent GCC from optimizing away any functions that you might call only from the App without messing up your optimization settings or screwing around with pragmas.
core.h:
struct core_functions
{
int (*pcore_func1)(int a, int b);
void (*pcore_func2)(void);
};
core.c:
int core_func1(int a, int b){ return a + b; }
void core_func2(void){ // do something here }
static const struct core_functions cfuncs=
{
core_func1,
core_func2
};
void core_main()
{
// do setup here
void (app_entry*)(const struct core_functions *) = ENTRY_POINT;
app_entry( &cfuncs );
}
app.c
void app_main(const struct core_functions * core)
{
int res;
res = core->pcore_func1(20, 30);
}
The downside / cost is a slight runtime & memory overhead and more code.
I am porting a program for an ARM chip from a IAR compiler to gcc.
In the original code, IAR specific operators such as __segment_begin and __segment_size are used to obtain the beginning and size respectively of certain memory segments.
Is there any way to do the same thing with GCC? I've searched the GCC manual but was unable to find anything relevant.
More details:
The memory segments in question have to be in fixed locations so that the program can interface correctly with certain peripherals on the chip. The original code uses the __segment_begin operator to get the address of this memory and the __segment_size to ensure that it doesn't overflow this memory.
I can achieve the same functionality by adding variables to indicate the start and end of these memory segments but if GCC had similar operators that would help minimise the amount of compiler dependent code I end up having to write and maintain.
What about the linker's flag --section-start? Which I read is supported here.
An example on how to use it can be found on the AVR Freaks Forum:
const char __attribute__((section (".honk"))) ProjString[16] = "MY PROJECT V1.1";
You will then have to add to the linker's options: -Wl,--section-start=.honk=address.
Modern versions of GCC will declare two variables for each segment, namely __start_MY_SEGMENT and __stop_MY_SEGMENT. To use these variables, you need to declare them as externs with the desired type. Following that, you and then use the '&' operator to get the address of the start and end of that segment.
extern uint8_t __start_MY_SEGMENT;
extern uint8_t __stop_MY_SEGMENT;
#define MY_SEGMENT_LEN (&__stop_MY_SEGMENT - &__start_MY_SEGMENT)