MQX Software Solutions Knowledge Base

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MQX Software Solutions Knowledge Base

Discussions

Sort by:
Hi everybody, As there is not a New MQX 4.2 Project Wizard, it is necessary to create a project from scratch. Here, we will create a new project making a copy from an example Project, for this example we are using FRDM-K64F120M but the process is similar for all the Freescale boards. 1. Import hello_frdmk64f example and just copy-paste it using Ctrl + C and Ctrl + V keys. 2. Delete the virtual folder to avoid editing the original file. 3. Create a New physical folder and named it Sources. 4. In Sources folder create a New Source file and name it main.c 5. Go to menu Project > Properties > C/C++ Build > Settings > Cross ARM GNU Assembler > Includes and delete all the paths. 6. Go to menu Project > Properties > C/C++ Build > Settings > Cross ARM C Compiler > Includes, delete all the paths and replace them with the following: C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\bsp\Generated_Code C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\bsp C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\psp C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\mfs C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\rtcs C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\shell C:\Freescale\Freescale_MQX_4_2\usb_v2\<used_board>.kds\debug\usbh\mqx ${eclipse_home}../toolchain/lib/gcc/arm-none-eabi/4.8.4/include ${eclipse_home}../toolchain/lib/gcc/arm-none-eabi/4.8.4/include-fixed ${eclipse_home}../toolchain/arm-none-eabi/include For the FRDM-K64F120M C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\bsp\Generated_Code C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\bsp C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\psp C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\mfs C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\rtcs C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\shell C:\Freescale\Freescale_MQX_4_2\usb_v2\output\frdmk64f.kds\debug\usbh\mqx ${eclipse_home}../toolchain/lib/gcc/arm-none-eabi/4.8.4/include ${eclipse_home}../toolchain/lib/gcc/arm-none-eabi/4.8.4/include-fixed ${eclipse_home}../toolchain/arm-none-eabi/include Note: You can use  Ctrl + C and Ctrl + V keys. 7. Go to menu Project > Properties > C/C++ Build > Settings > Cross ARM C Linker > General and replace the linker file path with the following C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\bsp\intflash.ld For the FRDM-K64F120M C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\bsp\intflash.ld   8. Go to menu Project > Properties > C/C++ Build > Settings > Cross ARM C Linker > Miscellaneous and replace all Other objects with the following: C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\bsp\bsp.a C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\psp\psp.a C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\mfs\mfs.a C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\rtcs\rtcs.a C:\Freescale\Freescale_MQX_4_2\lib\<used_board>.kds\debug\shell\shell.a C:\Freescale\Freescale_MQX_4_2\usb_v2\output\<used_board>.kds\debug\usbh\mqx\libusbh_mqx.a ${eclipse_home}../toolchain/lib/gcc/arm-none-eabi/4.8.4/armv7e-m/fpu/libgcc.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libc.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libsupc++.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libm.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libnosys.a For the FRDM-K64F120M C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\psp\psp.a C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\mfs\mfs.a C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\rtcs\rtcs.a C:\Freescale\Freescale_MQX_4_2\lib\frdmk64f.kds\debug\shell\shell.a C:\Freescale\Freescale_MQX_4_2\usb_v2\output\frdmk64f.kds\debug\usbh\mqx\libusbh_mqx.a ${eclipse_home}../toolchain/lib/gcc/arm-none-eabi/4.8.4/armv7e-m/fpu/libgcc.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libc.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libsupc++.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libm.a ${eclipse_home}../toolchain/arm-none-eabi/lib/armv7e-m/fpu/libnosys.a 9. Click to Apply and Ok buttons. 10. Go to C:\Freescale\Freescale_MQX_4_2\mqx\examples\hello and copy all the content in hello.c to main.c in your project 11. At this point you can be able to build and debug your New project. Enjoy...
View full article
1. Few basic questions and answers about FlexNVM and FlashX. 1.1 What is FlexNVM? FlexNVM is additional separate block of flash memory which could be used as data flash, as non volatile storage for emulated EEPROM or as combination both option. I will focus on first option in this document – FlexNVM will work simply as data flash. FlexNVM you can find in MCU parts which contain “X” at dedicated place in part number. For example: MK64FX512VMD12 contains 1 block (512 KB) of program flash and 1 block (128 KB) of FlexNVM MK64FN1M0VMD12 contains 2 blocks (512 KB each) of program flash only. For more details about FlexNVM and flash blocks, please see your MCU reference manual. For example chapter “Flash Memory Sizes”. 1.2 What is FlashX? MQX FlashX driver provide ability to write to and read from internal flash. Unfortunately FlexNVM memory is supported only partially in default state – Some of BSPs has implemented configuration and functions for emulated EEPROM (flexnvm example code). For more details, please check MQX_IO_User_Guide.pdf in c:\Freescale\Freescale_MQX_4_2\doc\mqx folder. 1.3 Can I use BSP for MCU without FlexNVM for my own board which has MCU with FlexNVM? It is not recommended. However you can use this BSP as base for your own board BSP. Please check MQX_BSP_Cloning_Wizard_Getting_Started.pdf, MQX_BSP_Porting_Guide.pdf  and MQX_BSP_Porting_Example_User_Guide.pdf documents in C:\Freescale\Freescale_MQX_4_2\doc folder. 1.4 Can I use FlashX in my KSDK project? Unfortunately FlashX driver was not implemented into KSDK. KSDK contains its own Standard Software Driver (SSD) for C90TFS/FTFx Flash family, however this is just low level driver without high level abstraction layer like in case of FlashX driver. 2. Procedure for update MQX FlashX driver to support FlexNVM. 2.1 Please backup these files: user_config.h, <your BSP>.h, init_flashx.c, flash_ftfl.c and flash_ftfe.c files. Note: user_config.h, <your BSP>.h and init_flashx.c are part of your BSP code. 2.2 Enable FlashX in user_config.h file by definition: #define BSPCFG_ENABLE_FLASHX                      1 2.3 Updates of <your BSP>.h file: 2.3.1 Please check MCU reference manual and update BSP_INTERNAL_FLASH_BASE, BSP_INTERNAL_FLASH_SIZE, BSP_INTERNAL_FLASH_SECTOR_SIZE if necessary. Typically we have to decrease BSP_INTERNAL_FLASH_SIZE in case when BSP without FlexNVM was used as base for own BSP. 2.3.2 Add new macros which will define FlexNVM in memory map. For example: #define BSP_INTERNAL_FLEXNVM_BASE  0x10000000 #define BSP_FLEXNVM_SECTOR_SIZE         0x400 #define BSP_INTERNAL_FLEXNVM_SIZE  0x00008000 2.4 Update init_flashx.c in your BSP folder: 2.4.1 Add FlexNVM file block into _bsp_flashx_file_blocks[] table. For example:     // data flash file block     { "dflash", BSP_INTERNAL_FLEXNVM_BASE, (uint32_t) (BSP_INTERNAL_FLEXNVM_BASE+ BSP_INTERNAL_FLEXNVM_SIZE - 1) },    Parameters are {name of file block, start address, end address}.    Note: This is pure software interface; range of addresses doesn’t need fit to physical flash block parameters. You can organize file blocks according your needs. 2.4.2 If you used non-FlexNVM BSP as base for your own BSP, you have to change HW block map for KinetisX devices. Please change _flashx_kinetisN_block_map into _flashx_kinetisX_block_map in _bsp_flashx_init structure. 2.5 Update flash_ftfl.c or flash_ftfe.c file: 2.5.1 Look at MCU reference manual whether your MCU has FTFL or FTFE flash memory module and select appropriate file for editing. 2.5.2 Add FlexNVM memory block into _flashx_kinetisX_block_map[] table. For example: { BSP_INTERNAL_FLEXNVM_SIZE / BSP_FLEXNVM_SECTOR_SIZE, (_mem_size) BSP_INTERNAL_FLEXNVM_BASE,  BSP_FLEXNVM_SECTOR_SIZE }, // FlexNVM block Parameters are {number of sectors, start address, sector size}. Note: This is description of physical hardware memory block; range of addresses must fit to physical flash block parameters. 2.5.3 Now we have to fix problem with FlexNVM address. Both Program Flash and FlexNVM Flash are programmed trough FTFL_FCCOBn / FTFE_FCCOBn registers where FCCOB1.. FCCOB3 contains address in 24bit format. Therefore we cannot work directly with FlexNVM addresses – they will not fit into 24bit due to FlexNVM base 0x10000000. FTFL/FTFE modules specifies that most significant bit in 24bit address (bit 23) will be used for distinguish between Program Flash and FlexNVM Flash. We can use for example such code: //Set 23th bit when FlexNVM flash address     if (write_addr & BSP_INTERNAL_FLEXNVM_BASE)     { write_addr = write_addr | (1 << 23);     }   and add this code into necessary functions prior write into command_array[] (content of command_array[] will be used for filling FTFL_FCCOBn / FTFE_FCCOBn registers). For basic work of FlashX example code is necessary update at least ftfl_flash_erase_sector()/ftfe_flash_erase_sector() and ftfl_flash_write_sector()/ftfe_flash_write_sector() functions. 2.6. After these changes, you can try using FlashX example code in flash_demo.c where you simply open FlexNVM file block instead of default program flash file block. For example: //#define FLASH_NAME "flashx:bank0" #define FLASH_NAME "flashx:dflash" In attachment file you can find example of modification for MQX4.2.0 and MK20DX72 MCU. 3. How to rewrite flash - general notes: Flash data must be in the erased state before being programmed. Cumulative programming of bits (adding more zeros) is not allowed. In case of both FTFL and FTFE modules we program flash by aligned phrases (typically 64 bits). If we want program by smaller chunks (e.g by bytes), FTFL module will allow you write into this phrase even if it is not recommended. However FTFE module will cause bus fault in case of second write into the same phrase. So, only save way how to change data in FTFE phrase which was already written is erase whole sector and rewrite data back. Therefore please use ioctl command FLASH_IOCTL_ENABLE_SECTOR_CACHE for FTFE module. The sector cache allocation is not required in case of Full sector write and partial sector overwrite when the destination area (aligned to phrases) is blank.
View full article
Hi Community, Based on How To: Create an MQX RTOS for KSDK project with Processor Expert in Kinetis Design Studio IDE from macl​ and dereksnell you can find in the attached document the steps to include RTCS to a KDS3.0 project using KSDK1.2 and Processor Expert as well as the final project. Thank you RBORB​ for providing the first draft of this process. For information about creating a new KSDK project with MQX and without Processor Expert please see the following document. How To: Create a New MQX RTOS for KSDK Project in KDS If you are looking for a simple document to get started with KSDK please see the following document. Writing my first KSDK1.2 Application in KDS3.0 - Hello World and Toggle LED with GPIO Interrupt Regards, Carlos
View full article
The attached document explains how to create a C++ project using CW10.6 with GCC compiler, MQX 4.1. Regards, Carlos
View full article
Hi Community members:   Here you can find the source code of a MSD ftp server, it is implemented on the  MQX 4.2 using the FRDM-K64 and IAR 7.40.3. The USB storage device should be connected to the board and the board to a Ethernet network. In this demo, usb stick is mounted as a:/ You can upload or download files saved in the memory device.   I hope this can be helpful.   Best regards Daniel Original Attachment has been moved to: shell.zip
View full article
Table of Contents Product Information on Freescale.com MQX Lite RTOS Product Summary Page Frequently Asked Questions (FAQ) General MQX FAQs Technical MQX FAQs Other Resources MQX Training Videos MQX Add-On Software
View full article
MQX RTOS Task Aware Debugging plug-in (TAD) is an optional extension to a debugger tool which enables easy debugging of multi-tasking applications. With TAD, we can inspect task contexts and kernel objects. Typical use cases include --view task error codes --Examine stack usage for each task --Examine memory usage -- Debug TCP reception problems --Examine socket and PCB data --Observe memory pool / message pool utilization levels -- Observe synchronization objects The following is a description of MQX task aware debugger and an example to debug a stack overflow. It is based on web_hvac demo in the MQX installation folder, it also applies to other applications. The MQX pull down menu is as below picture shows. The task summary window shows all the tasks in the system, the task name , task id , task state, priority and Task error code. The idle task is also listed since this is still treated by MQX  as a task, and can be helpful to know what’s happening with it. The stack usage window shows what percentage that allocated for a task interrupt have been used so far. This is a high watermark not the amount of the stack currently been used. If more than allocated stack is being used as some point, then you will see an over flow has been indicated at last column. Also for reference, the address for both the base for up and down are  shown. The kernel data window can be useful for confirming the environment you are running is actually what was loaded. You give them some key data such as the version of MQX running, the CPU, the PSP.  The settings of the time component and a number of the compile time configuration settings to confirm if you have things like the kernel logging or stack monitor turned on. The memory blocks window shows all of the blocks of memory that memory manager has currently reserved for kernel objects or application tasks.  Listed is starting address for each block , the size of each block in hexadecimal , who is the owner of each block.  Which can be either the system or specific tasks, and shows the type of block. We see different types such as the block for interrupts stack, system stack, task ready queue, block associated with interrupts.  The logging feature, message pools etc. Down to the bottom, we see the stacks specific memory blocks including the task descriptor and task space.  TAD knows what the task descriptor is so it gives all the information related to the task. The next group of windows  are related to various synchronizations  that MQX supports.  Such as semaphores and events ,mutexes. If some are greyed out and that because application doesn’t use it.  Example of Debugging with TAD In order to gain experience using the Task Aware Debugging (TAD) feature and to learn how it can be used to debug an application, I created a stack overflow in the shell task in web_hvac demo by reducing the task stack size from 2400 to 500. If I now run the application, we can see the application run into idle task quickly. Opening up the stack usage window, we see that indeed an overflow was detected. And that the stack information for the Shell task has been corrupted as a result.  The task summary window also has the corrupted information for the shell task. If you look closely, the listed tasks are short than before, and if you compare the list of tasks what you expected to be there. You noticed to shell task has completed disappear. But when we look at the console, we see that it clearly started. So where did it go? The stack overrun is a good clue. But also recommend scanning check for errors window. By reviewing the task summary, stack usage and errors windows, and doing a sanity check again the states values that expecting   can be very helpful ,make sure all the tasks are there. Check for error codes, and look for stack issues. To debug an application, the following steps should be follow: Review key TAD windows:                  Task Summary Window Stack Usage Window MQX Errors Window Audit various system parameters: -     Which tasks are running. -     Task states -     Check for identified errors -     Look for stack overflows
View full article
MQX includes a great demo for the web server in \<MQX_Path>\demo\web_hvac.  The web pages in this demo show how MQX can serve up data through the web server, and dynamically update the web page, for example the thermostat hvac properties are updated every second.  Also, the user can use a web page form to submit data to the server and update the application, like changing the temperature set point.  This is done with HTML forms, javascript, and CGI running in the MQX application. However, the web_pages directory in the web_hvac demo is missing the actual source files for the web pages.  Starting with MQX v4.0.2, they disappeared from the MQX release.  And since then, the web server APIs and CGI functionality has changed.  Posted here is the web_page directory for web_hvac, including the source code for the web pages.
View full article
Flash memory is critical component to any system, and it’s important to be able to access flash memory efficiently. In this document, we will look at the differences between the two main types of flash used today, NAND flash and NOR flash, how to erase and access flash. Then we will look at the MQX flashx driver, which can be used for both types of flash. Accessing NOR and NAND Flash There are two main types of flash memory, the first being nor flash , and the second being nand. For an interface point of view, the main difference is how the data is accessed. Nor flash is a full address and data  bus, similar to random devices, and nand devices is using io bus with commands , address and data being multiplexed to share the same bus. It is greatly reduces the number of pins to require connectivity in devices , But for software and data access perspective , there are more significant differences between the two types of memory. At the core, each bit is storing using different tech knowledge. With nor flash , the memory region is divided by equal size units called blocks.  The size of each block in today’s technology ranges from roughly 32k bytes to 128 kbytes, but this is  totally dependent on the devices select and over the years this is changed.  The internal circuitry of nor flash allows each byte of the device can be individually addressable in the same way that you can address bytes stored in ram, or in an EEPROM and this is why a full bus is used with nor flash. However this only applies for reading a byte or programming an individual byte, the racing skimming must be done at the block level,  so unlock a  race state requires the entire block to be affected. Nand flash , however, has being purposely architected differently in order to increase the storage density.  It too has a memory region divided in equal size of  blocks, but each of these blocks are further broken down into samll regions that are called pages, the page is typically 2k bytes in size and a block often has 64 pages, so 128 kbytes , to the lead data you still be working at the block level, but if you want to read and program part of flash, this is done page by page. However storing or retrieving data one page at a time is actually an advantage for many applications. Since you are often working with a large files such as  a phone, a song or an app.  So this is can be more efficient. The main draw back then of not being able to access bytes  individually is that nand flash can’t  be used to store a program code that you want to be executed in place. Since a CPU needs to read a single instruction, unless your CPU can specifically support this arrangement. There are a couple of downsize that the nand flash you maybe aware of however,  the first is in getting bit errors when you reading a page,  this is may not be a disater for musical file but obviously not acceptable for a data file or a backup for your image. To compensate for this , each page of flash has two sections,  the first is where your data is stored and the second is a smaller section is where error correction code is stored. There are differenct algorithm used to detect and correct for errors but the ideal is the data stored in ecc is used by the algorithm to detect errors  in the data,  and in some cases  correct an error in the data  field.  There is a limit to how much corruption can be detected, but minor errors such as a single bit error are dealt with regular basis without the application ever knowing it occurred. The second issue with nand to be aware of that it is more prone to developing a faulty bit. And this is caused an entire block to be declared as being bad, in fact even a new flash device will have a small percentage of blocks bad and over time some of the active blocks can be come bad. Circuitry in the flash device detects the block’s bad during erase or progam cycle and a bad block manager keeps track of this . Blocks of bad are automatically remapped, and since this happens behind,  the interface of software  doen’t know the difference. So to summarize the key differences between nor and nand, we saw you have to access data in pages with nand which is randly access in bytes . and there are differences in access time to erase, write and read from flash. The capacity  the flash  device contiues to rise for writes that is a steady rate,  but currently the largest nand devices have 10 times capacity of largest nor devices. And in terms of issues don’t impact the application code, we saw the nand flash requries bad block management  and error correction codes to deal with failure rate that experiences, the pin count is higher in nor given a type of interfaces has, which couple of with different capacity makes it more expencsive. And depending on how you using memory you maybe concered about the expected life cycle  of a chosen device . Eraing Flash Before getting into the driver though, the only other thing to cover you may come across when working with the flash has to do with the erase process, you may expect to read back the erased portion of memory has been all zeros but in fact  the erased flash memory has all bits set to the high state, so it read back the erased byte as being FF. When you write data to your address location  , the corresponing bits need to be zero are programed as logical zero and efficiently you can rewrite this location with first erase it providing you unwanted any of these bits transition from 0 to 1.  You can also write to a different address in the same block without first erasing block,  but in most cases you writing a large chunk of data, not a single byte,  and typically you don’t want to bother keeping in track of data   as being where to written to .  And for block should be erased before  write or not. This is what the driver does for you, which keeps your application quite simple, however,  be aware the overhead associated with the right command won’t  always be consistant.  As you sometimes you endure an erase and rewrite cycle, and other times you won’t. Where Flashx Driver Resides There are two groups of drivers in MQX, the first group contains io drivers, go through the io subsystem.  And it includs block mode drivers and byte mode drivers . The second group is a set of low level drivers such as the ADC and the lightweight GPIO driver. Since flash driver supports the writing and reading data of large chunks, it is categorized as blocked mode driver . In the SDK verison of MQX, the io sub system is limited. But the flash driver is still be considered as block mode driver. Similar to the structure of other drivers we’ve looked at, there is an upper layer and lower layer component in the flash driver. and before you can begin using any dirver, it has to be installed. If you selected flash using a configuation file, MQX will automaticly install the flash driver at boot up.  And when you install function is called,  the upper level will install function is passed a pointer to the low level configuration information. The installed function registered it’s called back function to the IO subsystem, once it’s associations are in place , your application code can use a normal a high level calls that access the flash device.  So for example,  before using the flash driver , you must open it , which will set up internal structures for the flash chip if hasn’t been opened before.  And will fetching the addressing for this device . You can then read from flash or write to it as you like using the high level commands. Accessing Flash Before getting further with using the driver though, it will be helpful to see how to access the flash itself.  The flash is organized to a series of blocks and you can structure those in different groups.  If you are using a kinetis processor, and using the flashx driver to access the internal flash, then as a minimum you need have a room for code base and reserve a saparate area for your data. You can also set your flash for equal size banks or however you wish to organize your  flash,  just keeping in mind the boundaries of these regions must be falled into block boundaries in the    flash . Each of these regions are effectively  a partition of the flash and the flashx driver refer to each partition  is a file or see in a monent the region of a flash you use for a file may not be continuously from address point of view , but for application point of view it can be considered to be continuous memory space. Accessing Flash Mqx maitans an index into a file and when you read from the file, the reading starts from an index, similarly, when you write to the file, it starts writing from the  index point , and the index  commands , as you wirte more data. Your application code can  adjust the location index, using  the fseek function , you maybe familiar with the fseek function found in a formatted  io section of starndard C library , and mqx’s fseek function is used in the same way. It can be used to set the index to provide  the offset from the beginning of a file, with an offset from the end of this file  , or to an offset in either  direction from the current position of the index. Data structures To understand flashx driver how it works , you need to farmilar with some key data structures that it uses. The first one to cover is the block info structure which defines how the flash is organnized. Some flash has different size blocks inside of it or maybe there is gaps between addressing . So this is a way of define a flash infrastructure. Your device will be represented by an array  or a block info structures,  one section for each section a  flash has continuous addressing  and all blocks  are in equal size.  The terminal is a bit  confusing here,  within each section of flash  there will be a number of blocks,  and the data structure   refers to is a  sector,   as mqx considers a sector to be the smallest eraseable units. The next element of this structure is the starting address of this section which is followed by the size section. The final element is reserved for any special flags and currently not being used. You can have a number of files in flash, the file block structure is used to define  a file, and it cantains a name for the file , the starting address for the file, and an ending address for the file, And the third data structure called the init structure is used to tie everything together , this contains a pointer to a array of block info structure, and a pointer to a array of file block structures, this also contains the base address of the flash device and some additional elements used to access the total flash address base . Flash Driver API So to summarized before we look  at the driver code, accessing the flash is very straight forward.  You must open the file  with the fopen function , and with the flashx driver , flags are not typically used.  To read from the file , you speciafy with reading data to be stored , and the number of bytes to read. And to write the flash you should provide  a pointer to the data to be written, and the numbe of bytes to transfer. And the last function we used, is the ioctl function, which can be used to retrieve or change the various parameters. When you using the ioctl function, you specify the command you want to use. And a point to where the result will place if you request a value as parameter . So what source code can you make .  you can retriev various values,  such as the base address, or the number of sectors.  You can flush the buffer, or control the buffering feature, erase all or part of flash chip, control the sector caching, or control the write protect. This document is the 19th Installment of the "Essentials of MQX RTOS Application Development" training course. Please watch the vedio for more details Essentials of MQX RTOS Application Development, Ses|NXP
View full article
I have just implemented an I2C demo for my customer, he found no demo for MMA8451Q based on MQX 4.1, so I personally wrote one for him based on the I2C EEPROM demo, as well as the driver code for MMA8451Q supporting both polled and interrupt mode. I think maybe it would be interesting for someone else, so I posted it here. The demo is for TWR-K60D100M, but I think it should be easy to port to some platform else, for example , TWR-K21F120M, all you have to do is creating a new MQX project and replace the source code with the attached one, Please also note the I2C device address might be different in tower boards. You may change the deifintion of I2C_MMA8451_BUS_ADDRESS in MMA8451.h according to the schematics. Please kindly refer to the attached result.txt for more details. Hope that helps, B.R Kan
View full article
Hi Community, Based on How to add RTCS to a Processor Expert Project Using KDS and KSDK​,  below you can find the steps to include MFS and Shell to a KDS3.0 project using KSDK1.2 and Processor Expert. Thank you Carlos_Musich for his great document and for providing the draft of this document. Regards, Isaac Avila
View full article
TWR-K70F120M running MQX and RTCS can work with the Dual Phy on TWR-SER2. Below I list the modifications I did to the default BSP: 1) I add phy_dp83xxx.c and phy_dp83xxx.h to the bsp_twrk70f120m build project. These files are with MQX in /mqx/source/io/enet/Phy 2) I modify the BSP to use DP83xxx PHY for the Ethernet MACNET: in the /mqx/source/bsp/twrk70f120m/init_enet.c: #include "phy_dp83xxx.h" const ENET_IF_STRUCT ENET_0 = {      &MACNET_IF,      //&phy_ksz8041_IF,      &phy_dp83xxx_IF,      MACNET_DEVICE_0,      MACNET_DEVICE_0,      BSP_ENET0_PHY_ADDR,      BSP_ENET0_PHY_MII_SPEED }; 3) MDIO line requires an external pull up resistor, per DP83849I Data sheet. As I didn't have one at the moment, I enable internal pull up on MCU pin PTB0. in the /mqx/source/bsp/twrk70f120m/init_gpio.c: //pctl->PCR[0] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK; /* PTB0, RMII0_MDIO/MII0_MDIO   */ /* PTB0, RMII0_MDIO/MII0_MDIO   */ /* internal pull up enabled on MDIO */ pctl->PCR[0] = PORT_PCR_MUX(4) | PORT_PCR_ODE_MASK | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; With these changes, the RTCS applications work over TWR-SER2 Dual PHY channel A. On TWR-SER2, J8 and J9 are un-shunted, SW1 = 11000000, SW2 = 10100000 on TWR-K70F120M, J18 is configured to disable 50 MHz OSC, as I use 50 MHz clock source from TWR-SER2 U504 50 MHz output. This clock is used to provide reference clock for the MCU (EXTAL), as well as for the Dual PHY X1 input (RMII reference clock).
View full article
Table of Contents Product Information on Freescale.com MQX Software Solutions Product Summary Page MQX Software Solutions Documentation MQX Software Solutions Downloads MQX Software Solutions Training Frequently Asked Questions (FAQ) General MQX FAQs Technical MQX FAQs Other Resources MQX Training Videos MQX Add-On Software
View full article
MQX 4.1.0 provides a USB Host CDC demo in the folder of "C:\Freescale\Freescale_MQX_4_1\usb\host\examples\cdc\cdc_serial", but to get it work, several steps need to be done: 1. Change CDC_EXAMPLE_USE_HW_FLOW in cdc_serial.h to 1. #define CDC_EXAMPLE_USE_HW_FLOW 1 2. In config\twrk70f120m\user_config.h, interrupt mode for UART should be set.//It depends on the platform, here given TWR-K70F120M is used. #define BSPCFG_ENABLE_TTYC 0 #define BSPCFG_ENABLE_ITTYC 1 In mqx\source\bsp\twrk70f120m\twrk70f120m.h, specify 'ittyc' instead of 'ttyc' #ifndef BSP_DEFAULT_IO_CHANNEL #if BSPCFG_ENABLE_ITTYC #define BSP_DEFAULT_IO_CHANNEL "ittyc:" /* OSJTAG-COM polled mode */ #define BSP_DEFAULT_IO_CHANNEL_DEFINED #else #define BSP_DEFAULT_IO_CHANNEL NULL #endif #else 3. In usb\host\source\classes\cdc\usb_host_cdc.c, pass fd_ptr instead of data_instance as the argument. a. Around line 977 //usb_hostdev_tr_init(&#38;tr, (tr_callback) usb_class_cdc_in_data_callback, (void *) data_instance); usb_hostdev_tr_init(&#38;tr, (tr_callback) usb_class_cdc_in_data_callback, (void *) fd_ptr); b. Around line 1116 //usb_hostdev_tr_init(&#38;tr, (tr_callback) usb_class_cdc_in_data_callback, (void *) data_instance); usb_hostdev_tr_init(&#38;tr, (tr_callback) usb_class_cdc_in_data_callback, (void *) fd_ptr); c. Around line 1226 //usb_hostdev_tr_init(&#38;tr, (tr_callback) usb_class_cdc_out_data_callback, (void *) data_instance); usb_hostdev_tr_init(&#38;tr, (tr_callback) usb_class_cdc_out_data_callback, (void *) fd_ptr); With above modification , the Host CDC demo can work with a Device CDC demo, such as the one in "C:\Freescale\Freescale_MQX_4_1\usb\device\examples\cdc\virtual_com", which is an echo demo, it would send back anything charactor that it receives. But to see the echo more clearly, I made it echo back the charactor that greater than what is received, for example, if you type A, and will see B from the HyperTerminal. To do that , you have to change Virtual_Com_App(void) in the virtual_com.c as below: void Virtual_Com_App(void) {     /* User Code */     if(g_recv_size)     {         _mqx_int i;                 /* Copy Buffer to Send Buff */         for (i = 0; i < g_recv_size; i++)         {             printf("Copied: %c\n", g_curr_recv_buf[i]);             g_curr_send_buf[g_send_size++] = g_curr_recv_buf[i]+1;         }         g_recv_size = 0;     }         if(g_send_size)     {         uint8_t error;         uint8_t size = g_send_size;         g_send_size = 0;         error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT,             g_curr_send_buf, size);         if (!error && !(size % DIC_BULK_IN_ENDP_PACKET_SIZE)) {             /* If the last packet is the size of endpoint, then send also zero-ended packet,             ** meaning that we want to inform the host that we do not have any additional             ** data, so it can flush the output.             */             error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT, NULL, 0);         }         if(error != USB_OK)         {             /* Failure to send Data Handling code here */         }     }     return; } After you download code into, for example, TWR-K70F120(Host) and TWR-K60D100M(Device), and assemble them with TWR-SER and TWR-ELEV, you may connect them via USB port as below: Please also pay attention to J10(USB VBUS Select) and J16(USB Mode Select) according to the function of each tower system. With HyperTerminal connected with TWR-K70F120M system, you may type in any charactor ended with ENTER, and you will see the charactor echoed back as the attached video. This issue would be fixed in the next release, and sorry for the inconvenience that has caused.
View full article
A new patch, MQX v4.2.0.2, is now available at www.nxp.com/mqxclassic​.This release comes in one download that contains both .zip packages and patch files. See the Release Notes (attached) for a full list of issues that are fixed in this release. The Release Notes also contain instructions for how to install via the .zip or patch files. To Download the patch: 1. go to www.nxp.com/mqxclassic 2. Click the "Download" button (below the Overview paragraph) -- you may be prompted to Sign In 3. Click on "MQX RTOS v4.2 releases and patches" 4. Review and click through the license agreement 5. Click on "MQX 4.2.0.2 Patch.zip"
View full article
Essentials of MQX RTOS Application Development Free Online Training Series with Videos, Tutorials, and Example Software! 10-Part Series - even more coming later [Scroll down to see all Sessions] Session 1: MQX Architecture and Initialization (20 min) Creating tasks Setting priorities Scheduling Synchronization concepts Introduction to drivers Session 2: Designing for a Multi-Tasking Environment (15 min) Writing applications in a Multi-Tasking Environment Super Loop Programming Limitations, Task Coding Structure Task States What is a blocking call? Task Context Switching Session 3: Task Management and the Scheduler (21 min) How does the MQX scheduler work? Scheduling Policies Priority-based, Time-slice (Round Robin) Selecting Priority Levels for Tasks What is the Task Template List? Using Tasks in your Application Session 4: Synchronization and Message Passing (17 min) What is Synchronization?  What is it used for? Data Flow, Control Flow, Mutual Exclusion Synchronization Options Events, Semaphores, Mutexes, Message Passing Message Passing Types of Message Pools, Message Pool Creation, Sending and Receiving, Light-weight Message Passing Session 5: Introduction to Drivers (28 min) Driver Architecture and options Block vs. Byte modes, POSIX drivers, Low level drivers, Polled vs. Interrupt modes Driver Initialization I/O Subsystem (POSIX) Serial Driver Details Light-weight GPIO Driver Details Session 6: Interrupts (15 min) Interrupts and the scheduler Techniques for writing an ISR Hardware Vector Table Nested Interrupts MQX Interrupt ISR Table Installing ISRs Default Interrupt handler Session 7: Light Weight Events (15 min) Overview of events Working with light-weight & full-featured events Ways to wait on an event Session 8: Light Weight Timers (17 min) One shot vs periodic timers Use cases for timers Working with correlated timers Writing timer Interrupt Service Routines (ISRs) Light weight timers & timer queues Timers and the timer task Session 9: Light Weight ADC Driver (18 min) Light-weight ADC driver (LWADC) Details Attributes of ADCs Configuring and reading ADCs Scaling the ADC output Session 10: Logging (23 min) What is logging?  Why use logs? Working with light-weight logs Working with kernel logging Logging MQX function and ISR entries and exits, task and stack usage Working with full-featured logs
View full article
Hello all, This document describes how to create a FreeRTOS project in KDS using the Kinetis SDK Project Generator tool. If you are interested in how to Create a FreeRTOS project using KDS and Kinetis SDK Project V2.0 please check the below link: https://community.freescale.com/docs/DOC-330183 In order to follow this document, first it is necessary to install: Kinetis Design Studio (KDS) Kinetis Design Studio Integrated Development |NXP KINETIS-SDK: Software Development Kit for Kinetis MCUs Software Development Kit for Kinetis MCUs|NXP KSDK Project Generator tool Software Development Kit for Kinetis MCUs|NXP Creating a new project using the Project Generator tool Kinetis SDK Project Generator tool is a supplement to the KSDK. It is intended to provide users with a convenient method for generating KSDK based projects for their intended target hardware. The KSDK Project Generator requires the user to install an instance of KSDK 1.2.0 or 1.3.0 before generating new projects. The KSDK Project Generator requires operates on Windows, Linux, and Mac OSX. 1. Launch the Project Generator executable. 2. Introduce the Project Name and choose the board used. For this example it is used the TWR-K64F120M. 3. In order to generate a FreeRTOS project, click on the "Advanced" button. 4. Choose the operating system, in this case FreeRTOS, the IDE KDS and select Generate standalone project. 5. After that, click on "Advanced Generate" button to create the project. Open the project in KDS Every application/example created using the KSDK Project Generator tool has one associated working set description file which includes the path to the example project file and the dependent RTOS library project file. Simply import that file into KDS working space. At this point you should be able to build the library and the project created. Developing a FreeRTOS with KSDK application Operating System Abstraction layer (OSA) provides a common set of services for drivers and applications so that they can work with or without the operating system. OSA provides these services: task management, semaphore, mutex, event, message queue, memory allocator, critical part, and time functions. An easy method to create a task is using  the OSA_TASK_DEFINE macro and the function OSA_TaskCreate(). The macro OSA_TASK_DEFINE declares a task handler and task stack statically. The function OSA_TaskCreate() creates task base-on the resources declared by OSA_TASK_DEFINE. The parameters for this function are: The stack size in byte. Pointer to the stack. The stack size in byte. Pointer to the stack. Initial priority of the task: OSA supports task priorities 0∼15, where priority 0 is the highest priority and priority 15 is the lowest priority. Pointer to be passed to the task when it is created. If this task will use float register or not. Pointer to the task handler. NOTE: The disadvantage with this method is that task function can only create one task instance. The project created using the Project Generator tool creates one  task (task_example) implementing OSA. For more information about functions, macros and drivers please consult the Kinetis SDK v.1.3 API Reference Manual. This is located, after install Kinetis SDK, at the path: <install_KSDK_1.3.0_path>\doc GPIO Example 1. Add a new task named task_led. Add also a macro for OSA_TASK_DEFINE, the priority of the task and the prototype. To initialize and start RTOSes, OSA uses abstract functions OSA_Init() and OSA_Start(). Call OSA_Init() after calling hardware_init(). 2. Create the empty body of task_led 3. Add the following code initialization code for GPIO driver. PRINTF("\nLED TASK is running \n"); /* Enable clock for PORTs */ CLOCK_SYS_EnablePortClock(PORTA_IDX); CLOCK_SYS_EnablePortClock(PORTE_IDX); //Initializes GPIO driver GPIO_DRV_Init(switchPins, ledPins); 4. Now add logic to toggle a LED when a button is pressed. while(1) { //  check if SW2 is pressed if(GPIO_DRV_ReadPinInput(kGpioSW3) == 0) { GPIO_SW_DELAY; GPIO_DRV_TogglePinOutput(BOARD_GPIO_LED_BLUE); } } 5. It is needed a delay for the push buttons debounce. In this case it is GPIO_SW_DELAY which is defines as follows: /*Delay for Switch debounce*/ #define GPIO_SW_DELAY \ do \ { \ uint32_t i; \ for (i = 0; i < 0x2FFFFF; i++) \ { \ __asm("nop"); \ } \ } while (0) GPIO 6. Build and debug the project. Enjoy...
View full article
Interrupts can be handled by MQX (MQX managed ISR) or bypassing MQX (MQX kernel ISR). If you want that MQX handled all the ISR process, you can use MQX managed ISR.  By this ISR,  MQX catches all hardware interrupts in the range that the BSP defined and saves the context of the active task. For most interrupts, MQX calls the ISR that is stored in the interrupt vector table at the location identified by its interrupt vector number. The disadvantage with this is the interrupt latency is longer and depends completely on MQX. Hardware vector table for all MQX managed isrs points to MQX kernel function _int_kernel_isr()). This function invokes user isr by jumping into instruction pointed by "isr_ptr" , as the below graph shows. A task can install an MQX managed ISR interrupt using:  _int_install_isr(interrupt_vector_number,isr_ptr,isr_data_ptr) _bsp_int_init(Vector, Pri, Subpri, TRUE); Vector – number of non-core vector (for example, 37 for LLWU, defined in IRQInterruptIndex in the MCU header file) Pri – priority of the interrupt source. Allowed values: MQX_HARDWARE_INTERRUPT_LEVEL_MAX, MQX_HARDWARE_INTERRUPT_LEVEL_MAX + 1, …, 7, where 7 is the lowest application interrupt priority level. Subpri – zero on Kinetis. Enable – TRUE to enable the interrupt vector source in NVIC.  At this level of interrupt, you can call MQX services. The other option is MQX kernel ISR. Some real-time applications need special event handling to occur outside the scope of MQX. The need might arise that the latency in servicing an interrupt be less than the MQX interrupt latency. If this is the case, an application can use _int_install_kernel_isr() to bypass MQX and let the interrupt be serviced immediately. You will have the very same Performance as if you were running bare metal. A kernel ISR must save the registers that it needs and must service the hardware interrupt. When the kernel ISR is finished; it must restore the registers and perform a return-from-interrupt instruction. Even though the compiler handles this for you.   In this case, you can't use MQX services.  However, you can put data in global area, which a task can access. The disadvantage on this is shared data problem and you can impact the kernel if the restoring stack fails.   If you need faster MQX kernel ISR, you can install Kernel ISR with : _int_install_kernel_isr(vector_num, isr_ptr)  _bsp_int_init(Vector, Pri, Subpri, TRUE); Vector – number of non-core vector (for example, 79 for FTM1, defined in IRQInterruptIndex in the MCU header file) Pri – priority of the interrupt source. Allowed values: 0 for highest priority kernel isr, 1, ..,MQX_HARDWARE_INTERRUPT_LEVEL_MAX-1 for lowest priority kernel isr. Subpri – zero on Kinetis. Enable – TRUE to enable the interrupt vector source in NVIC. And very important, to install a HW interrupt handler, you need the HW interrupt table in RAM, so your user_config.h has to define MQX_ROM_VECTORS to 0.   Next is a demo to show how to use mqx kernel ISR, you can download it for more details.   static void GPIO_Init(void); static void IRQ_Init (void); void PortA_ISR(void); void PortE_ISR(void);                TASK_TEMPLATE_STRUCT MQX_template_list[] = { /*  Task number, Entry point, Stack, Pri, String, Auto? */    {MAIN_TASK,   Main_task,   1500,  9,   "main", MQX_AUTO_START_TASK},    {0,           0,           0,     0,   0,      0,                 } };   char SW=0;     /*TASK*----------------------------------------------------- * * Task Name    : Main_task * Comments     : *    This task prints " Hello World " * *END*-----------------------------------------------------*/   void Main_task(uint_32 initial_data) {    int counter=0;                printf("\n Hello World \n");       GPIO_Init();       IRQ_Init();       while(1){                   if(SW==1){                                  SW=0;                                  printf("IRQ A was generated\n");                   }                   if(SW==2){                                  SW=0;                                  printf("IRQ E was generated\n\r");                   }                   printf("Waiting for IRQ... %d\n\r", counter);                   counter++;                   _time_delay(1000);    }       _mqx_exit(0); }   static void GPIO_Init(void){                               SIM_SCGC5 = (0|SIM_SCGC5_PORTA_MASK|SIM_SCGC5_PORTE_MASK); /* Enable clock for PORTA */                               PORTA_PCR19 |= (0|PORT_PCR_MUX(1)|PORT_PCR_IRQC(0xA));//|PORT_PCR_PE_MASK;//|PORT_PCR_PS_MASK;                PORTE_PCR26 |= (0|PORT_PCR_MUX(1)|PORT_PCR_IRQC(0xA))|PORT_PCR_PE_MASK|PORT_PCR_PS_MASK; }   static void IRQ_Init (void){                uint32_t result;                                                  /* install the interrupt routine */                _int_install_kernel_isr (103, PortA_ISR);                _int_install_kernel_isr (107, PortE_ISR);                                              result = _cortex_int_init(107, 2, TRUE);                result = _cortex_int_init(103, 3, TRUE);                }   void PortA_ISR(void){                SW=1;                PORTA_ISFR=0xFFFFFFFF;  //Clear Port A ISR flags }   void PortE_ISR(void){                SW=2;                PORTE_ISFR=0xFFFFFFFF;  //Clear Port E ISR flags }
View full article
1.  Getting Started with MQX -  Duration: 13 Minutes (English & Chinese) Setting up the Environment Architecting your Application Task Template Adding Ethernet Connectivity 2. Introduction to the MQX Platform -  Duration: 20 Minutes (English & Chinese) Components of MQX MQX Features Task Scheduling Memory Management Synchronization RTCS Features USB Host /Device Directory Structure Task Aware Debugging 3. Writing Your First Freescale MQX™ Application - Duration: 1 hr Freescale MQX Software Solution Offering Introduction to Real Time Operating System (RTOS) Install and setup Freescale MQX MQX Application Demo LED Blinking Demo Client-Server 4. Implementing Ethernet Connectivity with the Freescale MQX™ RTOS  - Duration: 45 min
View full article
In this section, we will cover the light weight ADC driver, which enable you to read the ADC the output and raw form, and converted to scale form , or even as average level over a number of reads. The light weight ADC driver also allows you to configure a number of attributes of the converter.  So you can customize your application. Quick overview of ADC ADC is a system that converts an analog signal into digital signal. Simply put, Analog signals here means any variable voltage that is being monitored. It doesn’t matter what the signal is doing, it can remain the same level continuously, it can have slight wave to it, or it can be seemingly random. The analog to digital converter requires you to provide the reference voltage. That defines the maximum level that the input can be.  To determine the voltage level of the input the circular ADC generate a local voltage, and just this level until the same level as the input.   This can be done in different ways but the circuitry will adjust the level of the local signal until the comparator to detect the two inputs are the same or lease the same as the resolution of ADC, once the signal level is matched, the output generated.  Which can be read by your application.  To calculate the signal level the ADC defines the full range from the input into the three levels.  ADC typically have a resolution of 12 to 16 bits, so the 2 12   to 2 16 different levels. Whatever level input signals determined to be add , the reading from the ADC will be a digital representation of this value compare the  reference voltage. The digital output then represents what percentage of the allowed input range the input signal is currently add. Being at the minimum level will result an output of zero and being the max will resut in an output of 0xffff. And for inputs some in between the result is the output that represents the level measured. So if you are using a reference voltage of 3.3V for example, the reading will represent what flection the 3.3 v  the input voltage is .  If the input voltage is zero.  The reading will be 0 of course. And if the input is 3.3 v, the reading will be all FF, meaning 100 percent. So in between, if the input voltage is 1v, the result will be roughly 30.3%. And an input of 2v, will result the input roughly 60.6%, and 3v will be 90.9%. ADC Driver in MQX architecture Diagram The light weight ADC driver is considered a low level driver and is located alongside the LWGPIO driver. This is because we don’t trade the interfaces as a part of serial communication, they passing data back and forth in blocks or in bytes, also it doesn’t make sense to be accessing the drivers through the IO subsystem.   There is a section dedicated to ADC module in bsp files folder in project. (take twrk70f120m for example) The ADC priority is defined as 3, though ADC is typically not used with interrupts,  The default reference voltage and maximum voltage is 3300mV. The input setting of the potentiometer is connected to ADC1_SOURCE_AD20 in Twr-k70 board. The adc1 device is designated as the default ADC device ADC API    1 _lwadc_init() This function initializes the ADC module according to the parameters given in the platform specific initialization structure. Call to this function does not start any ADC conversion. This function is normally called in the BSP initialization code.   2  _lwadc_init_input () This function initializes the application allocated LWADC_STRUCT with all data needed later for quick control of particular input. This function sets the ADC input to continuous conversion mode if not already in this mode. 3 _lwadc_set_attribute / _lwadc_get_attribute :  both this functions receive a pointer to the LWADC_STRUCT_PRT ,  and the attributes you interested in. All the attributes are defined in an enum LWADC_ATTRIBUTE. 4 _lwadc_read_raw () Read the current value of the ADC input and return the result without applying any scaling. 5 _lwadc_read () This function reads the current value of the ADC input, applies scaling according to preset parameters. 6 _lwadc_read_average() This function reads num_sample samples from the specified input and returns the scaled average reading. 7  _lwadc_wait_next() This function waits for a new value to be available on the specified ADC input.
View full article