DATASHEET SEARCH SITE | WWW.ALLDATASHEET.COM
Document overview
- Manufacturer or author: Provided By ALLDATASHEET.COM(FREE DATASHEET DOWNLOAD SITE)
- PDF pages: 30
Technical content
Figure 2. Graphical Elements from which the thing being described is derived. of some integral or structural type; i.e., a non-object. is indicated beneath the element type. side has a pointer, or an index, to the thing pointed to. field. It indicates "composition". are pointers to those", or "this talks to that". aggregated by or composited within the subject. The name used by the subject to reference it is indicated. A chip box indicates a hardware peripheral.
Rev. 0.1 3 2. Relevant Documentation Precision32 Application Notes are listed on the following website: www.silabs.com/32bit-mcu. AN664: Precision32™ CMSIS and HAL User’s Guide AN673: Precision32™ Software Development Kit (SDK) Overview 3. Examples The examples for the si32Library install with the Precision32 package to the si32-x.y\\Examples\\si32Library directory, where x is the major SDK version number and y is the minor SDK version directory. Some of these examples are simple demonstrations of how to use the components, and some are full application examples like a HID USB-to-UART bridge interface. 4. Component Architecture The si32Library is structured as a collection of indep endent and cooperating components. A component is a collection of related objects with a header file that incl udes any other components it may require, as well as any internal objects or sub-components that it provides. Th erefore, to use a component in an application or another component, it is sufficient to include that componen t's header file and add the component's sources and its dependencies to the project. All components are named according to the form somethingComponent, where something is a meaningful name like USB. The only exception is si32Library, which is the top level and does not have the Component suffix. Every component is represented in the source tree as a directory. That directory contains the following types of files: * .h: The component and object header files collectively comprise the interface. All of the documentation about the interface is here and not in the .c files. * .c: The individual source files collectively comprise the implementation for the component. There may be more than one implementation of any given interface. Documentation relevant to a specific implementation is found here. Some component directories contain subdirectories whose names also end in Component. These are sub- components and follow the same structure recursively. Su b-components are used to provide logical groupings of components. There are some specific files that each application must possess. These f iles contain various elements that are necessary for a build, but that are specific to each individual application. myBuildOptions.h contains all of the build options. It allows the application developer to enable or disable various compile time options, including assertions and debug logging. myLinkerOptions_<chain>.<ext> contains the definitions for application specific configuration options such as the desired stack and heap sizes. This file is included by the tool chain during compilation and is Applications do not include the myBuildOptions.h file directly because the si32BaseComponent of the si32Library includes it. It is the very first file included because it specifies the build options for the si32Library. Changes to this file to specify different build options require recompliation of the library. This allows each individual application to configure the si32Library as desired without needing to modify any of the library code. Figure 3 shows the dependencies of an si32Library-based application.
Figure 3. si32Library Application Dependencies
Rev. 0.1 5 5. Base Component COMPONENT: si32BaseComponent REQUIRES: none PROVIDES: none This component provides facilities for logging, error handling, memory allocation, and control flow. 5.1. Build Options si32Base.h provides benign defaults for all available build options. To change a build option for an application, enable or disable that option as appropriate in the application's myBuildOptions.h. si32BuildOption_enable_assertions: Enables si32Assert(). Default is off. si32BuildOption_enable_logging: Enables logging. Logging must be enabled to use any si32LogXXX() routine. Default is off. si32BuildOption_log_flow: Enables si32LogPrologue(), si32LogSelf(), si32LogArg(), si32LogAttr(), si32LogVar, si32LogEpilogue(). Default is off. si32BuildOption_log_ref_counts: Enables logging of reference counts if _log_flow is also enabled. Default is off. si32BuildOption_tally_allocations: Dynamic allocations encode size information for leak checking. Default is off. si32BuildOption_retention_zone_size: Retention allocation zone reserve (for MCUs with retention RAM). Default is 1. si32BuildOption_incremental_zone_size: Incremental allocation zone reserve. Default is 1. si32BuildOption_addressable_labels: Enable use of computed labels instead of switch abuse for local continuations. Default is off; switch/case is used. si32BuildOption_logPath: Workstation platforms can log to a file. Default is "/dev/stdout". 5.2. Logging si32BaseLogger.h defines a number of macros for logging wa ypoints during program execution. These depend on the si32HAL and require use of si32HAL/CPU/retarget_<chain>.c to redirect printf/scanf primitives to ITM, a UART, or some other device. void si32StartLogging(void): Configures the logging subsystem and initiates logging. For simulation builds on workstations this opens the log file. void si32StopLogging(void): Terminates logging. For simulation builds on workstations this closes the log file. void si32LogBeSilent(bool yn): Used to temporarily change the state of the logger without disabling it, or recompiling to turn it off. When silent the log does not send data to ITM etc. bool si32LogIsSilent(void): Queries whether the log is silent, or verbose. void si32LogBeIndented(bool yn): Controls whether the log is indented. When YES, si32LogPrologue() indents the log, and si32LogEpilogue() outdents the log, in addition to logging the entry/exit of a function, respectively. The default is YES, indent the log. bool si32LogIsIndented(void): Queries whether the log is indented, or flat. int si32LogPrint(char* fmt, ...): Prints to the log, with parameters similar to printf. Does not indent, even when preceded by si32LogBeIndented(YES). Does not append a newline. For io retargeting, it essentially just wraps printf. int si32LogTrace(char* fmt, ...): Prints to the log, with parameters similar to printf. It indents per si32LogBeIndented(yn) and appends a newline. int si32LogWarning(char* fmt, ...): Prints to the log, with parameters similar to printf. It indents per si32LogBeIndented(yn). Prepends "WARNING: " and appends a newline. int si32LogError(char* fmt, ...): Prints to the log, with parameters similar to printf. It indents per
6 Rev. 0.1 si32LogBeIndented(yn), prepends "ERROR: " and appends a newline. void si32LogPrologue(void): Logs the name of the surrounding function preceded by ">" and indented per si32LogBeIndented(yn). Useful for marking function entry. Intended to be paired with si32LogEpilogue() particularly when preceded by si32LogBeIndented(YES). void si32LogEpilogue(void): Logs the name of the surrounding function preceded by "<" and indented per si32LogBeIndented(yn). Useful for marking function exit. Intended to be paired with si32LogPrologue() particularly when preceded by si32LogBeIndented(YES). 5.3. Error Handling Error handling in si32Library adopts the strategy of stor ing an error code, with a get/set error methodology. This style is chosen over the "error out parameter" style in order to reduce the number of parameters to functions in the general case, improving the compiler's opportunity to pass parameters via registers. The error code is a char*, not an integer code, and points to a non-localized string. Erro r strings are intended specifically to aid the developer in debugging the application. These entry points are all macros. si32Assert(expression): Evaluates an expression and "halts" if that expression evaluates to false. si32If (expression) { handler statements }: If the expression is true, sets an error with the text of the expression, and executes the handler statements. It is 'if', but with internal error check, set, and log functionality. Use it just like 'if'. IF (expression) { handler statements }: Identical to si32If, but intended to be less disruptive when reading code. si32BreakIf(expression): Conditional break statement. si32ContinueIf(expression): Conditional continue statement. si32Catch(exception): Control flow escape for local exception handing. Catches a local throw from within the same function. si32Throw(exception): Control flow escape for local exception handing. Throws to the corresponding catch within the same function. si32ThrowExitIf(expression): Conditional throw to 'exit'. si32ThrowIf(expression, exception): Similar to si32ThrowTrapIf except instead of throwing 'trap' it throws the specified exception, and does not specify an error string. si32ThrowTrapIf(expression): Conditional throw to 'trap'. Evaluates an expression and throws a trap exception if that expression evaluates to true. si32TrapIf(expression): Synonymous with si32ThrowTrapIf. si32TrapIf is deprecated but still exists for compatibility with vintage code. si32Halt(): Halts, triggering a debugger breakpoint if possible, or simulates one via while(1). bool si32SetError(fmt, ...): Logs and pushes an error. Error stack depth is implementation dependent, and varies across embedded and workstation targets. StdC implementations are 1 deep. ObjC implementations are deeper. Parameters work like printf. Current implementations always return YES. char* si32GetError(): Peeks the current error. I.e, returns the error string but does not pop the error stack. si32ClearError: For embedded StdC implementation, clears the current error. For ObjC implementations, pops the error stack.
Rev. 0.1 7 5.4. Memory Management The si32Library supports static/compile time memory allocation, dynamic one-time allocation, and dynamic heap- based allocation. Static allocation relies on declaring all memory usage as data structures to be reserved and initialized by the compiler when the system boots. Dynamic one-time allocation relies on a statically allocated block of memory that is used to incrementally satisfy allocation requests at runtime. Memory allocated in this manner is not recoverable via deallocation or reallocation. It is only recoverable by resetting the entire memory block. Dynamic heap-based allocation is essentially the malloc/free model supporting allocation, reallocation, and deallocation on a heap. Static allocation is performed by writing C code that de clares and initializes data structures, and is outside the scope of this discussion. Dynamic one-time allocation is perfo rmed by overriding the default value of si32BuildOption_incremental_zone_size, thus creating a block of memory for servicing allocations. Calls to si32Base_allocate(SI32_INCREMENTAL_ZONE, size, alignment) claim memory from this block, called the incremental zone. Attempts to free this memory via si32Base_deallocate(pointer) will succeed, but the memory will not be reclaimed. Similarly, calls to si32Base_reallocate(pointer) will reallocate the pointer by claiming a new block from the incremental zone, effectively leaking the previous allocation. Dynamic heap allocation allows allocation, reallocation, and deallocation. si32Base_allocate(SI32_HEAP_ZONE, size, alignment) behaves similarly to calloc(). si32Base_reallocate(pointer) behaves similarly to realloc() when called on a heap pointer. si32Base_deallocate(pointer) behaves similarly to free() when called on a heap pointer. Note: The performance of heap-based dynamic memory depends on the heap implementation prov ided by the tool chain. Each supported compiler provides a unique implementation.
from base types, inheriting their behavior and properties. Therefore, the term class is generally avoided. The si32ObjectComponent provides both early and late binding capabilities. Figure 4. Object Structure
Rev. 0.1 9 Object functions typically follow this pattern: uint32 result = 0; // meta:{{si32SomeObject}do_something} si32Assert(is_si32SomeObject(self)); si32SomeObject *my = self; result = my->someObjectContext.variable; // meta:{{si32SomeObject}do_something} return result; The first line declares a variable for the function result and initializes it. The comment marks the end of the function entry and the start of the body. si32Assert is an assertio n that halts in the debugger if the expression is false. is_si32SomeObject performs the runtime type check. Next, a variable of the appropriate type is declared and bound to self. Note that this is 'safe' because the runtime type check succeeded. The symbol my is just chosen to reinforce that referenced attributes belong to the object bound to self. Next, the contents of the object's variables (i.e., its attributes) are accessed through the typed poi nter. The second comment marks the end of the body and starts the function exit. Logging and assertions only have a code footprint in debug builds. They are intended for use during development and debugging, not for final production code. Therefore, bu ild options exist to cause these constructs to compile away to nothing for release builds. Calling the functions of an object (i.e., in voking its operations) is accomplished in a similar fashion. However, it is not necessary to employ a type* my = self statement in order to invoke an operation on an object. The following is sufficient: uint32 result = si32SomeObject_do_something(&my_object, arg); Macros are employed to access the object's function tables in order to determine the correct implementation of the operation to invoke. This is how runtime fu nction overloading is implemented by the si32ObjectComponent and, therefore, all of the si32Library. For example: uint32 _si32ListObject_get_capacity(obj* /*self*/); #define si32ListObject_get_capacity(self) as_si32ListObject(get_capacity, (self)) The first line provides the function prototype for the early binding. Calling this directly invokes that specific function, bypassing the function table and thus preventing polymorphism. Early bindings are preceded by an underscore. The second line provides the late binding, which calls through the function table, enabling polymorphism.
attributes of the base type. Figure 5 shows the derived object structure. Figure 5. Derived Object Structure configures it for use as an object by preparing it's reference count, function tables, etc. initialize: All objects must be initialized prior to being used. retain: Increments the object's reference count. from 1 to 0 it is deallocated. zone are actually deallocated. thus, subsequent use may result in a po inter error. The policy is to retain it if it will continue to be used. object that performed the allocation is not required to be responsible for its eventual deallocation.
Rev. 0.1 11 manner. These functions are provided by the si32BaseComponent and should be used for all dynamic memory allocation because they provided tr acked, aligned, memory management transparently to the library and its applications. 6.2.1. Allocation of Objects Objects must be allocated a nd initialized before they can be used. Th ey are typically allocated on the stack as automatic variables. For example: si32UsartAPortalObject my_usart = si32UsartAPortalObject(); Objects whose lifetime must exceed that of the scope in which they are defined can be declared static, just like any other variable in C. static si32UsartAPortalObject my_usart = si32UsartAPortalObject(); Objects can also be dynamically allocated. si32UsartAPortalObject* my_usart = si32UsartAPortalObject_allocate(); Objects are allocated from the default allocation z one, one of the si32Alloca tionZoneEnumType values: SI32_RETENTION_ZONE, SI32_I NCREMENTAL_ZONE, or SI32_H EAP_ZONE. The default zone is SI32_HEAP_ZONE. Applications are free to change the default allocation zone at runtime. Both the retention zone and the incremental zone are incremental. They are simply blocks of bytes, and each allocation request just advances a pointer within the zone by the amount requested. Allocating from these zones does not incur additional RAM overhead. However, it is not possible to reclaim memory allocated from these zones except by resetting the entire zone. They are intend ed to support a programming model wherein all memory is preallocated at startup time and persists throughout the duration of the program's execution. The heap zone is implemented using the allocator provided by the tool chain. It allows dynamic deallocation and reallocation, at the cost of potential memory fragmentation and subsequent compaction. To determine the default allocation zone use: si32AllocationZoneEnumType si32Base_get_default_allocation_zone() To change the default allocation use: si32Base_set_default_allocation_zone(si32AllocationZoneEnumType zone) 6.2.2. Rules for Initializing Objects Regardless of how an object is allocated, it should not be used until it has been initialized. Initialization sets up the object's attributes and configures it for operation. si32UsartAPortalObject_initialize(&my_usart, SI32_PORTAL_OBJECT_CAPABILITY_FULL_DUPLEX |SI32_PORTAL_OBJECT_CAPABILITY_TRANSMIT |SI32_PORTAL_OBJECT_CAPABILITY_RECEIVE, SI32_USART_0); Attempting to invoke an object function on an uninitializ ed object results in an assertion (for debug builds) or (occasionally) a fault.
12 Rev. 0.1 6.2.3. Usage Once an object has been allocated and initialized, it can be used. si32UsartAPortalObject_set_configuration(&my_usart, SI32_PORTAL_OBJECT_CONFIGURATION_FULL_DUPLEX |SI32_PORTAL_OBJECT_CONFIGURATION_TRANSMIT |SI32_PORTAL_OBJECT_CONFIGURATION_RECEIVE); actual_rd = si32UsartAPortalObject_read(&my_usart, buffer, N); si32UsartAPortalObject_release(&my_usart); Another example: // allocate an object on the stack. si32PseudoThreadObject my_thread = si32PseudoThreadObject(); // initialize it. si32PseudoThreadObject_initialize(&my_thread, &my_run_loop); // use it. si32PseudoThreadObject_run(&thread, my_thread_fn); // eventually release it, once it is no longer needed. si32PseudoThreadObject_release(&thread); 6.2.4. Rules for Retaining and Releasing Objects Regardless of how an object is allocated, it should be retained and released in order to correctly manage its reference count. In some cases, a reference to an object may be passed to a function, and that object may or may not be dynamically allocated. If the reference to the object mu st remain valid even after the function returns (i.e., it was stored somewhere for later use), then it must be re tained. All calls to retain must be matched with a call to release, once the retainer of the object no longer needs a reference to it. Reference counting allows dynamic objects that are no longer needed to become deallocated, and allows static objects that are no longer needed to release any aggregated objects whose references they hold. For example: // retain it. si32BufferObject_retain(&my_tx_buffer); // use it... // release it. si32BufferObject_release(&my_tx_buffer); All objects are initialized with a reference count of one. Th is means that statically allocated objects created on the stack (but not those defined at file scope) must be rel eased prior to return from the function wherein they are allocated. The reason is that those objects may contain references to other objects. These other objects must be released when the statically allocated stack object goes ou t of scope; otherwise, their reference counts can never decrement to zero. For example:
Rev. 0.1 13 void f() // allocate an object on the stack and zero it. si32BufferObject my_buffer = si32BufferObject(); // initialize it. si32BufferObject_initialize(&my_buffer, ...); // use it... // release it. si32BufferObject_release(&my_tx_buffer); 6.3. si32RootObject si32RootObject is the root of the object hierarchy.
22 Rev. 0.1 10. USB Component COMPONENT: si32UsbComponent REQUIRES: none PROVIDES: si32UsbAudioComponent, si32UsbCdcComponent, si32UsbCoreComponent, si32UsbDfuComponent, si32UsbHidComponent, si32UsbMscComponent The USB component is a collection of sub-components that add specific USB functionality: si32UsbAudioComponent provides the USB Audio Device Class functionality and definitions. si32UsbMscComponent adds USB Mass Storage Class functionality and definitions. si32UsbHidComponent adds USB HID Class functionality. si32UsbDfuComponent adds USB DFU Device Class functionality. All class components depend on the si32USBCoreComponent to provide the basic USB definitions required by the core USB Specification and are optional; they only need to be compiled if the functionality is needed. The si32UsbCoreComponent provides the basic USB Device model and device controller functions. 10.1. si32UsbCoreComponent COMPONENT: si32UsbCoreComponent REQUIRES: none PROVIDES: si32UsbConfigurationObject, si32UsbDefaultEndpointObject, si32UsbDeviceObject, si32UsbEndpointObject, si32UsbInterfaceObject The si32UsbCoreComponent provides support for the standard USB Device Model and the standard USB Requests required for USB Enumeration. This component includes objects that provide the basic functionality that collectively can be used to act as a stand- alone USB device. The objects, however, are intended to se rve as the base objects that are extended by the USB Device Class components or custom applications. 10.1.1. si32UsbDeviceObject This is the root object of any USB Device. An application can define many si32UsbDeviceObjects, but only one can be associated with the USB device co ntroller at any given time. An si32Us bDeviceObject also has a reference to an si32UsbStringTable, which is used to look up strings by index and language ID, and a collection of one or more si32UsbConfigurationObjects. All si32UsbDeviceObjects contain a default endpoint object that can be shared among all interfaces contained in the device's configurations. Control requests for standar d Chapter 9 requests for enumeration, as well as any device class or vendor specific req uests, will all be received by the defau lt endpoint and dispatched by the si32UsbDeviceObject. An si32UsbDeviceObject receives notification of a new control request and is a control request recipient, so it may dispatch control requests that specify a Device recipient to itself. 10.1.2. si32UsbConfigurationObject This object contains the specific power and functi on configuration provided by the USB device. An si32UsbDeviceObject contains a collection of one or more configuration objects. When a configuration object has been set through a USB SET_CONFIG standard request, the device is considered to be functional and enumerated. An si32UsbConfigurationObject contains a collection of si32UsbInterfaceObjects that provide the functionality supported by the configuration. An si32UsbConfigurationObject is not a control request recipient; therefore, it will not receive notification of control requests that may be targeted at an interface or endpoin t contained in its configuration. However, the collection of available interfaces and endpoints is dependent on the active configuration, so a device object queries a configuration for its interfaces or endpoints when attempting to deliver a control request.
Rev. 0.1 23 10.1.3. si32UsbEndpointObject This object represents the device-side of a USB endpoint. An endpoint is bound to a specific interface object and can only be used when that interface has been set. A ll USB I/O occurs using an si32UsbEndpointObject or an object derived from an si32UsbEndpointObject. An si32UsbEndpointObject is a control request recipient, so it will receive control requests that specify an endpoint recipient through its RequestHandler operation. 10.1.4. si32UsbDefaultEndpointObject This object derives from the si32EndpointObject and prov ides the support expected from a USB default control endpoint. 10.1.5. si32UsbInterfaceObject This object represents a single USB Interface that can be enabled within a configuration. The interface may contain or refer to 0 or more endpoint objects through wh ich the firmware may communicate with the host when the interface is enabled. The si32UsbInterfaceObject is a cont rol request recipient, so it will receiv e control requests that specify an interface recipient through its RequestHandler operation. An si32UsbInterfaceObject contains a collection of si32 UsbEndpointObjects that it uses to communicate with the host. 10.2. si32UsbAudioComponent COMPONENT: si32UsbAudioComponent REQUIRES: none PROVIDES: si32UsbAudioControlInterfaceObject, si32UsbAudioEndpointObject, si32UsbAudioInterfaceObject, si32UsbAudioObject, si32UsbAudioStreamingEndpointObject, si32UsbAudioStreamingInterfaceObject The si32UsbAudioComponent encapsulates the set of objects that add support for the USB Audio Device Class. The objects in this component extend the standard USB device objects provided by the si32UsbCoreComponent. 10.3. si32UsbDfuComponent COMPONENT: si32UsbDfuComponent REQUIRES: none PROVIDES: si32UsbDfuDeviceObject, si32UsbDfuInterfaceObject, si32UsbDfuObject The si32UsbDfuComponent contains a set of objects that adds support for the USB Firmware Download specification, allowing applications to easily add DFU capability to their embedded applications. 10.4. si32UsbHidComponent COMPONENT: si32UsbHidComponent REQUIRES: none PROVIDES: si32UsbHidInterfaceObject The si32UsbHidComponent contains objects that add support for the USB Human Interface Device (HID) class specification to the si32UsbComponent. The component currently consists of the minimum objects necessary to allo w an application to intercept USB HID class specific messages for th e application-specific HID interface and provide the ap plication with endpoints that can be used to send or receive hid reports.
24 Rev. 0.1 10.5. si32UsbMscComponent COMPONENT: si32UsbMscComponent REQUIRES: none PROVIDES: si32ScsiDeviceObject, si32ScsiMediaObject, si32StorageObject, si32UsbMscObject The si32UsbMscComponent contains the objects necessary to add support for the USB Mass Storage Class specification. The component defines and implements Bulk-only transport and provides default implementations for the common SCSI Block Commands and an abstract SCSI Media Interf ace. An application can quickly add a new media type using this interface by providing the media capacity, block size, a read function, and a write function.
30 Rev. 0.1 CONTACT INFORMATION Silicon Laboratories Inc.
400 West Cesar Chavez
Austin, TX 78701 Tel: 1+(512) 416-8500 Fax: 1+(512) 416-9669 Toll Free: 1+(877) 444-3032 Please visit the Silicon Labs Technical Support web page: https://www.silabs.com/support/pages/contacttechnicalsupport.aspx and register to submit a technical support request. Silicon Laboratories and Silicon Labs are trademarks of Silicon Laboratories Inc. Other products or brandnames mentioned herein are trademarks or registered trademarks of their respective holders. The information in this document is believed to be accurate in all respects at the time of publication but is subject to change without notice. Silicon Laboratories assumes no responsibility for errors and omissions, and disclaims responsibility for any consequences resulting from the use of information included herein. Additionally, Silicon Laboratories assumes no responsibility for the functioning of undescribed features or parameters. Silicon Laboratories reserves the right to make changes without further notice. Silicon Laboratories makes no warranty, rep- resentation or guarantee regarding the suitability of its products for any particular purpose, nor does Silicon Laboratories assume any liability arising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without limitation conse- quential or incidental damages. Silicon Laboratories products are not designed, intended, or authorized for use in applications intended to support or sustain life, or for any other application in which the failure of the Silicon Laboratories product could create a situation where per- sonal injury or death may occur. Should Buyer purchase or use Silicon Laboratories products for any such unintended or unauthorized ap- plication, Buyer shall indemnify and hold Silicon Laboratories harmless against all claims and damages.