CCS News RSS

Click here to view the PDF newsletters. Interested in receiving our newsletters in your inbox? Click here to subscribe.

Extreme Code Optimizer

Thursday 24 June, 2021

If you have a version 5 compiler there is an optimization feature you may not be aware of. For many chips there is an aggressive code optimizer available, optimizing for space instead of speed. The optimizer is able to search the entire compiled program to find repeating blocks of code whereby reducing all those repeating blocks into one shared sub-routine. Optimizer is executed during the final phase of the compile which presents the ability to cross a function boundary when performing the optimization. This can only be done on parts with a flexible call instruction and available stack, for example the PIC18 and PIC24 families of devices.

This optimization level can be achieved by adding this line of code into your project.
#opt compress

The average size reduction of program memory is approximately 15%. In some cases we have seen program memory reduced by 60%. Provided below are examples of compression levels:



Consider this example. When a program that passes &n seven times to two functions and the code needed to do that takes 6 instructions. On the right we show the normal optimization and on the right #opt compress.



For more information on other advanced Version 5 features please visit: www.ccsinfo.com/version5



Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

ADC2

Monday 17 May, 2021

Microchip has some chips out that they call ADC2. This is the ADC module with a computational unit. In addition to legacy mode of operation, the ADC2 module can be setup in Accumulate, Average, Burst Average or Low-Pass Filter modes of operation. When setup for Accumulate mode with each trigger of the ADC, the conversion result is added to the accumulator and the ADCNT register is incremented. When setup for Average mode with each trigger of the ADC the conversion result is added to the accumulator and when the specified number of triggers has been done, the average will be preformed on the accumulator. When setup for Burst Average mode, it is similar to Average mode the difference being that when the ADC is triggered, it will perform the specified number of conversions and then perform the average calculation. When setup for Low-Pass Filter mode with each trigger of the ADC, the conversion result is sent through the filter.

To support these modes of operation, the CCS C Compiler's built-in setup_adc() function has an optional 2nd and 3rd parameter to set some parameters when using these the new modes of operation. When using Accumulate, Average or Burst Average modes the 2nd parameter sets how much the accumulated value is divided by after each conversion. When using Low-Pass Filter mode the 2nd parameter sets the cut-off frequency of the filter. The 3rd parameter to the function sets the number of samples to be done before performing a threshold comparison for Average, Burst Average and Low-Pass Filter modes of operation.

In addition to the updates to the setup_adc() function, the built-in functions adc_write() and adc_read() have been added to write and read some the other registers used by the ADC2 module. For example when setup for Low-Pass Filter mode, the filtered result is stored in the ADFLTRH and ADFLTRL registers. After the calculation is completed the adc_read() function can be then be used to read the filtered result, for example:

Result = adc_read(ADC_FILTER);

Another feature of the ADC2 module is the ability to set a trigger source to start a conversion. To support this feature the built-in function set_adc_trigger() has been added to the CCS C Compiler. For example the following can be used to setup the ADC2 module to trigger the conversion when Timer 2 period match occurs:

set_adc_trigger(ADC_TRIGGER_TIMER2);

The following is an example using the CCS C Compiler to setup and use the ADC2 module for Low-Pass Filter mode, see ex_lowpass_filter_adc2.c in the PICCExamples folder for entire example:

setup_timer_2(T2_CLK_INTERNAL | T2_DIV_BY_128, 155, 10);

//~10ms period, 100ms interrupt

setup_adc_ports(ADC_PIN, VSS_VDD);
setup_adc(ADC_LOW_PASS_FILTER_MODE | ADC_CLOCK_INTERNAL |
ADC_TAD_MUL_255 | ADC_THRESHOLD_INT_END_OF_CALCULATION,
FILTER_CUT_OFF_FREQ, ADC_READINGS);

set_adc_channel(ADC_CHANNEL);
set_adc_trigger(ADC_TRIGGER_TIMER2);

while(TRUE)
{
if(interrupt_active(INT_AD_THRESHOLD))
{
FilteredResult= adc_read(ADC_FILTER);
clear_interrupt(INT_AD_THRESHOLD);
}
}

Conditioning ADC data has become a standard requirement for dealing with analog voltages. Even a small amount of noise can disrupt your application. The ADC2 modules can save a lot of processing time to automate the most common filtering operations. See the ex_adc2_trigger.c example program in the compiler example directory for a full program.



Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Introduction to the EZ App Lynx Library

Monday 17 May, 2021

The EZ App Lynx compiler library, Android Application, and iOS Application can add some neat capabilities to your PIC® MCU project. With a Bluetooth® interface, this allows a user's embedded project to interface to a smart device.



The technique used to do this does not require to write an app for the phone. In the above diagram, the micro sends the text to display on the initially blank screen. It then requests a button be put on the screen. The generic app available from CCS simply does anything the PIC® MCU tells it to.



The same certified app available in the smart device stores (for free) can be used for any number of PIC® MCU programs. Each program makes the display and operation it's own. Graphics and logs can be sent to the smart device or you can required the app download the images from the web.



At the PIC® MCU, a simple library is used call EZ APP LYNX and is included with all IDE compilers. An example program looks like this:

void main(void) {
ezapp_field_index_t pot;
EZAppInit(); //EZ App Lynx API

pot = EZAppAddFieldAnalogValueScaled(
"POT_A1",
EZAPP_ANALOG_TYPE_GAS_GAUGE,
0, //min
1023, //max
330, //scaling
2 //decimal points, 3.30
);

for(;;) {
EZAppTask(); //EZ App Lynx API to keep Bluetooth up
EZAppSetValue(pot, read_adc());
}
}

The library has a number of buttons, indicators, sliders and much more. Here is an example inserting a background on the smart device display:



Charts and graphics are easy to do as well:
An easy way to get started is using the development kit that includes a plug in Bluetooth® module, ready to start communicating with a smart device.



More information about EZ App Lynx, visit: http://www.ccsinfo.com/content.php?page=ez-app





Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Programmable Switch Mode Controller (PSMC)

Monday 17 May, 2021

Pulse Width Modulation (PWM) capability was first added to the PIC® microcontroller line using the Capture/Compare/PWM (CCP) unit. Since then we have seen the enhanced CCP (ECCP) and a variety of power and motor control PWM modules each with its own features. The PWM module is called the Programmable Switch Mode Controller (PSMC). This is the most sophisticated PWM yet and is on chips like the PIC16F1789.

The PSMC allows for standard PWM, complementary PWM, shutdown control and deadband control like some of the older modules. It also allows for high resolution on the duty and frequency, as well variable frequency. It can for example do 3 phase 6 step PWM.

Input pins, comparator outputs and CCP triggers can be used not only to control shutdown, but to control if the PWM is running, or to start or stop a cycle.

Some PIC® MCU devices have as many as 4 independent units and the units can optionally be synchronized with each other.

The compiler functions are:
setup_psmc(unit, mode, period, period_time,
rising_edge, rise_time,
falling_edge, fall_time);

psmc_pins(unit, pins_used, pins_active_low);

psmc_duty(unit, fall_time);

psmc_deadband(unit, rising_edge, falling_edge);

psmc_blanking(unit, rising_edge, rise_time, falling_edge, fall_time);

psmc_shutdown(unit, option, source, pins_high);

psmc_freq_adjust(unit, freq_adjust);

psmc_modulation(unit, options);

psmc_sync(slave_unit, master_unit, options);

The following is a short example program that shows off some of the features:
#include <16f1789.h>
#use delay(osc=20mhz)

#define us(time) (int16)(time*(getenv("CLOCK")/1000000))

void main(void) {

setup_psmc(1, PSMC_ECCP_BRIDGE_FORWARD,
PSMC_EVENT_TIME | PSMC_SOURCE_FOSC | PSMC_DIV_2, us(100),
PSMC_EVENT_TIME, us(10),
PSMC_EVENT_TIME, us(35));

psmc_deadband(1, us(2), us(4));
psmc_modulation(1, PSMC_MOD_IN_PIN);
psmc_pins(1, PSMC_A | PSMC_B | PSMC_C | PSMC_D);

setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN0);
set_adc_channel(0);

while(TRUE) {
psmc_duty(1, us(((read_adc()*(int16)10)/25)) );
}
}



Other examples are included with the compiler download and begin with EX_PSMC_



Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

The CCS Compiler Comes with DMX512 Bus Lighting Drivers

Thursday 22 April, 2021

DMX512 is a serial protocol that is commonly used to control stage lighting and effects. It was originally intended as a standardized method for controlling light dimmers. It soon became the primary method for linking controllers, a lighting console for example, to dimmers and special effect devices such as fog machines and intelligent lights.

A DMX512 network employs a multi-drop bus topology with nodes strung together in a daisy chain. A network consist of a single DMX512 controller, which is the master of the network and only transmitter, and one or more slave devices. Each slave device has an IN connector and usually an OUT or THRU connector, were as the controller only has an OUT connector. The controller's OUT connector is connected via a DMX512 cable to the first slave's IN connector. A second cable then links the OUT or THRU connector of the first slave to the IN connector of the next slave in the chain, and so on until all slaves are connected. The specification requires a terminator to be connected to the final OUT or THRU connector of the last slave on the daisy chain.

A DMX512 network is called a "DMX universe." The OUT connector on a DMX512 controller can control a single universe. Each universe operates up to 512 channels with each channel's parameter ranging between 0 and 255. A controller simply changes the values of these parameters.

For the DMX512 protocol, the controller transmits asynchronous serial data at 250 kbits/s. The data format is fixed at one start bit, eight data bits, and two stop bits. Each data frame consists of the following, a break, mark-after-break, slot 0 (Start Code) and up to 512 slots of channel data, each containing one byte. The break, which signals the end of one packet and the start of another, cause the slaves to start reception and also serves as a position reference for the data bytes within in the packet. The first slot, slot 0, is reserved for a start code that specifies the type of data in the packet.

The CCS C Compiler comes with a DMX512 driver, dmx.c, which can be used to develop code for either a DMX512 controller or a DMX512 slave device. When setup for a DMX512 controller the following functions are provided, DMXInit() to initialize the driver, DMXSetChannel() to set the specified channel to the specified value, DMXGetChannel() to get the current set value for the specified channel, and DMXCommit() to transmit the DMX512 channel data to the slave device. When setup for a DMX512 slave device the following functions are provided, DMXInit() to initialize the driver, DMXKbhit() to determine if new data as been received, and DMXGetd() to retrieve the DMX data.

In addition to the driver, the CCS C Compiler also provides the following two examples: ex_dmx_controller.c and ex_dma_slave.c, showing how to use the DMX512 driver to build code for a DMX512 controller and a DMX512 slave device.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Long Range RF Communications

Thursday 22 April, 2021

Introducing the new CCS Long Range RF Development Kit. LoRa® is low-power wide-area network protocol that can be used to periodically communicate sensor data. LoRa® uses a proprietary spread spectrum modulation that is similar to and a derivative of Chip Spread Spectrum (CSS) modulation. This allows for long-range transmission, up to 9 miles, with low power consumption. This makes it ideal for battery applications that only needs to periodically transmit sensor data.

The CCS Long Range RF Development Kit comes with two development boards with Microchip's RN2903 modules. The RN2903 modules are designed to communicate using LoRa® modulation using the US frequency band. This is everything needed to develop a LoRa® peer-to-peer (P2P) implementation. The development kit's exercise manual has several exercises for setting up testing different types of LoRa® P2P networks using the provided RN2903 and LoRa® P2P drivers.

Additionally, the development kit can be used the to develop code to communicate on a LoRaWAN®network. LoRaWAN® is a upper level network protocol, developed by the LoRa® Alliance, that uses LoRa® modulation for creating a cloud-based network. In LoRaWAN® networks end-devices periodically send messages to a gateway, which forwards it to a network server which in turn forwards the message to an application server. Any response for the end-device is then forward back in the reverse order. The development kit can be used to develop and test end-devices for a LoRaWAN® implementation, using the provided RN2903 and LoRaWAN® driver. Testing the LoRaWAN® end-device will require at minimum an external LoRaWAN® gateway, not provided with the Long Range RF Development Kit.

LoRaWAN® is a mark used under license from the LoRa Alliance®. Use of the LoRa Alliance® and LoRa Alliance® Member marks is pursuant to license from the LoRa Alliance®.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Using Overloading to Deal with Mixed ROM and RAM Data

Thursday 22 April, 2021

The CCS C Compiler supports C++ like function overloading. Function overloading allows the user to develop two functions with the same name, but have different parameters or return types. The CCS C Compiler can distinguish between RAM and ROM pointers when overloading. This is useful on the PIC® MCU which uses the Harvard architecture, meaning accessing the RAM and ROM is different. Since accessing RAM and ROM is different, the compiler needs to know which one the user is accessing so it can use the proper method.

Here is a simple example of function overloading using ROM and RAM pointers:

int Checksum(rom char * ptr) {

int cs;
while(*ptr!=0) // *ptr reads from ROM
cs += *ptr;

return cs;
}

int Checksum(char * ptr) {
int cs;
while(*ptr!=0) // *ptr reads from RAM
cs += *ptr;

return cs;
}

...
char data[10] = "Foo Bar";
const char hex[] = "0123456789ABCDEF";

label_cs = checksum("Hello World"); // Calls first funct
hex_cs = checksum(hex); // Calls first funct
data_cs = checksum(data); // Calls second funct

Checksum() has two functions, one for handling ROM pointers and one for handling RAM pointers. In the CCS C Compiler the 'rom' keyword specifies the ROM flash memory, if this is not specified the CCS C Compiler will use RAM. When Checksum() is called with the "Hello World" as a 'rom char *'

Some compiler built in functions deal with conversions from ROM to RAM pointers. For example strcpy() has two forms:
strcpy(ramstring, "Hello World");
strcpy(ramstring, buffer);

This is so the compiler can easily deal with awkward syntactical issues like this:
char string[] = "ABCDEFGHIJ";

ROM string moved to RAM and string is a RAM pointer. The CCS C Compiler also supports this syntax with all the appropriate conversions:
char string[10];
string = "Hello World";

Note that %s in a printf() is able to figure out if the string is in RAM or ROM however most string functions in string.h do not have overloaded versions for ROM data. For example if you want to do strcat(string,"...") then you must first make a function like this:

char *strcat(char *s1, rom char *s2)
{
unsigned char *s;

for (s = s1; *s != '\0'; ++s);
while(*s2 != '\0')
{
*s = *s2;
++s;
++s2;
}

*s = '\0';
return(s1);
}

Here is a more complex example of function overloading based on ROM and RAM pointers:

struct {
union {
rom char* pRom;
char* pRam;
};
int1 isRom;
} savedString;

void SetSavedString(rom char* pRom) {
savedString.pRom = pRom;
savedString.isRom = TRUE;
}

void SetSavedString(char* pRam) {
savedString.pRam = pRam;
savedString.isRom = FALSE;
}

void PrintSavedString(void) {
if(savedString.isRom)
printf("%s", savedString.pRom);
else
printf("%s", savedString.pRam);
}

SetSavedString((rom char*)"Hello World");
SetSavedString((char*) "foo bar");

SetSavedString() saves a (char*) or (rom char*) depending on what was passed in by the user to memory, and sets a flag denoting the type of pointer that is being used. The PrintSavedString() checks the flag to select the proper pointer, and prints the string.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

PIC® MCU Address Spaces - Part 3

Thursday 18 March, 2021

In part one we covered the two hardware address spaces in the PIC® MCU and how they can be used from C. Part two explained how a developer defines virtual address spaces. In this article we will detail how some PIC® MCUs have their own alternative address spaces and how the C compiler deals with them.

First, we must have a basic understanding about the fundamental addressing at the hardware level. Consider a PIC16F887 part and the instruction to add a memory value to the working register and put the result in the working register. The 14 bit instruction looks like this:
0 0 0 1 1 1 0 a a a a a a a

The aaaaaaa is the address in memory to get the data from. Notice there are only 7 bits so the address range is 0-127. In order to gain access to the rest of memory, there are some bank select bits. If the bank select bits are set to 010 then the instruction with aaaaaaa set to 0000001 will actually access memory location 0100000001. Fortunately, the compiler (at least the CCS C compiler) takes care of setting the right bank select bits before any instruction that needs the bits changed. There is a similar method used for program memory where the bits are called the page select bits. That comes into play with goto's and calls.



The following topics cover special features in some PIC® MCU parts that allow for a more effective way to access memory.

Mid-range Shared RAM
Even the old PIC chips had some special function registers duplicated in every bank, so there is no need to switch banks to access a popular register, like the status register. Many of the newer PIC® MCUs also have some general purpose RAM duplicated in all the banks. For example, on the PIC16F887 locations 0x70-0x7F reference the same RAM locations regardless of the bank bit setting. That means 0x70 and 0x1F0 are the same location. It is for this reason the compiler scratch locations begin at 0x70.



Mid-range Linear Address Space
On the mid-range parts the special function registers typically are at the start of each bank. For example 0x00 to 0x1F are SFR and 0x20-0x7F is general RAM. Then 0x80 to 0x1F are SFR and 0xA0 to 0xFF has general RAM. This means the largest data structure a user can have in RAM is 96 bytes or 80 bytes if there is shared RAM. If the user needs a larger array for example, they would need to split it into two smaller arrays.

On some mid-range PIC® MCUs there is an extended instruction set (4 and 5 digit parts after the F). In these parts there is a second way to access RAM called linear addressing. The linear address space has all the general purpose RAM locations and none of the SFR's. The entire general purpose RAM is put at location 0x2000 and up. Location 0x2000 is the same as 0x20. Location 0x02050 is the same as 0xA0. Now users can have data structures as large as memory can hold. The only way to address using the linear method is using indirection via the FSR registers. In the CCS C Compiler anytime a user accesses a data item using a variable index the linear addressing method is used if available on the part.

PIC18 Access Space
On the PIC18 parts most instructions have what is called an access bit to select what address space is used in the instruction. In the normal mode, the addressing works like the PIC16 using bank select bits somewhere else to fully specify the address. However, if the access bit is 0 then the address in the instruction is used to access only certain registers. The add instruction on the PIC18F4520 looks like this:
0 0 1 0 0 1 0 x a a a a a a a a

When x (the access bit) is 1 the address in the instruction is combined with the bank select bits to form the physical address.



When x is 0 then the physical address depends on the value of the address. With lower addresses then the remaining address bits are used as-is to get the physical address without using the bank select bits. For example, 00000001 will give users physical address 1 regardless of the bank select bit setting. This is kind of like the shared RAM feature in the PIC16. When the address is higher (0x80 and up on the PIC18F4520) then 0xF80 is added to the address over the cutoff to get the physical address. This allows for access to special function registers regardless of the bank select bit setting. Be aware however that different PIC18 parts have a different split between general purpose RAM and the SFR's in the access space. The PIC18F4520 has 128 bytes in each however the PIC18F4550 has only 96 bytes in general RAM and the rest in SFR's.

It should also be pointed out the PIC18 has a special double word instruction that can copy from any RAM address to any other RAM address.

PIC18 XINST
Most PIC18 parts have a XINST bit in the configuration fuses. When this bit is set the way the general purpose RAM is accessed when the access bit is set is modified. Instead of accessing the RAM directly the address is first added to the contents of another register. The intent with this feature is to make the using local variables easier in C code where users could have variables on a stack. This would allow for recursive functions. Since this feature is either on or off for the whole CCS has decided not to add support in the compiler for XINST because of the rare need for recursion and the inefficiencies caused by using this mode.

PIC24/DSPIC Extended RAM
On the 24 bit parts, the bank select bits were removed. Looking at the same add instruction it looks like this:
1 0 1 1 0 1 0 0 0 0 0 a a a a a a a a a a a a a

That means the instruction has direct access to RAM locations 0-1FFF (8K). That is a lot but many of these parts have more RAM than that. There are two ways to access RAM above 1FFF. First is to indirectly access the RAM using a 16 bit pointer (64K). This does require an extra instruction or two but is not as bad as it sounds since many instructions allow indirect addressing using one of the working registers. The other method is to use a special instruction to copy to/from any address 0-FFFF (64K) and a working register.

In summary, we have a great way to access 8K of RAM and there is a method to get at RAM over 8K but the method needs to be repeated for each access.

PIC24/DSPIC PSV Mode
Access to program memory (for constants) requires some extra steps to set up some registers and grab the data. The 24 bit parts have a mode that can be used to map the upper 32K of RAM addresses on to a selected area of program memory. This can be used to access constants in program memory as easily as if they were in RAM. When doing this, users loose access to the upper 32K of RAM. By default the CCS Compiler does not use this technique because in general it seems additional RAM is more important than fast access to ROM. A lot of the Microchip example code does use PSV mode so there is support in the CCS compiler to allow for easier porting.

#device PSV=16 // Turns on PSV mode
const char serial_number[] = {"123456789"}; // Saved in ROM
...
sn = atol32(serial_number); // Is accessed by a RAM address


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Use the IDE Column Editing Feature to Quickly Edit Repetitive Text

Thursday 18 March, 2021

There are situations where there is a need to make repetitive but identical changes to each line, or copy a block of text and then add the same text or spacing to each line when editing source code. Column editing allows a way to enter or delete text on multiple rows at once.

Access this feature by pressing the CTRL key while making a selection with the left mouse button. This enables selecting a rectangular region to be able to type to replace its contents, paste over it, or delete it.

The following are some examples.

1. Editing identical variable types



In the above illustration, column select the "int" type, and then simply type "unsigned int", to all 3 lines at once.

2. Working with Enums



Above shows a selected rectangle consisting of all of the enum variants to avoid copying the spacing. Pasting it into the switch statement maintains its tabbing. Next insert "case" into each line by simply column select the space before "SHAPE" and type "case".


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

Dealing With Out of ROM Errors

Thursday 18 March, 2021

Often times the "Out of ROM, a segment or the program is too large" error pops up near the end of a project and users are now forced to deal with this new problem. This article will help to understand the causes and some simple solutions to get back to the project.

About Segment Sizes
The first thing to realize is that users may get this error and have plenty of ROM left. The reason is the CCS C Compiler does not split a function across a ROM page boundary. This error message always produces some informational lines in the .err file to help understand what is going on. Here is an example output for the case where a function is too large for a segment.

C:PICmain.c:1231:1: Error#71 Out of ROM, A segment or the program is too large
process_data
Seg 00000-00002, 0000 left, need 009C7 Reserved
Seg 00003-00003, 0001 left, need 009C7
Seg 00004-00055, 0000 left, need 009C7 Reserved
Seg 00056-007FF, 003D left, need 009C7
Seg 00800-00FFF, 042E left, need 009C7
Seg 01000-017FF, 0800 left, need 009C7
Seg 01800-01FFF, 0800 left, need 009C7
Seg 02000-027FF, 0800 left, need 009C7
Seg 02800-02FFF, 0800 left, need 009C7
Seg 03000-037FF, 0800 left, need 009C7
Seg 03800-03FFF, 0800 left, need 009C7

The first thing to notice is the "process_data." This is the name of a function in the users program that caused the linker to stop. Then look at the number after "need", this is how many words would be needed for that function (process_data). Sometimes it is different in different areas of memory because extra instructions are needed to jump to other pages.

The ROM in the chip is split into segments. Each segment is shown in this list. The first and third are marked as reserved, this is the reset jump and interrupt handler. These segments cannot be relocated. Of the remaining segments you will notice there is never more than 800 (2K) available (left). This is because on this chip the page size is 0x800.

There is plenty of ROM available on this chip but the function takes 9C7 and that does not fit into the 800 segment size. The simple solution is to split the function into two.

We most commonly see this error in technical support with main() as the function and there are no other functions in the program. It is always good to adapt a coding style where there are some limits on function size to aid in readability, maintainability and to keep sanity. It is recommended that a function should fit on a screen or at least a page.

It is possible to get an error like the above when users have a well structured program with lots of small functions. Consider the following example:

void func_b(void) {
...
}
void func_c(void) {
...
}
void func_d(void) {
...
}
void func_a(void) {
funct_b();
funct_c();
funct_d();
}

If funct_b(), funct_c() and funct_d() are each only called once then the compiler to save valuable stack space will copy the code from those functions to funct_a(). This makes funct_a() way bigger that it appears.

To solve the problem users can tell the compiler to never inline the function like this:
#separate
void func_b(void) {
...
}

Note that when prototyping the function there must also have the #separate there.

Here are the page (max segment) sizes for each family:



Fragmentation
Another problem maybe the way the segments are being used. Users can see something like this:

Seg 00000-00002, 0000 left, need 00261 Reserved
Seg 00003-00003, 0001 left, need 00261
Seg 00004-00055, 0000 left, need 00261 Reserved
Seg 00056-007FF, 003D left, need 00261
Seg 00800-00FFF, 022E left, need 00261
Seg 01000-017FF, 00F7 left, need 00261
Seg 01800-01FFF, 0005 left, need 00261
Seg 02000-027FF, 0193 left, need 00261
Seg 02800-02FFF, 0073 left, need 00261
Seg 03000-037FF, 011B left, need 00261
Seg 03800-03FFF, 0175 left, need 00261

In total you have enough RAM for your function of size 261 but not all in the same segment. The linker does try to shift functions around and make room, but if this is not possible you will get the error. The best way to solve this is to again split some larger functions into smaller functions. If there are more smaller functions the linker will be able to shuffle things around and make more room in one of the segments for your 261 function.

To find out how much ROM each functions used in the IDE use COMPILE > STATISTICS. There needs to be an error free compile to see this however.

Code Optimization
If users are really out of ROM then they need to consider optimizing your code. The general rule is to find groups of lines that are the same or similar and move them to a function. The compiler does some optimization between statements, but most of the optimization is done on a single statement. Skimming through the .LST file to identify C lines that generate a lot of assembly can help to identify areas that users may want to check for the possibility to move to a function. Here are some examples:

1. Even though this appears to be a simple initialization you will save ROM by moving the four lines to a function:
next_in=0;
next_out=0;
count=0;
total=0.0;
read_from_history();
...
next_in=0;
next_out=0;
count=0;
total=0.0;
read_from_device();

2. Unless using #opt compress (see below) the compiler does not optimize the subscript expression used here:
weight = weight_lookup[width*height+cal_offset];
time = time_lookup[width*height+cal_offset];

When possible do this:
volume = width*height+cal_offset;
weight = weight_lookup[volume];
time = time_lookup[volume];

3. When reviewing the LST file users will see printf's can take a lot of space. For code like this:
printf("Max position = %lu:%lurn", max_x, max_y);
printf("Ave position = %lu:%lurn", ave_x, ave_y);
printf("Min position = %lu:%lurn", min_x, min_y);

Consider:
void printxy( rom char * label, int16 x, int16 y) {
printf("%s position = %lu:%lurn", label, x, y);
}
...
printxy("Max", max_x, max_y);
printxy("Ave", ave_x, ave_y);
printxy("Min", min_x, min_y);

Compiler Optimization
By default the compiler uses optimization level 9. This provides a good level of optimization that has been well tested. If the optimization is set down then now is a good time to get it back up to 9. If there are any optimization problems do report then to support so we can fix them.

Some chips have a more extreme level of optimization available. To invoke it use:
#opt compress

This optimization will save ROM but will take longer to run. What the compiler does is to go through the whole program and any sequence of instructions that is repeated are made into a function that is called each time it is needed. This will make debugging and even reading the .LST file more difficult. The savings can be substantial and may prevent users from moving to a larger chip.


Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit https://www.ccsinfo.com.

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.

 Displaying 11 to 20 (of 199 articles)   Result Pages: [<< Prev]   1  2  3  4  5 ...  [Next >>]