Static libraries contain code that is linked at compile time to the project calling it. It can be used to provide reusable functions or to distribute code in a binary-only format (a header file will still be needed).
To create a static library, go to File -> New -> Silicon Labs MCU Project and select Library:
Write any functions you want the library to contain. Library functions can call other library functions. Be sure to create a header file containing prototypes for the functions you wish to be called from the linking project. There will be no main() function in the library. Build this project.
Create a new project to link to the library (or use an existing project).
In this project, add the directory containing the library's header file to the include path. Do this by going to Properties -> C/C++ Build -> Settings -> Tool Settings -> Compiler -> Includes -> Add directory path.
Add the library's .lib file to the linker by going to Properties -> C/C++ Build -> Settings -> Tool Settings -> Linker -> Libraries -> Add. You must build the library project for the .lib file to be created.
Add the #include for the libraries header file to the linking project. You can now call functions from the library.
Why do I2C pins have to be open-drain and not push-pull?
Setting the I2C pins to push-pull can cause damage to the devices on the bus. The reason this is an issue is that there are three parts of the I2C communication protocol specifically that can result in a direct short from power to ground:
In these above three scenarios, it is possible for one device to be driving SDA high, while another device on the bus is driving SDA low. If the outputs are open-drain, devices can only drive low, or float (pulled-up in the case of I2C). In the above three scenarios, this means there is no conflict since the device driving low will always win on the bus.
If the outputs are push-pull, then the only two possible states are drive low or drive high; there is no "float" state. In the above three scenarios with push-pull outputs, one device on the bus will be driving SDA low, and another will be driving SDA high, so there will be a direct short between power and ground through the two devices. This can cause damage to the devices and is not recommended.
How do I troubleshoot the "address space overflow" error in an 8051 project using Keil?
The 8051 memory model contains several different types of segments including:
DATA, IDATA, PDATA, and XDATA all allow read and write access, whereas CODE is read only. The memory segments are listed in order of speed and code efficiency (DATA accesses are fastest and generate the most compact code, wherease CODE accesses are the slowest and generate the least compact code).
Keil locates variables by default depending on which of the following memory models are selected:
Users can manually locate variables in a specified memory segment using the following macro from si_toolchain.h (provided by Silicon Labs):
SI_SEGMENT_VARIABLE(name, vartype, memseg)
name is the name of the variable,
vartype is the data type (i.e. uint8_t)
memseg is a memory segment (i.e. SI_SEG_IDATA)
Variables that don't specify a segment or use the SI_SEG_GENERIC segment are located based on the rules defined by the specified memory model passed to the linker.
During the link stage of the build process, the linker places all variables and functions into the appropriate memory segments. If the number of bytes assigned to a memory segment exceeds the maximum size of the segment, the linker generates an error like:
*** ERROR L107: ADDRESS SPACE OVERFLOW
where SPACE and SEGMENT specifies which memory space and segment are overflowed and LENGTH specifies the size of the memory segment.
In the example above, _DATA_GROUP_ is a segment created to hold all variables defined in the DATA segment when overlaying is used. Overlaying allows the linker to reuse memory that can't be used simultaneously such as two local variables in two functions that aren't called at the same time.
There are two primary methods to fix an address space overflow error: (1) change the default memory segment by changing the linker memory model or (2) manually move certain variables to other memory segments.
Changing the Memory Model in Simplicity Studio
Specifying a Memory Segment
Use the SI_SEGMENT_VARIABLE() macro from si_toolchain.h as described above.
The M51 map file generated by the linker can be a great resource for determining how much memory each module uses and to decide which variables to relocate to another memory segment to free up space in an overflowed segment.
As an example, the EFM8UB1_Blinky project was modified to create three large variables in main(), TIMER2_ISR(), and enter_DefaultMode_from_RESET() by adding the following to the beginning of each respective function:
uint8_t main_data_hungry; // added to main() uint8_t interrupts_data_hungry; // added to TIMER2_ISR() uint8_t initdevice_data_hungry; // added to enter_DefaultMode_from_RESET()
Attempting to build the project will result in several errors:
make: *** [EFM8UB1_Blinky.omf] Error 1
*** ERROR L114: SEGMENT DOES NOT FIT
*** ERROR L107: ADDRESS SPACE OVERFLOW
This is because we added variables that use 192 bytes of the default memory segment, which is DATA in the small memory model. DATA can only hold up to 128 bytes including register banks, bit data, etc.
Looking at the top of the M51 map file, we can see that the DATA segment is using 0x10C (268) bytes, well over the 128 byte maximum.
Further down the M51 map file, each segment and its memory usage are listed. Unfortunately, with overlaying enabled, the _DATA_GROUP_ segment does not fit and thus can't be placed. So we don't see any usage.
To aid in troubleshooting, we can temporarily disable overlaying, which will create a separate segment for each module. This way we can see each module's contribution to memory usage separately.
Temporarily Disabling Overlaying
Once overlaying is disabled, we can rebuild the project and get a much more useful M51 map file with each module's memory usage in detail.
Here we can clearly see that the ENTER_DEFAULT_MODE_FROM_RESET segment in the INITDEVICE module is using 0x41 (65) bytes. Once the DATA memory segment overflows, the linker stops placing memory, so we won't see the other two large variables until we free up some memory in the DATA segment.
Applying either of the two solutions described above would fix the errors. For example, changing the memory model to large would place the 192 bytes of variable data in XDATA. Similarly, we could manually place the variables in another memory segments such as IDATA, PDATA, or XDATA.
1) What deposition process is used for the Sn plating (electroplate, immersion, or hot dip)?
2) What is the thickness of the Sn plating?
3) Is the Sn plating subjected to an annealing process after deposition with the purpose of mitigating Sn whiskers?
4) If the Sn plating is annealed after plating, is the plating tested according to JESD 201?
5) On packages that have a pad to designate pin 1, are those pads also Sn plated?
1) The deposition process used is electroplating.
2) Thickness of the electroplating is a minimum of 10 µm.
4) No. JESD 201 does not apply to components with bottom-only terminations where the full plated surface is wetted during assembly (for example: QFN and BGA components, Flip Chip bump terminations).