SYS/BIOS and controlSUITE ADC Example

From Texas Instruments Wiki
Jump to: navigation, search

Summary

The purpose of this application is to demonstrate how you would convert an example application found within controlSUITE and incorporate it into SYS/BIOS. This example application will demonstrate an ADC periodically sampling the ADC0 pin. For the sake of keeping this article generic device specific information will be ignored. This article also assumes the user is familiar with the SYS/BIOS basics that are covered in the SYS/BIOS 1.5 Day Workshop.

The following host software development tools and target content components were used with this example.

Project Files

Two attached example projects are included:

Media:Sysbios_adc_f28335.zip Example Project for the TMS320F28335

Media:Sysbios_adc_concerto.zip - Example project for the 28x DSP in the F28M35H52C1


The SYS/BIOS portion of the code is based on the SYS/BIOS->28x Examples->Task Example which can be found under the “Project templates and examples section” of the New CCS Project window.

Example applications on how to interface with specific peripherals are located in controlSUITE. The attached project for the F28M35x device is based on the "adc_soc" example located under the “F28M35x_examples_Control” folder within controlSUITE. For the F28335 device, "adc_seqmode_test" example located under the DSP2833x_examples_ccsv4 directory within controlSUITE was used.

SYS/BIOS Modules Used

  • Clock- Periodically calls a function.
  • Hwi - Calls a function when a specific hardware interrupt is triggered.
  • Task - Low priority function that runs continuously.
  • Semaphore - Synchronizes the action of multiple threads that work together.
  • LoggerBuff - Can store messages that will be sent to Code Composer when the application is paused.

Important Functions Created

  • startAdcSeq - This function is periodically called every 100 milliseconds by the Clock module. When ran a single ADC conversion will be initiated.
  • readAdc - The Hwi module will call this function when the ADC’s end of conversion triggers an interrupt. The result of the ADC conversion will be stored and a semaphore will be posted to wake up the copyResult function.
  • copyResult - This function will continuously loop but will go to sleep until the readAdc post to its semaphore. When woken up, the adcResult variable will be saved to a buffer and a message will be sent to the Logger buffer stating the value of the current adcResult. The function will then go back to sleep waiting for another semaphore post.

Starting Point

The Task example is a good starting point since it already enables the majority of the modules we will need. However, this module doesn’t include the Clock module we will use and it also includes the Timer module that will be disabled.

Modification to the SYS/BIOS Task Example Configuration File

Enabling and Creating a Clock Instance

Double click on the task.cfg file under Project Explorer. On the right hand side, you should see several tabs. Click on the tab that says “Available Products”. In the dropdown that is displayed, click on SYS/BIOS. Click on "Scheduling" and then right click on Clock. Select the option “Use Clock”.

Enable the Clock Module

Sysbios-enable use clock.png 


A new "SYS/BIOS Clock - Basic Options" screen will appear.


Sysbios-clock-options.png 

 

Under "Time Base" select “Use Timer to automatically call Clock_tick()”. Clock uses the Timer module to create a timer to generate the system tick, which periodically calls Clock_tick(). Tick period is the unit of time used for the Clock module. Therefore, by setting the Tick period to 1 millisecond the Clock instances will be based on multiplies of 1 millisecond.

Creating a Clock Module Instance

Now click on the Outline tab that is located to the right of the Available Products tab. This shows all of the modules that have been enabled and for certain modules it shows the module's instances that were created.


Sysbios-outline list.png


As started earlier, an instance of the Clock module will be used to call a function that will periodically start an ADC conversion. Under the Outline tab, right click on Clock and select “New Clock”. Click the Ok button that is located in the “Create new Clock” window that pops up. The “Portable Clock Instance - Basic Options” screen will appear.


Sysbios-portable clock options.png


Under "Thread Settings", set the "Name" field to adcSeqClock. This sets the newly created Clock instance name to adcSeqClock. Set the "Function" field to startAdcSeq. This is the function that will be called periodically by the Clock module's instance.

Set both the "Initial timeout" and "Period: field to 100. The unit of time for both of these fields is based on the Clock module’s Tick Period which was set to 1 millisecond. Therefore, a value of 100 in the Period field indicates that the startAdcSeq function will be executed every 100 milliseconds. The same logic applies to the "Initial timeout" field.

Also check the “Requires runtime start” checkbox. This makes sure that this Clock instance runs automatically at startup.

Enable Clock Manager and Software Interrupt Support

Save the task.cfg file. Under the Outline window, red error boxes will appear next to Clock and adcSeqClock. By default the SYS/BIOS Task example application disables the Clock Manager and Software Interrupts from being used. In Code Composer Studio if you click the Problems tab, which is usually located on the bottom, you will see that this is the problem.


Sysbios-clock and swi errors.png 


Since the Clock module will be used, Software Interrupts and Clock Manager must be re-enabled. Under the Outline tab click on “BIOS”. On the new screen that appears click on the button that says “Runtime”.


Sysbios-welcome.png


This will display the “SYS/BIOS - Basic Runtime Options” screen.

  • Note You might not see the same exact screenshot as above. However, you should still click on the Runtime button.


Under Threading Options check both “Enable Software Interrupts” and “Enable Clock Manager”.


Sysbios-threading options.png 


If you save the task.cfg you should see the previous errors disappear.

Creating Hwi Instance

Under Outline, right click on “Hwi” and Select “New Hwi…”.

Click on Ok in the “Create new Hwi” window. Click on the hwi0 entry that appears under “Hwi”. The "C28x Hardware Interrupt Instance - Basic Options" screen should appear.


Sysbios-Hwi-Basic Options.png 


Under the "Required Settings" section, set the Name field to adcHwi. Set the “ISR function” field to readAdc. The” Interrupt Number” field value will depend on which interrupt is set at the end of an ADC conversion for ADC0. For this Hwi instance, readADC should run at the end of an ADC conversion for ADC0. On the Concerto example application that was included in this article, ADCINT1 is set at the end of an ADC conversion which is mapped to INT 1.1 in the PIE. The Concerto Technical Reference Manual states that this interrupt is mapped to Vector ID/Interrupt Number 32. Therefore, the "Interrupt Number" field should be set to 32. The same concept applies to other devices. 

LoggerBuf Module

Now under Outline, click logger0 that is located under LoggerBuf. No settings are needed however it is worth understanding the various options.


Sysbios-Logger Buf Options.PNG


Under Buffer Settings, there is a “Number of records” field. This field specifies how many messages/records this log buffer will store. The other field “Buffer overflow policy” determines what happens if you try to add more records to a log when it is already full. The two options are to replace the oldest record with the newest record and the other is to ignore any new records after the buffer has been filled.

Configuring Semaphore Instance

Under Outline, click mySem which is located under Semaphore.

Sysbios-semaphore instance.png

Set the Name field to adcResultSem. This sets the name of the semaphore instance and the variable name that will be used in the program. Change the “Semaphore type” to a “Binary Semaphore”. The option “Binary Semaphore” means that a semaphore’s count variable can only be 1 or 0. This is usually when you want to protect a variable or a section of code from being ran simultaneously by another thread. This semaphore will be used to only allow the Task function to store the adcResult variable and print out the variable’s value after the Hwi has updated the variable and posted the semaphore.

Configuring Task Instance

Under Outline, select myTask located under Task.

Set the “Name” field to adcTask and set the “Function” field to copyResult.


 Sysbios-task instance.png

Deleting the Timer Instance

This example application doesn’t require an instance of the Timer module therefore to save memory we should delete it. Under Outline, right click and delete the myTimer instance located under Timer.

Graphing Data

In the copyResult task, the result of the ADC was added to an array. This most likely would be use for further processing of the data. However, you could also use Code Composer Studio to graph the data while the system is running. The Graph Visualization for MSP430 article explains how to use this useful feature in Code Composer Studio.

Known Issues:

Below contains several issues that were corrected in the attached example projects. Note that these corrections were tested only for the F28335 and Concerto platforms. However, these changes might also be applicable for other platforms.

Concerto

Errors #10265, #10099-D and warning #10097

These errors and warnings point to the below statement located in the F28M35x_Headers_BIOS.cmd file:

 PieVectTableFile  : > PIEVECT, PAGE = 1

 This is due to the PIEVECT being placed in the wrong PAGE in the memory linker command file (F28M35H52C1.cmd).

Move the below statement from the PAGE 0 section to the PAGE 1 section in the memory linker command file.

PIEVECT : origin = 0xD00, length = 0x100

10247-D creating output section "ramfuncs" without a SECTIONS

Add the following lines to the memory linker command file "F28M35H52C1.cmd". 

ramfuncs : LOAD = FLASH PAGE = 0,
	   RUN = L03SARAM PAGE = 1,
	   LOAD_START(_RamfuncsLoadStart),
	   LOAD_SIZE(_RamfuncsLoadSize),
	   RUN_START(_RamfuncsRunStart)

F28335

Warning: #303-D typedef name has already been declared (with same type)

This warning is due to a conflict between typedefs defined in SYS/BIOS and the controlSuite libraries. To solve this add the following statement at the very top of your source code:

#define xdc__strict

#10247-D creating output section "ramfuncs" without a SECTIONS

For F28335, add the following lines to the memory linker command file "TMS320F28335.cmd" somewhere within the "SECTIONS" section.

 	ramfuncs : LOAD = FLASH PAGE = 0,
		   RUN = L07SARAM PAGE = 1,
		   LOAD_START(_RamfuncsLoadStart),
		   LOAD_END(_RamfuncsLoadEnd),
		   RUN_START(_RamfuncsRunStart)

Training

The "Intro to TI-RTOS Kernel Workshop" is now available. Follow the link below to find out more. The TI-RTOS Kernel Workshop covers the SYS/BIOS operating system available for all TI embedded processors - C28x, MSP430, Tiva-C, C6000 and AM335x (Cortex A-8). You can take a LIVE workshop (scheduled at various sites around the U.S.) or download/stream the videos of each chapter online and watch at your own pace. All of the labs, solutions, powerpoint slides, student guides, installation instructions, lab procedures, etc., are all available to you. The workshop labs run on all MCU platforms and the C6000. Check it out...

Intro to TI-RTOS Kernel Workshop