In the Rt-thread 2.0.0 formal version of the introduction of PIN devices as miscellaneous devices, its device driver files pin.c in Rt-thread-2.0.1\components\drivers\misc, mainly for the operation of Chip Gpio, such as light led, Keys and so on. At the same time for the corresponding chip platform, you need to write the underlying GPIO driver, such as GPIO.C.
One, in PIN.C defines a static PIN device object static struct Rt_device_pin _hw_pin, where struct type struct rt_device_pin is defined in Pin.h as:
/**/struct rt_device_pin{ struct rt_device parent; Const struct rt_pin_ops *ops;};
structrt_device_pin_mode{rt_uint16_t pin; //pin index in pins[] of gpio.crt_uint16_t mode;};structrt_device_pin_status{rt_uint16_t pin; //pin index in pins[] of gpio.crt_uint16_t status;};structrt_pin_ops{void(*pin_mode) (structRt_device *device, rt_base_t pin, rt_base_t mode); void(*pin_write) (structRt_device *device, rt_base_t pin, rt_base_t value); int(*pin_read) (structRt_device *device, rt_base_t pin); /*Todo:add GPIO Interrupt*/};
In Pin.c, the main implementation of the _pin_read,_pin_write,_pin_control three functions, while registering these three functions as a _hw_pin device Unified interface function:
intRt_device_pin_register (Const Char*name,Const structRt_pin_ops *ops,void*user_data) {_hw_pin.parent.type=rt_device_class_miscellaneous; _hw_pin.parent.rx_indicate=Rt_null; _hw_pin.parent.tx_complete=Rt_null; _hw_pin.parent.init=Rt_null; _hw_pin.parent.open=Rt_null; _hw_pin.parent.close=Rt_null; _hw_pin.parent.read=_pin_read; _hw_pin.parent.write=_pin_write; _hw_pin.parent.control=_pin_control; _hw_pin.ops=ops; _hw_pin.parent.user_data=User_data; /*register a character device*/Rt_device_register (&_hw_pin.parent, name, RT_DEVICE_FLAG_RDWR); return 0;}
Finally, the Rt_pin_mode,rt_pin_write,rt_pin_read three functions are added to the Finsh list of functions for debugging.
Second, the main implementation of the GPIO.C in the struct Rt_pin_ops three interface functions: Stm32_pin_mode,stm32_pin_write,stm32_pin_read:
Const Static struct rt_pin_ops _stm32_pin_ops ={ Stm32_pin_mode, stm32_pin_write, Stm32_pin_read,};
Also register the PIN device with the device name "PIN":
int stm32_hw_pin_init (void) { rt_device_pin_register ("pin" , &_stm32_pin_ops, rt_null); return 0 ;} Init_board_export (stm32_hw_pin_init); // Stm32_hw_pin_init'll be called in Rt_components_board_init ()
Third, when using the PIN device, you need to define the Rt_using_pin in the Rtconfig.h macro. Also modify the array of IO ports used in GPIO.C:
/*STM32 GPIO Driver*/structpin_index{intindex; uint32_t RCC; Gpio_typedef*Gpio; uint32_t pin;};/*LED->pd12,pd13,pd14,pd15; USER button->pa0*/Static Const structPin_index pins[] ={ { 0, Rcc_ahb1periph_gpiod, Gpiod, Gpio_pin_12},//Green{1, Rcc_ahb1periph_gpiod, Gpiod, gpio_pin_13},//Orange{2, Rcc_ahb1periph_gpiod, Gpiod, gpio_pin_14},//Red{3, Rcc_ahb1periph_gpiod, Gpiod, gpio_pin_15},//Blue{4, Rcc_ahb1periph_gpioa, Gpioa, gpio_pin_0},//User button};
Also in GPIO_PIN.C's peripheral initialization function, you need to call the Rt_device_open function (although the function is not implemented at the bottom), to ensure that the device reference count value of the PIN device object class Ref_count is not 0, so that the normal use of Rt_device_ Control,rt_device_write,rt_device_read function Operation Gpio Port:
Static structRt_device_pin_mode led_mode[]={ {0, Pin_mode_output}, {1, Pin_mode_output}, {2, Pin_mode_output}, {3, Pin_mode_output},};Static structRt_device_pin_status led_status[]={ {0, Pin_high},/*0:green on*/ {1, Pin_high},/*1:orange on*/ {2, Pin_high},/*2:red on*/ {3, Pin_high},/*3:blue on*/ {0, Pin_low},/*4:green off*/ {1, Pin_low},/*5:orange off*/ {2, Pin_low},/*6:red off*/ {3, Pin_low},/*7:blue off*/};/*it can ' t be pin_mode_input_pullup, or the key always keep Pin_high status*/Static structRt_device_pin_mode Key_mode = {4, pin_mode_input};Static structRt_device_pin_status Key_status = {4, pin_low};Static structRt_device_pin * PIN_DEVICE;
Staticrt_err_t Gpio_pin_init (Const Char*pin_device_name) {Pin_device= (structRt_device_pin *) Rt_device_find (pin_device_name); if(Pin_device = =rt_null) {rt_kprintf ("pin device for Gpio%s not found!\r\n", Pin_device_name); return-Rt_enosys; } /*Oflag have no meaning for pin device, so set to Rt_null*/ if(Rt_device_open (&pin_device->parent, rt_null) = =Rt_eok) { /*Init led*/ for(intI=0; i< (sizeof(Led_mode)/sizeof(led_mode[0])); i++) {Rt_device_control (&pin_device->parent, Rt_null, &Led_mode[i]); Rt_device_write (&pin_device->parent, Rt_null, &led_status[i],sizeof(Led_status[i]));//init all led Pin_high } /*Init key*/Rt_device_control (&pin_device->parent, Rt_null, &Key_mode); } return 0;}intRt_gpio_pin_init (void) {Gpio_pin_init ("Pin"); return 0;} Init_app_export (rt_gpio_pin_init);
Rt-thread device driver Component pin device