Writing software for dsPIC (R) DSC using Erika Enterprise
This section describes the details about the various configuration options which are available to create and compile an Erika Enterprise application for a dsPIC (R) DSC microcontroller.
1. Avoid the generation of dependency files
The typical compilation process of an Erika Enterprise application involves the computation of a dependency file which is used to understand which are the files which needs to be compiled or updated.
To avoid the computation of these dependencies (useful when you are sure you basically have to compile everything), you can put the following line in the OIL file:
CPU mySystem {
OS myOs {
EE_OPT = " NODEPS ";
...
};
...
};
The typical compilation process of an Erika Enterprise application produces various files which can be used to better analyze the code generated by the C30 compiler. In particular, from each .C file, a .SRC file is produced containing the corresponding assembler listing, which is then compiled by the MPLAB ASM30 compiler to produce the .o.
It is possible to avoid the intermediate step which leads to the production of the .SRC file. In that case, the compiler will be responsible of producing the .O file directly from the .C file. This in general also speeds up the compilation process a little bit. To obtain that feature, you can put the following lines in the OIL file.
CPU mySystem {
OS myOs {
EE_OPT = " NOSRC ";
...
};
...
};
2 Printing the commands executed (verbose mode)
The default compilation process typically prints only a compact output for each compilation step. That is in general not useful whenever a file is not compiled properly and the user wants to know the exact command which is executed in the compilation process. To obtain a printing of the complete list of commands issued by the Erika Enterprise makefile, you can add the following line to the OIL file:
CPU mySystem {
OS myOs {
EE_OPT = " VERBOSE ";
...
};
...
};
3 Source files composing an application
The source files which can be put in an RT-Druid project are composed by C-language files (with extension .c) and Assembler files (with extension .S). Assembler files are always preprocessed by the C preprocessor. All the application files which has to be included in the final application needs to be listed inside the OIL file, as in the following OIL example:
...
CPU_DATA = PIC30 {
...
APP_SRC = " file_1 .c";
APP_SRC = " file_2 .c";
};
...
4 Stack handling
Erika Enterprise can be configured as monostack or multistack. In a monostack configuration, only a single stack exists in the system. No blocking primitives are supported, and all the tasks and interrupts execute on the same stack. In this case, the one and only stack starts from the top of the application allocated memory, growing towards higher addresses. The monostack configuration can not be used if the application needs to call RTOS primitives such as WaitSem and WaitEvent. Moreover, it cannot be used when Erika Enterprise conformance classes ECC1 and ECC2 are used. To configure a monostack kernel in the OIL file, the user has to write the following lines:
...
CPU_DATA = PIC30 {
...
MULTI_STACK = FALSE;
};
...
In a multistack configuration, the kernel support the existence of different stacks in the same application. Having different stacks allow the application tasks to use blocking primitives like WaitSem and WaitEvent, which basically may block the execution of the running task. In that case, the calling task must have a private stack which is changedupon blocking. The stack will be selected again when the task will be rescheduled. There are different stacks available in a multistack configuration:
-
• A shared stack (used by all the tasks which have a shared stack);
• An IRQ stack (used by all the ISR Type 2 routines);
• A set of private stacks (one for each task which has selected a private stack).
In the dsPIC (R) DSC architecture, the shared stack works as in the monostack configuration, that is it is allocated at the end of the application data section, growing towards higher addresses. The IRQ stack and the private stacks, instead, are allocated in the application data space as arrays. The following example shows an OIL configuration which configures a multistack kernel without a separate IRQ stack (in this case, IRQ handlers execute on the stack of the interrupted task):
...
CPU_DATA = PIC30 {
...
MULTI_STACK = TRUE {
IRQ_STACK = FALSE;
};
};
...
The following example shows an OIL configuration which configures a multistack kernel with a separate IRQ stack (in this case, some registers are saved on the stack of the interrupted task, but the IRQ handler C function is executed on a separate IRQ stack).
...
CPU_DATA = PIC30 {
...
MULTI_STACK = TRUE {
IRQ_STACK = TRUE {
SYS_SIZE =64;
};
};
};
...
5 Runtime stack checking exceptions
When multistack configurations are used, it is very useful to be informed when a particular stack becomes full. For this reason, the dsPIC (R) DSC core allows the user to specify a stack limit over which an exception should be raised. The stack limit is contained inside the internal register SPLIM. Erika Enterprise and Erika Enterprise Basic are able to automatically handle the SPLIM register, setting it at runtime to the top of the current stack when a multistack configuration.
The SPLIM feature is by default disabled, because it adds some (little) overhead at each stack change. To enable it, you must include the following lines inside the OIL configuration file:
...
CPU_DATA = PIC30 {
...
ENABLE_SPLIM = TRUE;
};
...
Please note that Erika Enterprise does not provide a default handler for the stack overflow exception generated by the SPLIM register. The exception should be specified by the developer as the behavior to implement is often application dependent.
6 Interrupt handling
Erika Enterprise and Erika Enterprise Basic for dsPIC (R) DSC provide support for fast Interrupt Service Routines (ISR) which do not require any RTOS primitive to be called, as well as regular ISRs, which can call RTOS primitives (e.g., a timer interrupt can call ActivateTask to activate a periodic task). The first kind of ISRs are called ISR Type 1, and always have hardware interrupt priority greater than the second kind of ISRs which are called ISR Type 2.
At the implementation level, Erika Enterprise uses the dsPIC (R) DSC DISI assembler instruction to implement interrupt disabling. The DISI instruction only disables the first 6 priority levels out of the 7 available in the 16-bit dsPIC (R) DSC core. For this reason, ISR Type 2 must always have an interrupt priority between 1 and 6.
ISR Type 1 must always have a priority greater or equal than ISR Type 2. As a matter of fact, interrupt priority 7 is reserved for ISR Type 1 only. ISR names follow the Microchip convention. Basically the ISR names are listed inside the linker script for the particular target which are provided together with the ASM30 assembler packaged together with Microchip MPLAB IDE under the directory
To define an ISR Type 1 the developer has to write an interrupt handler as it is written in typical dsPIC (R) DSC applications which does not use Erika Enterprise. Here is an example of the definition of an ISR Type 1 for the timer 3 Interrupt of a pic30F2010 device:
void __attribute__(( __interrupt__)) _T3Interrupt( void)
{
...
}
Writing an ISR 1 in this way implies that:
-
• The C function will be attached to the interrupt of the peripheral (in the example, timer 3). Every time an interrupt for the peripheral arrives, then the C function will be executed.
• The compiler will generate a proper function prologue and epilogue which saves the register used before starting executing the statements inside the function. The registers will be saved inside the stack of the interrupted task. For that reason, when using a multistack configuration, the user should reserve a proper space able to contain all the nested ISR Type 1 for each stack in the system.
To define an ISR Type 2 the developer has to write a C function in the following way:
# include " cpu/ pic30/ inc/ ee_irqstub.h"
...
ISR2( _T3Interrupt)
{
...
}
Writing an ISR 2 in this way implies that:
-
• An assembler stub will generated for the ISR. The ISR stub will have the name of the ISR (in the example, _T3Interrupt). The assembler stub will call a C function named ISR2_functionname which content is specified as the content of the function (in the example, the function is called ISR2__T3Interrupt). The assembler function will be attached to the interrupt of the peripheral (in the example, timer 3). Every time an interrupt for the peripheral arrives, the assembler stub will execute, which in turns calls the internal C function whose body has been specified by the developer.
• The assembler stub saves all the CPU registers on the current stack. After that, if a multistack configuration with private IRQ stack has been selected, the stack is changed to a private IRQ stack. Otherwise, the ISR will execute on the stack of the running task, as in the ISR1 case. At the end of the stub, the Erika Enterprise end IRQ function will be executed to choose which is the next task to run.
7 Configuring the usage of Microchip ICD2
dsPIC (R) DSC devices can be debugged using the Microchip product called Microchip ICD2, which is basically an In-Circuit debugger which directly connects to the microcontroller core. When connected, the ICD2 requires the usage of a set of memory locations, which must be left free by the application.
For this reason, when compiling an application which will be debugged using the Microchip ICD2, the user has to specify the following line inside the OIL file:
...
CPU_DATA = PIC30 {
...
ICD2 = TRUE;
};
...
8 Configuring a particular dsPIC (R) DSC microcontroller
Microchip produces various versions of the Microchip microcontrollers, each one with different peripherals and memory sizes. To support the heterogeneity of these devices, Microchip offers, through the C30 Compiler toolchain, a set of files which can be used to configure the compiling process.
In particular, for each device, there are four files:
-
• A linker script, available under the directory Support/gld of the Microchip ASM30 Assembler, which contains the linking information such as the memory sizes, and the available interrupt handlers;
• An Assembler include file, available under the directory Support/inc of the Microchip ASM30 Assembler, which contains the declaration of the device’s register addresses to be used inside assembler programs;
• A C include file, available under the directory support/h of the Microchip C30 Compiler, which contains the declaration of the device’s addresses to be used inside C programs;
• A library, available under the directory lib of the Microchip C30 compiler, which contains a set of libraries for the usage of the microcontroller peripherals. Every Erika Enterprise application which has to be compiled together with the Microchip C30 compiler needs the specification of these four files. To set which files have to be used for the particular device, the user can specify the following lines inside the OIL file.
If the device number is known, and the files to be used are the default files provided by Microchip, then the developer can directly specify the device name in the OIL file, as in the following example:
...
MCU_DATA = PIC30 {
MODEL = PIC33FJ256GP710;
};
...
Currently, Erika Enterprise supports the following values for the MODEL attribute:
• PIC24 devices:
PIC24FJ128GA006, PIC24FJ128GA008,
PIC24FJ128GA010, PIC24FJ32GA002,
PIC24FJ32GA004, PIC24FJ64GA002,
PIC24FJ64GA004, PIC24FJ64GA006,
PIC24FJ64GA008, PIC24FJ64GA010,
PIC24FJ96GA006, PIC24FJ96GA008,
PIC24FJ96GA010, PIC24HJ128GP206,
PIC24HJ128GP210, PIC24HJ128GP306,
PIC24HJ128GP310, PIC24HJ128GP506,
PIC24HJ128GP510, PIC24HJ256GP206,
PIC24HJ256GP210, PIC24HJ256GP610,
PIC24HJ64GP206, PIC24HJ64GP210,
PIC24HJ64GP506, PIC24HJ64GP510.
• PIC30 devices:
PIC30F1010, PIC30F2010,
PIC30F2011, PIC30F2012,
PIC30F2020, PIC30F2021,
PIC30F2022, PIC30F2023,
PIC30F3010, PIC30F3011,
PIC30F3012, PIC30F3013,
PIC30F3014, PIC30F4011,
PIC30F4012, PIC30F4013,
PIC30F5011, PIC30F5013,
PIC30F5015, PIC30F5016,
PIC30F6010, PIC30F6010A,
PIC30F6011, PIC30F6011A,
PIC30F6012, PIC30F6012A,
PIC30F6013, PIC30F6013A,
PIC30F6014, PIC30F6014A,
PIC30F6015.
• PIC33 devices:
PIC33FJ128GP206, PIC33FJ128GP306,
PIC33FJ128GP310, PIC33FJ128GP706,
PIC33FJ128GP708, PIC33FJ128GP710,
PIC33FJ128MC506, PIC33FJ128MC510,
PIC33FJ128MC706, PIC33FJ128MC708,
PIC33FJ128MC710, PIC33FJ256GP506,
PIC33FJ256GP510, PIC33FJ256GP710,
PIC33FJ256MC510, PIC33FJ256MC710,
PIC33FJ64GP206, PIC33FJ64GP306,
PIC33FJ64GP310, PIC33FJ64GP706,
PIC33FJ64GP708, PIC33FJ64GP710,
PIC33FJ64MC506, PIC33FJ64MC508,
PIC33FJ64MC510, PIC33FJ64MC706,
PIC33FJ64MC710.
Please note that we did not have the possibility to directly test all the possible devices produced by Microchip. In general this is not a problem, because the various devices are directly mapped to appropriate compiler flags. The following is the list of devices we tested directly: PIC30F2010, PIC30F6014A, PIC33FJ256GP710, PIC24FJ128GA010, which basically are the devices mounted on the Microchip Evaluation boards supported by Erika Enterprise.
If the device is not supported by the particular version of RT-Druid or if the developer needs to use a custom file, then the four files can be specified separately as in the following example:
...
MCU_DATA = PIC30 {
MODEL = CUSTOM {
LINKERSCRIPT = " p33FJ256GP710. gld ";
DEV_LIB = " libp33FJ256GP710 - elf.a";
INCLUDE_C = " p33FJ256GP710.h";
INCLUDE_S = " p33FJ256GP710.inc ";
};
};
...
As a result of this specification, the correct include files, libraries and linker scripts will be used when compiling an Erika Enterprise application.
Read about Erika enterprise
Also:
http://dev.emcelettronica.com/how-does-erika-enterprise-support-flex-boa...
http://dev.emcelettronica.com/how-to-configure-edf-scheduler
- Chris's blog
- 1949 reads





Post new comment