Although the. NET Micro Framework is easy to learn and use, it is difficult for some applications that require real-time and high performance. After all, the upper-layer applications of. NET Micro Framework are interpreted and executed by the lower-layer CLR (TinyCLR). It is inevitable that the execution efficiency will be discounted.
GHI (a major manufacturer of. NET Micro Framework hardware products outside China) provides a RLP solution (https://www.ghielectronics.com/docs/50/rlp-enhanced ). Allow. NET Micro Framework applications call the C ++ program compiled by MDK, mainly to solve performance problems, and use C ++ to complete some code that is relatively time-consuming. The function is relatively simple.
Different from the solutions we provide, we use MDK to develop C ++ programs in a stream-driven manner. The user program uses the standard streaming Driver Interface for relevant calls. In addition, the streaming Driver provides an event mechanism, and the underlying layer and the upper layer can interact with each other through events.
In addition, it provides a variety of. NET Micro Framework PAL layer interfaces for the mdk c ++ program, allowing users to develop powerful programs as they wish.
Before that, I have written two related articles :《. NET Micro Framework dynamic call C/C ++ underlying code (Principles) and [Iot smart gateway-11] stream-driven user-driven (mdk c ++ development).
Compared with the functional functions introduced in the previous article, some more practical functions are extended, such as I2C and SPI interfaces. The underlying interrupt is enabled and disabled, HAL_COMPLETION and HAL_CONTINUATION are similar to the underlying multi-thread support and interrupt program user-state execution. The number of function functions has increased from 61 to 80. The specific functional interfaces are as follows:
(* (*lcd_printf)( * (*debug_printf)( * (** (* (** (* (*private_free)( **DISABLE_INTERRUPTS)(**ENABLE_INTERRUPTS)(**HAL_COMPLETION_Initialize)(HAL_CALLBACK_FPN EntryPoint,* (* (**HAL_CONTINUATION_Initialize)(HAL_CALLBACK_FPN EntryPoint,* (* (* (*hal_snprintf)( * buffer, size_t len, * (*hal_stricmp)( * dst, * (*hal_strncmp_s)( * str1, **hal_strlen_s)( * *(*memcpy)( * dst, * *(*memset)( * dst, **YFSoft_Flash_Read)( UINT32 address, UINT32 count,UINT8 **YFSoft_Flash_Write)( UINT32 address, UINT32 count,UINT8 * (** (** (**CPU_TIMER_Initialize)(UINT32 timer, UINT32 ARR,UINT16 PSC,HAL_CALLBACK_FPN ISR, ** (* (** (**USART_Initialize)( ComPortNum, BaudRate, Parity, DataBits, StopBits, *USART_Uninitialize)( (*USART_Write)( ComPortNum, * (*USART_Read)( ComPortNum, **USART_Flush)( (*USART_BytesInBuffer)( (*USART_DiscardBuffer)( * (******PWM_ApplyConfiguration)( PWM_CHANNEL channel, GPIO_PIN pin, UINT32& period, UINT32& duration, PWM_SCALE_FACTOR &* (***CPU_SPI_nWrite16_nRead16)( SPI_CONFIGURATION& Configuration, UINT16* Write16, INT32 WriteCount, UINT16**CPU_SPI_nWrite8_nRead8)( SPI_CONFIGURATION& Configuration, UINT8* Write8, INT32 WriteCount, UINT8****I2C_Execute)(UINT16 address,UINT8 *inBuffer, inCount,UINT8 *outBuffer, outCount,UINT32 clockRateKhz, (* (** (* (* (* (*LCD_DrawImage)(INT32 x,INT32 y,UINT8 * (*LCD_DrawImageEx)(INT32 x,INT32 y,UINT8 * (* (*LCD_DrawStringEx)(INT32 x,INT32 y,UINT32 color,UINT8 *fontdata, width, height, count); (* (* (*LCD_GetFrameBufferEx)(UINT8 * (* (*
The following describes the driver development steps.
1. Create a new project in MDK version 4. xx, add the generalstream. h header file, and then add the template file UserDriver. cpp. As shown in:
2. Select the MCU type. You can select STM32F103/STM32F207/STM32F407/STM32F405 based on the actual hardware.
(The chip used by lingxiao Smart terminal is STM32F405RG)
3. Enter the corresponding platform macro definition
4. Configure the discrete loading configuration file for specific hardware
The discrete file content of the lingxiao Smart terminal is as follows:
LR_IROM1 0x08010000 0x00010000 {; load region size_region
ER_IROM1 0x08010000 0x00010000 {; load address = execution address
}
RW_IRAM1 0x20000400 0x00002000 {; RW data
. ANY (+ RW + ZI)
}
}
It indicates that the program is loaded at 0x08010000, the size is 64 K, and the RAM space is the 8 K space starting from 0x20000400.
Note:In addition to the available RAM, user drivers can also allocate memory on the heap directly through the memory operation functions provided by interfaces.
5. Write the user driver (C/C ++). The following is a comprehensive example using GPIO operations, display operations, clock interrupt operations, and Event Notifications.
#include defined(YF_Campsis103) || defined(YF_Campsis405) COM_PORT COM1 COM_PORT COM3 TIMER_ISR(* defined(YF_Campsis103) || defined(YF_Campsis405)->CPU_GPIO_SetPinState(PC0,!MF->->CPU_GPIO_SetPinState(PF6,!MF->->CPU_TIMER_SetState(TIM3,(Num++>= MF->Notice_GenerateEvent(UserDriver_Hander, GeneralStream_Open2_UserDriver( MF = (IGeneralStream_Function* MF->debug_printf(,MF->iParam1,MF-> defined(YF_Campsis103) || defined(YF_Campsis405)->->->-> Num = ->CPU_TIMER_Initialize(TIM3,,(SYSTEM_TIM_CLOCK_HZ/--> MF->USART_Initialize(COM_PORT,,USART_PARITY_NONE, MF->->LCD_DrawString(,, GeneralStream_IOControl1_UserDriver( code, BYTE *inBuffer, inCount, BYTE *outBuffer, - GeneralStream_IOControl2_UserDriver( code, data[]={,,->USART_Write(COM_PORT, data, ->lcd_printf(->debug_printf( str[->hal_snprintf(str,,->LCD_FillRectangle(,,,->LCD_DrawString(, defined(YF_Wisteria207) || defined(YF_Wisteria407)->CPU_GPIO_SetPinState(PF7,! MF->->CPU_GPIO_SetPinState(PF8,! MF-> code+ GeneralStream_Read_UserDriver(BYTE *buffer, offset, - GeneralStream_Write_UserDriver(BYTE *buffer, offset, - main( IGeneralStream_Function *MF= IGeneralStream g_GeneralStream_UserDriver __attribute__ ((at(IGeneralStream_Address))) =&&&&&&&
7. Use YFAccessFlash to deploy the UserDriver. binfile.
Select the UserDriver. binfile and deploy it directly.
Note:If this is not the first time to deploy and run the user driver, you must terminate the execution of the current program. Otherwise, the deployment may fail (the application needs to be deployed first for the device of lingxiao 103, and then the user driver is deployed ).
8. User Programming (C #)
public class Program { public static void Main() { Debug.Print("UserDriver Test ..."); GeneralStream gs = new GeneralStream(); if (gs.Open("UserDriver") <= 0) { Debug.Print("Open UserDriver failed!"); return; } gs.Notice += new GeneralStreamEventHandler(gs_Notice); Debug.Print("Open UserDriver OK!"); int e = 0; byte[] bytData= new byte[8]; while (true) { Debug.Print(gs.IOControl(100, e++).ToString()); gs.Read(bytData, e, 10); System.Threading.Thread.Sleep(1000); } } static void gs_Notice(uint hander, uint data, DateTime timestamp) { Debug.Print(hander.ToString() + " - " + data.ToString()); } }
9. After the user program is written, it is directly compiled and executed in VS 2010.
Hardware operation (as follows ):
-------------------------------------------------------
MF Introduction: http://blog.csdn.net/yefanqiu/article/details/5711770
MF data: http://www.yfiot.com/DownloadList.asp? Id = 2 & page = 1