MQXソフトウェアソリューションナレッジベース

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

MQX Software Solutions Knowledge Base

ディスカッション

ソート順:
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
記事全体を表示
NXP provides a software driver library for their Kinetis ARM Cortex-M0 and M4 devices, the ‘Kinetis SDK’, available from http://www.nxp.com/ksdk.   The below link provides information about how download a KSDK package, how to install KSKD v2.0 project wizard in Kinetis Design Studio (KDS), and how to create a KSDK v2.0 project. Using Kinetis Design Studio v3.x with Kinetis SDK v2.0 NOTE: Before you continue with this document, it is important to download and install KSDK v2.0. The purpose of this document is to provide information that enables developers to start their first application using FreeRTOS and KSDK v2.0. Creating a new FreeRTOS with KSDK V2.0 application. The following steps show how to create a new FreeRTOS project in KDS using KSDK v2.0. 1. Open Kinetis Design Studio. 2. Go to 'File' menu and click on File->New->Kinetis SDK 2.x Project 3. Select a project name and the Kinetis SDK folder then click 'Next' 4. Select the processor or board to be used, in addition it is important to include all SDK drivers and add FreeRTOS to the project and click 'Finish' 5. In the project created you can see the following folder structure: 6. The main.c file is a template for main module created by new Kinetis SDK 2.0 Project Wizard, this contains a task responsible of printing "Hello world." message. 7. If you want to build and debug this example uncomment the next lines: #include "fsl_debug_console.h" and PRINTF("Hello world.\r\n"); 8. Build and debug. Developing the first FreeRTOS with KSDK V2.0 application. This section describes the creation of a simple application that blinks LEDs on the TWR-K64F120M board. After a new project is created, in the main function the following routines are called in order to initialize the board hardware: BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); By default only the UART0 is initialized in order to use it as debug console. Also in main it is created a task (hello_task) using xTaskCreate () function. xTaskCreate () creates a new task and adds it to the list of tasks that are ready to run; it contains the following parameters: pvTaskCode. Pointer to the task entry function. Tasks must be implemented to never return. pcName. A descriptive name for the task. This is mainly used to ease debugging. Max length defined by configMAX_TASK_NAME_LEN. usStackDepth. The size of the task stack specified as the number of variables the stack can hold - not the number of bytes. For example, if the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes will be allocated for stack storage. The stack depth multiplied by the stack width must not exceed the maximum value that can be contained in a variable of type size_t. pvParameters. Pointer that will be used as the parameter for the task being created. uxPriority. The priority at which the task should run. pvCreatedTask. Used to pass back a handle by which the created task can be referenced. Writing the application. The TWR-K64F120M contains 4 LED's connected to GPIO signals (optionally isolated using jumpers): — Green LED (D5) to PTE6 — Yellow LED (D6) to PTE7 — Orange LED (D7) to PTE8 — Blue LED (D9) to PTE9 For this example it is used the TWR-K64F120M board, however if you are using the FRDM-K64F the RGB LED is connected through GPIO signals: — RED to PTB22 — BLUE to PTB21 — GREEN to PTE26 To initialize the GPIO, enable the port clock, define a pin configuration, either input or output, in the pin_mux.c file, as is described in the below steps: Open the pin_mux.c file.    2. Enable the port clock.      CLOCK_EnableClock(kCLOCK_PortE);    3. Configure these pins as GPIO signals.       PORT_SetPinMux(PORTE, 6u, kPORT_MuxAsGpio);     PORT_SetPinMux(PORTE, 7u, kPORT_MuxAsGpio);     PORT_SetPinMux(PORTE, 8u, kPORT_MuxAsGpio);     PORT_SetPinMux(PORTE, 9u, kPORT_MuxAsGpio); Then, in main function create 5 tasks, one to initialize the GPIO driver and the other to blink the LEDs. You can find the complete code at the end of this document.   /* Create RTOS task */ xTaskCreate(init_task, "Init_task", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_blue, "Task_blue", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_orange, "Task_orange", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_yellow, "Task_yellow", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_green, "Task_green", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); Write the code of each task. 1. init_task function. In this function are initialized the GPIO pins as output using the gpio_pin_config_t structure then it is called the GPIO_PinInit() function for each GPIO pins.      The GPIO_PinInit() parameters are: base. GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) pin. GPIO port pin number. config. GPIO pin configuration pointer.      Finally call vTaskSuspend(), this function suspend the task. When a task is suspended, it will never get back to execution unless it is explicitly set in Ready state by another task.      The code for init_task function is:      gpio_pin_config_t ledB_config = {                       kGPIO_DigitalOutput, 0,                   };          gpio_pin_config_t ledO_config = {                          kGPIO_DigitalOutput, 0,                   };          gpio_pin_config_t ledG_config = {                      kGPIO_DigitalOutput, 0,                   };          gpio_pin_config_t ledY_config = {                       kGPIO_DigitalOutput, 0,                   };       /* Init output LED GPIO. */     GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PIN, &ledB_config);     GPIO_PinInit(BOARD_LED_ORANGE_GPIO, BOARD_LED_ORANGE_GPIO_PIN, &ledO_config);     GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, &ledG_config);     GPIO_PinInit(BOARD_LED_YELLOW_GPIO, BOARD_LED_YELLOW_GPIO_PIN, &ledY_config);     vTaskSuspend(NULL); 2. task_blue, task_orange, task_yellow, task green functions. It is necessary to write the code of each task. Each task uses LED_XXX_TOGGLE() and vTaskDelay (), to toggle a LED, this should be in a infinite loop.      Below is the code for the task_blue function:      while (1)        {                         /* Toggle LED BLUE */               LED_BLUE_TOGGLE();               vTaskDelay( 500 );        } Finally build and debug the project.  Enjoy! Complete Code main.c #include <string.h> #include "board.h" #include "pin_mux.h" #include "clock_config.h" #include "fsl_debug_console.h" /* FreeRTOS kernel includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" /* Task priorities. */ #define task_PRIORITY (configMAX_PRIORITIES - 1) static void init_task(void *pvParameters) {        /* Init output LED GPIO. */          gpio_pin_config_t ledB_config = {                       kGPIO_DigitalOutput, 0,                   };          gpio_pin_config_t ledO_config = {                          kGPIO_DigitalOutput, 0,                   };          gpio_pin_config_t ledG_config = {                      kGPIO_DigitalOutput, 0,                   };          gpio_pin_config_t ledY_config = {                       kGPIO_DigitalOutput, 0,                   };        /* Init output LED GPIO. */                   GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PIN, &ledB_config);                   GPIO_PinInit(BOARD_LED_ORANGE_GPIO, BOARD_LED_ORANGE_GPIO_PIN, &ledO_config);                   GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, &ledG_config);                   GPIO_PinInit(BOARD_LED_YELLOW_GPIO, BOARD_LED_YELLOW_GPIO_PIN, &ledY_config);                   vTaskSuspend(NULL); } static void task_blue(void *pvParameters) {         while (1)        {        /* Toggle LED BLUE */               LED_BLUE_TOGGLE();               vTaskDelay( 500 );        } } static void task_orange(void *pvParameters) {         while (1)        {        /* Toggle LED ORANGE */               LED_ORANGE_TOGGLE();               vTaskDelay( 500 );        } } static void task_yellow(void *pvParameters) {         while (1)        {        /* Toggle LED YELLOW */               LED_YELLOW_TOGGLE();               vTaskDelay( 500 );        } } static void task_green(void *pvParameters) {         while (1)        {        /* Toggle LED GREEN */               LED_GREEN_TOGGLE();               vTaskDelay( 500 );        } } int main(void) { /* Init board hardware. */ BOARD_InitPins();   // This function initializes the pins used in this example BOARD_BootClockRUN(); BOARD_InitDebugConsole();   /* Create RTOS task */ xTaskCreate(init_task, "Init_task", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_blue, "Task_blue", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_orange, "Task_orange", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_yellow, "Task_yellow", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); xTaskCreate(task_green, "Task_green", configMINIMAL_STACK_SIZE, NULL, task_PRIORITY, NULL); vTaskStartScheduler(); for(;;) { /* Infinite loop to avoid leaving the main function */ __asm("NOP"); /* something to use as a breakpoint stop while looping */ } } Complete Code  pin_mux.c #include "fsl_device_registers.h" #include "fsl_port.h" #include "pin_mux.h" /******************************************************************************* * Code ******************************************************************************/ /*! * @brief Initialize all pins used in this example * * @param disablePortClockAfterInit disable port clock after pin * initialization or not. */ void BOARD_InitPins(void) { /* Ungate the port clock */ CLOCK_EnableClock(kCLOCK_PortC); CLOCK_EnableClock(kCLOCK_PortE); /* Affects PORTC_PCR3 register */ PORT_SetPinMux(PORTC, 3u, kPORT_MuxAlt3); /* Affects PORTC_PCR4 register */ PORT_SetPinMux(PORTC, 4u, kPORT_MuxAlt3); PORT_SetPinMux(PORTE, 6u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 7u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 8u, kPORT_MuxAsGpio); PORT_SetPinMux(PORTE, 9u, kPORT_MuxAsGpio); }
記事全体を表示
Several reasons may lead to a hard fault, for example, calling a function pointer with an invalid address, stack overflow, trying to read or write to an on-chip peripheral that is powered down or not being clocked, accessing non-mapped memory etc. It is often difficult to find out what caused the hard fault, fortunately the cortex-M stores some information in ARM fault status register, the hardware automatically pushes several CPU register on the stack before entering the Hard Fault Handler. This document below shows a way to debug a Hard Fault in MQX. For Hard Fault, we can hook our exception handler into the vector table. we will find vector table in the vector.c source file in the BSP library. By default, isr is configured to DEFAULT_VECTOR, which is the _int_kernel_isr() function of the MQX dispatcher. We cam put our own function, like void my_kernel_isr (void), to vector table offset 0x0c.  Inside my_kernel_isr(), we can get the interrupt stack frame, CPU register content at the time of exception and use directly the my_kernel_isr - just remove the static keyword, as we need the my_kernel_isr to be global, as it is referenced from vectors.c and it will be implemented in the application, main.c, for example.  Now, put breakpoint to this my_kernel_isr and see the registers read by prvGetRegistersFromStack(). Typically at most interest would by "lr" and "pc". For example, "lr" would have an address of an instruction that a return from a function call would return to. By looking into the .map file or using the debugger, we will know, which function has been executed by the CPU when exception occurred. Hook our own kernel isr into the vector table In file vectors.c,   the default ISR for Hard_Fault is DEFAULT_VECTOR Now we modified it to my_kernel_isr, so when hard fault happens, my_kernel_isr will be executed. Read the register value The following code is for CodeWarrior/Kinetis Design Studio to a C module, for IAR/KEIL, we need to write the same function as an assembler source file. void my_kernel_isr( void ) __attribute__( ( naked ) ); /* The fault handler implementation calls a function called prvGetRegistersFromStack(). */ static void my_kernel_isr(void) {     __asm volatile     (         " tst lr, #4                                                \n"         " ite eq                                                    \n"         " mrseq r0, msp                                             \n"         " mrsne r0, psp                                             \n"         " ldr r1, [r0, #24]                                         \n"         " ldr r2, handler2_address_const                            \n"         " bx r2                                                     \n"         " handler2_address_const: .word prvGetRegistersFromStack    \n"     ); } void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress ) { /* These are volatile to try and prevent the compiler/linker optimising them away as the variables never actually get used.  If the debugger won't show the values of the variables, make them global my moving their declaration outside of this function. */ volatile uint32_t r0; volatile uint32_t r1; volatile uint32_t r2; volatile uint32_t r3; volatile uint32_t r12; volatile uint32_t lr; /* Link register. */ volatile uint32_t pc; /* Program counter. */ volatile uint32_t psr;/* Program status register. */     r0 = pulFaultStackAddress[ 0 ];     r1 = pulFaultStackAddress[ 1 ];     r2 = pulFaultStackAddress[ 2 ];     r3 = pulFaultStackAddress[ 3 ];     r12 = pulFaultStackAddress[ 4 ];     lr = pulFaultStackAddress[ 5 ];     pc = pulFaultStackAddress[ 6 ];     psr = pulFaultStackAddress[ 7 ];     /* When the following line is hit, the variables contain the register values. */     for( ;; ); } Notes about Cortex M4 registers: MQX sets active stack pointer to PSP in boot.s The core automatically switches the active stack pointer to MSP in handler mode and switches back to PSP with exception return Compare with .map file we need to find out which function executes while hard fault occurs. To determine application , Use trace debugging tool (DSTREAM, ULINK-PRO, J-Trace, Lauterbach uTrace for Cortex-M …) or enable Kernel log and explore its content with MQX TAD #define MQX_KERNEL_LOGGING 1   _klog_create(2048,LOG_OVERWRITE);   /* Enable kernel log */   _klog_control(KLOG_ENABLED | KLOG_CONTEXT_ENABLED |                 KLOG_INTERRUPTS_ENABLED| KLOG_FUNCTIONS_ENABLED | KLOG_INTERRUPT_FUNCTIONS |                 KLOG_MEMORY_FUNCTIONS | KLOG_PARTITION_FUNCTIONS, TRUE); By this we only find, which function causes the problem. Next, we will have to think why this occurs, and give more application specific debugging effort to find the root cause.
記事全体を表示
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
記事全体を表示
  I2C is a common way to interface a processor with a peripheral such as EEPROM, accelerometer, or communication device, and can even be used to communicating with another processor. Quick Review of I2C I2c: inter-integrated circuit, meaning that is a communication channel between integrated circuit devices, typically from a microprocessor to a peripheral device, such as a memory chip, some type of sensor, a data converter or maybe a display.   By design, i2c isn’t intended for high throughput connections, so you won’t see it used for something like chip ram, rather it is typically used when relatively small amount of data is being sent or received. There are only two conductors through the i2c bus, the first is a serial clock line which is usually written as SCL,   as the name implies, SCL is a clock signal sent on this line. The second is a serial of data line, or SDA, and the data sender on this line will be synchronized with a clock signal making it easier for the receiver to decoding incoming data, and i2c connections is one to one link, with one device being as a master and the other being a slave.  But multiple devices can be connected to the same bus with different one to one pairs communicating on the channel. Only one pair can be communicating at a time of course, and having more than one device capable of being a master will acquire additional synchronization to avoid conflicts. With i2c, the communication is poll response, meaning the master will poll slave with either data that wants to send to slave or send a command request the slave sends specific information back, only the master can initiate communication and part of the job is to provide the clock signal, which should does not only when is transmitting,    but also when the slave is transmitting back. Sending Data with I2C The clock and data lines have pull up resistors, so when the bus is idle and both of the wires will be in high state. To begin a transmission,  a master  pulls a data line low which is refer to as a start condition , the master then drives the clock signal while  sent 7 address bits on the data line.  The address bits are followed immediately by either a 0 to indicate the master wants to send the data or a 1 meaning the master would like to read the data back from the slave, the seven address bits must closely bound to a slave device that is on the bus of course, and the device with margin address will set as an acknowledge or an ACK bit on the data line to   indicate that has receive the request which is done by holding the data line low. At this stage, one of two things going to happen. If the master wants to send data or   a command to address the slave , he will continue on with first byte to transmit ,  data bits will sent out   and again the address slave or add the   ACK bit at the end , this continues until the master is done sending it’s commanding data. And there is no fixed limit to size of the message. If the master is just sending data and is not expecting receive response back from the slave, it will indicate that is done by signaling a STOP condition, after the last data byte is sent. However, instead of sending data,  the master maybe expecting the salve to immediately to reply back and signals this request, with a read bit have the address, In this case,  slave acknowledge address and then sent out a byte of data synchronize to  the master’s clock , once the byte is complete, the master will indicate acknowledgement of  the data, and this continues until the master receives the amount of data  it was expecting. It signals to the device the expected amount of data has been received by not acknowledging a last byte. And instead leaves the data line high, which is called the NAK for not acknowledge. Finally the master terminates the communication by signaling a stop condition and stops generation of the clock signal. And the last thing to cover is the case when the master like to send either data or a command and immediately receive data back from the slave. So a combination of previous two scenarios,   the first part of the transaction is identical to just sending data with master sending out the number of bytes has to transmit, and the slave acknowledge each byte. However, the stop condition is not asserted at the end of transmission, and the master will send a start bit , which is called a repeatedly start bit. The seven address bits will send again followed by a read setting which the slave acknowledge. The slave then send the data with the master’s address on each byte until the last byte which isn’t acknowledged, and the session is terminated with a stop bit. Note: This document is the 11th Installment of the "Essentials of MQX RTOS Application Development" training course. Please watch the vedio for more details MQX RTOS Part 11: IC2 Driver|NXP
記事全体を表示
Accelerometer and magnetometer FXOS8700CQ example code for MQX4.1.1 This example code was written for FRDM-K64F board and it is based on Tom’s bare-metal code (Thank you). Content of attached zip file could be unpacked directly to examples directory (c:\Freescale\Freescale_MQX_4_1\mqx\examples\..). It contains generated projects for CW10GCC, IAR, KDS, make and KEIL toll chains. Note: unfortunately this example project cannot be used as source for New Project Wizard in CW10. Example code uses polled I2C MQX driver for communication with FXOS8700CQ chip and it contains two options for acquisition sensors data. We can use polled (0) or interrupt (1) mode according SENSOR_USE_INTERRUPT macro definition. In polled mode we periodically read sensor status until new data are available. In interrupt mode sensor drives interrupt pin when new data are available. Example code contains calibration functions for increasing accuracy. Magnetometer calibration function collects data during 30s interval where we should rotate with board around z-axis in 360° range (leave board on table and rotate from north to south and back to north). It acquires approximately 3 samples per second. For change this ODR rate, we have to modify CTRL_REG1 value. Note: Interrupt mode works correctly up to 200Hz ODR. Higher ODRs was not tested due to capacitance on interrupt pin (C56). Polled mode was tested up to 800Hz ODR (accelerometer only). Example code displays received data on debug console and drives RGB LEDs according measured g’s. If you are interested in more complex algorithms please refer to our Freescale Sensor Fusion Library for Kinetis MCUs. I hope it helps you. RadekS
記事全体を表示
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...
記事全体を表示
This document shows how to use a mutex and semaphores in order to synchronize two tasks in a FreeRTOS and SDK 2.0 project. For this example it is used SDK 2.0, TWR-K64F120M, and FreeRTOS. If you want to know how to create a new SDK 2.0 with FreeRTOS project please check the below link: https://community.freescale.com/docs/DOC-330183 MUTEX EXAMPLE: Introduction A mutex provides mutual exclusion among tasks, when they access a shared resource. When used for mutual exclusion the mutex acts like a token that is used to guard a resource. When a task wishes to access the resource it must first obtain ('take') the token. When it has finished with the resource it must 'give' the token back - allowing other tasks the opportunity to access the same resource. Mutexes cannot be used in interrupt service routines. Mutexes use the same semaphore access API functions. Writing a Mutex example code The mutex example code is used to demonstrate how to use a mutex to synchronize two tasks. It creates a mutex and two tasks. Both tasks use PRINTF to print out messages. Each task will lock the mutex before printing and unlock it after printing to ensure that the outputs from tasks are not mixed together. According with this proposal it is necessary to follow the below steps. In main function, create a mutex using the xSemaphoreCreateMutex() API. This API creates a mutex, and returns a handle by which the created mutex can be referenced. Mutexes cannot be used in interrupt service routines. xMutex = xSemaphoreCreateMutex(); Create two tasks with the same priority, these tasks will use PRINTF to print out messages.        xTaskCreate(write_task_1,"write_task_1",configMINIMAL_STACK_SIZE,NULL,                      task_PRIORITY, NULL);        xTaskCreate(write_task_2,"write_task_2",configMINIMAL_STACK_SIZE,NULL,                      task_PRIORITY, NULL); The two print tasks both use the PRINTF. If they used it in the same time, there would be conflicts, so a mutex is used to synchronize the two tasks. Each print task will try to lock the mutex before printing the message, using the macro xSemaphoreTake (SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait); it will wait for the mutex as long as needed. Once the mutex is locked it prints the message and then unlocks the mutex  with the macro xSemaphoreGive (SemaphoreHandle_t xSemaphore) so that the other task can lock it. This process is repeated indefinitely. static void write_task_1(void *pvParameters) {     while (1)     { xSemaphoreTake(xMutex, portMAX_DELAY);         PRINTF("Hello, this is the |");         taskYIELD();         PRINTF("first task \r\n"); xSemaphoreGive(xMutex);         taskYIELD();     } } static void write_task_2(void *pvParameters) { while (1) { xSemaphoreTake(xMutex, portMAX_DELAY); PRINTF("And now this is the |"); taskYIELD(); PRINTF(" second task\r\n"); xSemaphoreGive(xMutex); taskYIELD(); } } At this point you can build and debug the example. Complete Code /* Kernel includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" #include "semphr.h" /* Freescale includes. */ #include "fsl_device_registers.h" #include "fsl_debug_console.h" #include "board.h" #include "pin_mux.h" #include "clock_config.h" /******************************************************************************* * Definitions ******************************************************************************/ SemaphoreHandle_t xMutex; /******************************************************************************* * Prototypes ******************************************************************************/ static void write_task_1(void *pvParameters); static void write_task_2(void *pvParameters); /******************************************************************************* * Code ******************************************************************************/ /*! * @brief Main function */ int main(void) { xMutex = xSemaphoreCreateMutex(); BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); xTaskCreate(write_task_1, "WRITE_TASK_1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); xTaskCreate(write_task_2, "WRITE_TASK_2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); /* Start scheduling. */ vTaskStartScheduler(); for (;;) ; } /*! * @brief Write Task 1 function */ static void write_task_1(void *pvParameters) { while (1) { xSemaphoreTake(xMutex, portMAX_DELAY); PRINTF("Hello, this is the "); taskYIELD(); PRINTF("first task \r\n"); xSemaphoreGive(xMutex); taskYIELD(); } } /*! * @brief Write Task 2 function */ static void write_task_2(void *pvParameters) { while (1) { xSemaphoreTake(xMutex, portMAX_DELAY); PRINTF("And now this is the "); taskYIELD(); PRINTF(" second task\r\n"); xSemaphoreGive(xMutex); taskYIELD(); } } SEMAPHORE EXAMPLE: Introduction Binary semaphores and mutexes are very similar but have some subtle differences: Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes binary semaphores the better choice for implementing synchronisation (between tasks or between tasks and an interrupt), and mutexes the better choice for implementing simple mutual exclusion. A semaphore can be used in order to control the access to a particular resource that consists of a finite number of instances. Writing a Semaphore example code After install SDK 2.0 you can find a semaphore example at the path: <SDK_install_path>\SDK_2.0_xxx\boards\<your_name>\rtos_examples\freertos_sem The example uses four tasks. One producer_task and three consumer_tasks. The producer_task starts by creating of two semaphores (xSemaphore_producer and xSemaphore_consumer). These semaphores control access to virtual item. The synchronization is based on bilateral rendezvous pattern. Both of consumer and producer must be prepared to enable transaction. Here’s the API (copied from the FreeRTOS website): MODULES xSemaphoreCreateBinary SemaphoreHandle_t xSemaphoreCreateBinary( void ); Creates a binary semaphore, and returns a handle by which the semaphore can be referenced. xSemaphoreCreateBinaryStatic SemaphoreHandle_t xSemaphoreCreateBinaryStatic(                           StaticSemaphore_t *pxSemaphoreBuffer ); Creates a binary semaphore, and returns a handle by which the semaphore can be referenced. xSemaphoreCreateCounting SemaphoreHandle_t xSemaphoreCreateCounting(                                             UBaseType_t uxMaxCount, UBaseType_t uxInitialCount); Creates a counting semaphore and returns a handle by which the newly created semaphore can be referenced. xSemaphoreCreateCountingStatic SemaphoreHandle_t xSemaphoreCreateCountingStatic(                                  UBaseType_t uxMaxCount,                                  UBaseType_t uxInitialCount StaticSemaphore_t pxSempahoreBuffer ); Creates a counting semaphore and returns a handle by which the newly created semaphore can be referenced. xSemaphoreCreateMutex SemaphoreHandle_t xSemaphoreCreateMutex( void ) Creates a mutex, and returns a handle by which the created mutex can be referenced. Mutexes cannot be used in interrupt service routines. xSemaphoreCreateMutexStatic SemaphoreHandle_t xSemaphoreCreateMutexStatic(                             StaticSemaphore_t *pxMutexBuffer ); Creates a mutex, and returns a handle by which the created mutex can be referenced. Mutexes cannot be used in interrupt service routines. xSemaphoreCreateRecursiveMutex SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void ) Creates a recursive mutex, and returns a handle by which the mutex can be referenced. Recursive mutexes cannot be used in interrupt service routines. configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for xSemaphoreCreateRecursiveMutex() to be available. xSemaphoreCreateRecursiveMutexStatic SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer ) Creates a recursive mutex, and returns a handle by which the mutex can be referenced. Recursive mutexes cannot be used in interrupt service routines. configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for xSemaphoreCreateRecursiveMutexStatic() to be available. vSemaphoreDelete void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); Deletes a semaphore, including mutex type semaphores and recursive semaphores. Do not delete a semaphore that has tasks blocked on it (tasks that are in the Blocked state waiting for the semaphore to become available). xSemaphoreGetMutexHolder TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex ); Return the handle of the task that holds the mutex specified by the function parameter, if any. xSemaphoreGetMutexHolder() can be used reliably to determine if the calling task is the mutex holder, but cannot be used reliably if the mutex is held by any task other than the calling task. xSemaphoreTake xSemaphoreTake( SemaphoreHandle_t xSemaphore,                  TickType_t xTicksToWait ); Macro to obtain a semaphore. The semaphore must have previously been created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or xSemaphoreCreateCounting(). xSemaphoreTakeFromISR xSemaphoreTakeFromISR(         SemaphoreHandle_t xSemaphore,         signed BaseType_t *pxHigherPriorityTaskWoken ) A version of xSemaphoreTake() that can be called from an ISR. Unlike xSemaphoreTake(), xSemaphoreTakeFromISR() does not permit a block time to be specified. xSemaphoreTakeRecursive xSemaphoreTakeRecursive( SemaphoreHandle_t xMutex,                          TickType_t xTicksToWait ); Macro to recursively obtain, or 'take', a mutex type semaphore. The mutex must have previously been created using a call to xSemaphoreCreateRecursiveMutex(); configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this macro to be available. xSemaphoreGive xSemaphoreGive( SemaphoreHandle_t xSemaphore ); Macro to release a semaphore. The semaphore must have previously been created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or xSemaphoreCreateCounting(), and obtained using sSemaphoreTake(). xSemaphoreGiveRecursive xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex ) Macro to recursively release, or 'give', a mutex type semaphore. The mutex must have previously been created using a call to xSemaphoreCreateRecursiveMutex(); configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this macro to be available. xSemaphoreGiveFromISR xSemaphoreGiveFromISR(         SemaphoreHandle_t xSemaphore,         signed BaseType_t *pxHigherPriorityTaskWoken) Macro to release a semaphore. The semaphore must have previously been created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) must not be used with this macro. uxSemaphoreGetCount UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore ); Returns the count of a semaphore. Enjoy!!!
記事全体を表示
Quick Overview of FreeRTOS vs MQX RTOS MQX  real-time operating system is designed for uniprocessor, multiprocessor, and distributed-processor embedded real-time system. Freescale semiconductor adopted this software platform for its microprocessors.  This includes Kinetis, Coldfire, PowerPC, ARC,ARM, StrongARM, xscale CPUs. The main features of MQX RTOS are scalable size, component-oriented architecture and easy of use. FreeRTOS is a popular real-time operating system kernel for embedded devices, that has been ported to 35 architectures. It is distributed under the GPL with an optional exception. FreeRTOS provides a very small footprint, low overhead and very fast execution. The kernel itself consist of only three or four C files. 4-8k bytes of flash minimum. Similar features : [to be done] Tasks, events, semaphores,mutex, message queues, power saving when idle                                                                  Freertos unique features : 1 Task nofifications: Each RTOS task has a 32-bit notification value which is initialized to zero when the RTOS task is created. An RTOS task notification is an event sent directly to a task that can unblock the receiving task, and optionally update the receiving task’s notification value. 2 Recursive mutex:  A mutex used recursively can be 'taken' repeatedly by the owner. The mutex doesn't become available again until the owner has called xSemaphoreGiveRecursive() for each successful xSemaphoreTakeRecursive() request. For example, if a task successfully 'takes' the same mutex 5 times then the mutex will not be available to any other task until it has also 'given' the mutex back exactly five times. 3 Stack overflow hook/notification: Each task maintains its own stack. The memory used by the task stack is allocated automatically when the task is created, and dimensioned by a parameter passed to the xTaskCreate() API function. Stack overflow is a very common cause of application instability. FreeRTOS therefore provides two optional mechanisms that can be used to assist in the detection and correction of just such an occurrence 4 Deferred interrupt handling:  Used from application interrupt service routines to defer the execution of a function to the RTOS daemon task. A mechanism is provided that allows the interrupt to return directly to the task that will subsequently execute the pended function. This allows the callback function to execute contiguously in time with the interrupt - just as if the callback had executed in the interrupt itself 5 Blocking on multiple objects:  Queue sets are a FreeRTOS feature that enables an RTOS task to block (pend) when receiving from multiple queues and/or semaphores at the same time. Queues and semaphores are grouped into sets, then, instead of blocking on an individual queue or semaphore, a task instead blocks on the set. MQX unique features: 1 Destruction of resource based on ownership:  [to be done] 2 Name services:  tasks can associate a 32-bit number with a string or symbolic name.MQX RTOS stores the association in a names database that all tasks on the processor can use. The database avoids global variables. 3 Inter-Processor Communication:  An application can run concurrently on multiple processors with one executable image of MQX RTOS on each processor. The images communicate and cooperate using messages that are transferred by memory or over communication links using inter-processor communication. The application tasks in each image need not be the same and, indeed, are usually different. 4 Watchdogs: Watchdogs are option components that let the user detect task starvation and deadlock conditions at the task level. 5 Task Queue Scheduling:  you can use task queues to explicitly schedule tasks or to create more complex synchronization mechanisms. Because task queues provide minimal functionality, they are fast. An application can specify a FIFO or round robin scheduling policy when it creates the task queue
記事全体を表示
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
記事全体を表示
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
記事全体を表示
Hello All, Next document lists the steps needed to install a basic NIO driver in MQX for KSDK 1.3. In this document, a basic SPI driver for FRDM-K64F was created in order to serve as guidance for any user's driver. Source and header file for this NIO SPI are attached as well as hello.c source files that was taken from hello_world example in order to test this driver. I hope you can find it helpful! Best Regards, Isaac Avila
記事全体を表示
If you are interested in a PPP connection between your PC and your board using Win 7 OS you may find the attached document useful. This project (ATTACHED) starts PPP service and waits for a Windows connection. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- If you are interested in getting started with MQX for KSDK please see the following document: How To: Create a New MQX RTOS for KSDK Project in KDS If you are interested in using RTCS with Processor Expert please see the following document: How to add RTCS to a Processor Expert Project Using KDS and KSDK Regards, Carlos
記事全体を表示
Q: I installed the MQX software release, but when I run a project, CodeWarrior can't find file x...  A: Symptom A project will build correctly, but when you run it, CodeWarrior asks you to locate files that it can't find. Solution: This problem is caused if you are running from a directory that is not the default directory that the installer placed the files. You just need to re-build the libraries. To build all MQX libraries at once, the special mass-build project may be used. The project is located together with the user_config.h file in directory: <install_dir>/config/<board>/build_libs.mcp. See the Release Notes for more details on building the libraries. Q: What software tools do I need for the MQX 3.0.0 demos and lab tutorials? A: The first release of Freescale MQX (3.0.0) requires CodeWarrior for ColdFire v7.1 Professional Edition (30-day evaluation available) to unlock the full potential of the demos and labs. Is version 7.1 necessary?  Yes, 7.1 contains the necessary support for M5225EVB and M52259DEMOKIT. What about CodeWarrior Special Edition?  Due to the code size limitation (<128k) of Special Edition, several lab demos will not compile/program.  These include MQX labs 3 and 4.  Also, Task Aware Debugging is not available in Special edition, therefore lab 5 is not possible.  Additionally, the targets which utilize the MRAM on the M52259EVB will not work. What about CodeWarrior Basic and Standard Edition? Task Aware Debugging is not available in Basic or Standard edition,therefore lab 5 is not possible.  Also, with Basic Edition the targets whichutilize the MRAM on the M52259EVB may not work. Q: I'm having trouble establishing an Ethernet connection between my PC and the board.  What do I do? A: 1) Hit the Reset button on the board after you plug in the cable.  2) Wait a minute or two for your computer to connect. Connect the board directly to your computer with an ethernet crossover cable.  You must wait a minute or two for your computer to try to aquire a network address.  Since you're no longer connected to your network the computer will eventually revert to an Auto IP address on the same subnet as board (169.254.x.x). 3) Disable your wireless router if you have one. 4) Disable proxy server settings in your web browser. Notes: When connected your computer might report limited or no connectivity, but it should still work. Ping is disabled in release 3.0.0, so pinging the board from the computer will not work. If all else fails, configure your IP address manually as instructed by the quick start guide. Q: Can I modify the webpages used in the webserver lab? A: Yes, there is a tool called MKTFS which can be used to convert web pages and images into a C array's, which are used by the MQX webserver.  Edit the webpages in the folder \demo\web_hvac\web_pages.  Then click on \demo\web_hvac\mktfs.bat.  The script will update the file tfs_data.c in the \demo\web_hvac folder.  When you recompile the hvac_web project and program it the new webpages will be loaded into memory.          Q: Can I use my own USB Flash drive in the labs? A: Yes, just copy over the files from the flash drive that is provided with the M52259EVB or M52259DEMOKIT. Q: My USB Flash drive doesn’t work, what should I do? A: Not all USB flash drive conform to the same specification and there are small differences between them that could cause some not to work.  It will say "Unable to open USB disk" at the terminal if the flash drive is not compatible. We are working to expand compatibility to as many usb flash drive manufactures and models as possible.  If you encounter one that does not work please perform the following tasks. Open up the project in <mqx install directory>/usb/host/examples/mass/msc_commands/codewarrior/ Load and run the project with the USB stick unattached. Then with the Terminal open and connected, plug in the non-functioning USB stick. A test will run automatically upon insertion of the USB stick.  The test will output useful information to the terminal that will help us. Please provide us the output that this test generates, along with the exact make and model of the USB flash drive.  We will create a thread on the forums that you can post this to. More info: Tested USB Stick Q: What are tasks and how are they created? A: Tasks share the same code space if they execute the same root function. A task always starts executing at the entry point of the root function even if the function is its creator’s root function. This is not the same behavior as fork() in UNIX. Q:Do I always need at least one autostart task? A: Yes. In an application, at least one autostart application task is required in order to start the application. In a multiprocessor application (the application can create tasks remotely), each image need not have an autostart application task; however, each image must include IPC Task as an autostart task in the task template list. If no application task is created on a processor, Idle Task runs. Q:How much stack space should I give to various tasks in my application? A: This is a really hard question to answer as the amount of stack space is extremely application specific. Different tasks will need varying amounts of stack space depending on the job they are trying to perform. We usually recommend starting all (or most) of tasks with plenty of stack memory (double or triple what you think they would need) and then later optimizing the system with TAD (Task Aware Debugging module). Q: How do I dynamically alter the task stack size? A: In a situation where a task runs a while and then blocks. In it's blocked state, it holds a couple of event connections which are used by interrupts, but otherwise needs no stack space. One would like to reduce the stack space being used by the task in its blocked state. How do you do this? If the task is never going to run again, the user could _mem_free or better yet _mem_free_part on the stack. Using _mem_free_part will not cause some of our tools to complain. In the task whose stack to be freed, the very first thing it does is to save the value of kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST; /* Global var */ pointer stack_ptr; { /* In task */ KERNEL_DATA_STRUCT_PTR kernel_data = _mqx_get_kernel_data(); /* Do this very first thing */ stack_ptr = kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST; /* Rest of code for task */ } { /* some other task*/ _mem_free(stack_ptr); } Q:How does MQX™ measure a timeslice? Is the timeslice absolute or relative? That is, if a task has a 10-ms timeslice and starts at time=0 ms, does it give up the processor at time=10 ms, or does it give up the processor after 10 ms of execution? A: With a 10-ms timeslice, MQX counts the number of periodic timer interrupts that have occurred while the task is active. If the equivalent of 10 or more milliseconds have expired, MQX effectively runs _sched_yield() for the task. As a result, a task does not get 10 ms of linear time since higher-priority tasks will preempt it. Also, if the task calls a scheduling service (for example _task_block() or _sched_yield()), MQX sets the task’s timeslice counter back to zero. As with timeouts, the time that MQX allocates is plus or minus BSP_ALARM_RESOLUTION. Q: How do I increase TCP performance? A: Increase the size of the send and/or receive windows. Send data in multiples of the maximum segment size (MSS). Disable the Nagle algorithm. Q: Is there a limit to the number of sockets that can be created with RTCS? A: No. Sockets come from a partition with an infinite growth factor, so the number of sockets is limited only by the available memory on the board. Q: Do I always need at least one autostart task? A: Yes. In an application, at least one autostart application task is required in order to start the application. In a multiprocessor application (the application can create tasks remotely), each image need not have an autostart application task; however, each image must include IPC Task as an autostart task in the task template list. If no application task is created on a processor, Idle Task runs. Q: Is it possible to rename a task after it is created? A: Here's a function to get a pointer to the task's template struct where the task's name is stored. The function needs a couple of structures from mqx_prv.h.Namely, TD_STRUCT and KERNEL_DATA_STRUCT. You can add the function to your application or add it into MQX itself. If you are adding it to app, you will need to include "mqx_inc.h" and add mqx\source\include to the compiler's include search path. /*FUNCTION*-------------------------------------------------------------------* * Function Name : _task_get_template_ptr* Returned Value : TASK_TEMPLATE_STRUCT_PTR* Comments :* Returns a pointer to the task's template structure* *END*----------------------------------------------------------------------*/TASK_TEMPLATE_STRUCT_PTR _task_get_template_ptr(_task_id){ /* Body */  KERNEL_DATA_STRUCT_PTR kernel_data;  TD_STRUCT_PTR td_ptr;  _GET_KERNEL_DATA(kernel_data);  if (task_id == MQX_NULL_TASK_ID) {    td_ptr = kernel_data->ACTIVE_PTR;  } else {    td_ptr = (TD_STRUCT_PTR)_task_get_td(_task_id);  } /* Endif */  if (td_ptr) {    return( td_ptr->TASK_TEMPLATE_PTR );  } /* Endif */  return( NULL );} /* Endbody */An example of how to use this function:/* Need prototype */extern TASK_TEMPLATE_STRUCT_PTR _task_get_template_ptr(_task_id);..../* Dynamically create the task */some_task_id = _task_create(..... );.../* Change name of some_task */template_ptr = _task_get_template_ptr(some_task_id);template_ptr->TASK_NAME = "new name";../* Change name of the current (active) task */template_ptr = _task_get_template_ptr(MQX_NULL_TASK_ID);template_ptr->TASK_NAME = "new name"; Q: How are exceptions or unhandled interrupts handled by MQX? A: Basically, there are three ways of handling unhandled interrupts. They are mutually exclusive - in other words, you can only have one active at a time. You'd pick the one that best suits you for an application and use it: 1) _int_default_isr() This is the default mode of handling interrupts - it simply blocks the offending task and sets its state to "Unhandled Interrupt Blocked" 2) _int_unexpected_isr() This mode can be activated by calling _int_install_unexpected_isr() from the application. This will also block the offending task and set its state, but also will print some info on the console about who and what caused the unexpected exception 3) _int_exception_isr() This is the most functional (but also most complex) of all the modes. It can be activated by calling _int_install_exception_isr(). Once this is installed, any unhandled interrupts will call _int_exception_isr(). It might help you understand the behavior of this function by actually looking at the code. It's in source\psp\\int_xcpt.c. Here are the comments that define the behavior: If an exception happens while a task is running, then: if a task exception handler exists, it is executed, otherwise the task is aborted. If an exception happens while an isr is running, then: if an isr exception handler exists, it is executed, and the isr aborted otherwise the isr is aborted. This is why you have to provide exception handlers. For tasks, you install these with _task_set_exception_handler(). You would need to install a handler for each task in your system that you want handled (conceivably, this could be the same handler for all of them) For ISRs, you install these with _int_set_exception_handler(). The parameter is the vector number of the interrupt your installing a handler for, not the exception vector itself (in other words, you'd install handlers for the vectors of ethernet, UARTs, timers, etc, not the divide by zero vector) So, if you want to have full "handling" of all unhandled interrupts, you'll have to install handlers for all the tasks and ISRs that exist in your system. The handler itself could simply flag the error and allow the task to continue running. Other comments: -Note that you shouldn't have to rebuild MQX libraries to change the modes - its simply done with a function call -If one of the above three methods of handling unhandled interrupts does not suit you, you can also create your own handler to take whichever action you want and install it by calling _int_install_default_isr() with your own ISR as a parameter. This might be a simpler approach than using the exception handlers. Q:How is DNS enabled? A:Include DNS.H in the application. Call DNS_init() after calling RTCS_create(). Then insert the following code: DNS_First_Local_server[0].IP_ADDR = "my dns server's ip addr"; Q:Does MQX have memory protection? A: No, not full memory protection (this allows us to run the same code on CPUs -- like DSPs -- without MMUs). However, we do have a version of MQX with some level of MMU support. It allows simple memory protection between tasks and is available for some PowerPC derivatives. Q:What happens if Idle Task blocks because of an exception? A: If Idle Task blocks, System Task, which is really a system task descriptor that has no code, becomes the active task. System Task Descriptor sets up the interrupt stack; then re-enables interrupts. As a result, the application can continue to run. Q:If more than one task "owns" a semaphore, and a priority boost is required, do all owning tasks have their priority raised, or just one? A: The owning task with the highest priority gets boosted. Q:In many RTCS examples we find "/* Enable IP forwarding */ _IP_forward = TRUE;". What does this do? A: This enables forwarding of IP packets from one interface to another. If you have two Ethernet connections, this allows RTCS to route packets between the two interfaces. Q:How do we setup Ethernet auto-negotiation? A:Normally, this is done in the file enet_ini.c, located in the BSP (source/bsp), and normally autonegotiate is the default. Sometimes (but not always) the flag passed to enet_initialize is passed down to this function, and is used to select autonegotiate. Q:How do I bind a UDP socket to a specific IP address and have it receive broadcast packets? A: RTCS does not allow UDP sockets bound to a specific IP address to receive broadcast packets. You can get around this by binding using INADDR_ANY, however in this case you may receive extra traffic you do not wish to receive (e.g. there are two Ethernet interfaces on the board). RTCS emulates BSD and we consider this to be an appropriate behavior. Q:If there is no file system on an MQX target running RTCS how can I use FTP to upload and download files to it? Say I have a datafile on a PC that I want to be able to upload over ethernet to my MQX app as well as later download it. Can I do that without a file system ... say get a file line by line and interpret it? Likewise output it line by line? A: Yes, this is possible, but it requires that you do some work to design the "device" to handle this. Without a file system, the FTP server can communicate with any MQX device - these are usually identified by a string such as "ttya:", "ittyb:", "flash:", etc. They can either by installed by the application or the BSP. The ones previously mentioned are installed by the BSP, but the RTCS apps example (apps.c) also installs two new devices called null: and kmem: In order to communicate with these devices via FTP, on the PC you would do the following: Type: ftp my_ip_address (prompt for user name) - hit Enter To put a file to the server, type: put localfilename remotedevice For example: put test.txt ttya: This will send the contents of test.txt from the PC to the target - the ttya: device will put it to the screen. If you replace ttya: with null: in the apps example, it will simply discard everything it reads. To get a file from the server, type: get remotedevice localfilename For example: get kmem: coredump This will store the contents of kernel data into a file on the PC Now, you can design your own device to do something similar. I would recommend looking at the source\io\io_mem and source\io\io_null devices to use as templates. Basically, you need to code an install, open, close, read, write and ioctl function for your device. When the FTP server calls fopen(), read() and write() on your device, it will access these functions. It would be up to you to decide what to do with the data once it arrives in your functions, but you could process it and also store it for later use. Note that both the RTCS TFTP and FTP *servers* use the same structure. The FTP client uses device names to access the data to send. However, the TFTP client API decodes the data without using a device. Q: Is there a documented API for the IP layer? A:This interface isn't documented since it's assumed that the user won't usually access it. There are four functions: IP_init(), IP_send() (for outgoing packets), IP_send_if() and IP_service() (for incoming packets). IP_send_if() is used only by BOOTP/DHCP to send a limited broadcast with a source IP address of 0.0.0.0. Q: How is the timer used on MQX? A: On ColdFires, timer PIT is used as system timer for scheduler (dispatcher) and for time counting. Q: How to free memory after use mem_alloc? A: Use mem_free
記事全体を表示
It's a note to configre and use Flexbus interface in MQX platform .
記事全体を表示
A pair of TCP server & client and a pair UDP server & client are implemented to demo socket API in RTCS. It supports K60N512 and K70F120M on IAR EWARM 6.50 at this moment. You can port it to other boards and IDE easily. 1) Copy Freescale_MQX_4_0 folder and override the default MQX folder 2) RTCS Socket Example Guide.doc can be found in ..\Freescale_MQX_4_0\rtcs\examples\socket
記事全体を表示
This blog shares several issues reported by China customers when they use NAND FFS in MQX4.1.1. NAND FFS open failure issue Customer reported they can use a pressure test code to continuously open file, write file and close file, each time write about 20 bytes with append and they will find after running for a while, file open will fail and it returns error code 0x3067 (MFS_EOF). Each time file open failed, file has been written with 20480 bytes. This is a typical use case at customer side for data logging. The test code is attached named as "nand_pressure_test.cpp". Attached patch file named "mfs_write.patch" can resolve this issue. Memory allocation issue when using MFS & NAND FFS Customer run pressure test for MFS and NAND FFS by creating multiple levels of sub-folders (up to 100 levels) and in each sub-folder they create random number of files (up to 50). For each file, they will write 250 bytes. They found code failed to open new file when create sub-folders to 41 level. Traced the code on K70 tower and found actually this is not problem with MFS to search clusters for the new file, instead when the issue occurs, it's the drive_ptr (MFS_DRIVE_STRUCT) which is corrupted when MFS use memory allocation routine to allocate file path. The pressure test code for this case is attached. File named "MultiLevel_Folder_Test.zip". The memory corruption for MFS drive info is due to there is no protection in MFS_Parse_pathname() on whether the actual path name used passed from fopen will be exceeding 260 bytes which is fixed in mfs.h file to be compatible with Windows. So need to take care of this internal limitation when handling multiple level folders. MFS deadlock issue when using NAND FFS Customer reported random code block issue when running pressure test against NAND FFS. The issue is quite random, sometimes takes 12 hrs to reproduce the issue. Test code attached. Name is "MFS deadlock issue.zip". The resolution and description on this issue is in attached file named "MQX-4919 NandFFS explanation". Hao
記事全体を表示
Hi All, The new Freescale MQX™ 4.1.1 GA release is now available on www.freescale.com/mqxrtos ·         Files available           # Name Description 1 FSL_MQX_RELEASE_NOTES_4_1_1 Freescale   MQX™ RTOS 4.1.1 Release Notes 2 Freescale   MQX RTOS 4.1.1 for Linux This   release has the same basic code as the 4.1.1 version, with just the changes   needed to build and debug on Linux systems. 3 Freescale   MQX RTOS 4.1.1 MQX™    Source code. Includes an RTOS, File System, TCP/IP and USB host/device   software stacks. ·         What is New? ·         New Board Support Package o   FRDM-K64F o   TWR-K64F120M ·         New Features and Updates o   MQX RTOS 4.1.1 enables development on Linux machines o   MQX RTOS 4.1.1 supports the new Freescale IDE, Kinetis Design Studio o   Example ISR and related documentation is updated to give guidance on setting up a Kernel ISR (a.k.a Gorilla ISR) - extremely high priority ISR o   Power PC (PX) family support has been dropped o   Readme files are added to examples without a description o   Register definition header files for Kinetis MCUs are added for convenience when porting to an MCU sub-family device o   Both interrupt driven I2C master and slave mode drivers are changed to support synchronous blocking mode and share the same API with the polling driver variant.  Improves performance by eliminating the need to poll for data availability. ·         Known issues o   For known issues and limitations please consult the release notes
記事全体を表示
Hello I want to share this document that describes steps to configure and use the MQXLite Performance Tool to analyze and debug the applications of the Freescale MQXLite operating system. I hope this helps!! Regards Soledad
記事全体を表示
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.
記事全体を表示