i.MX处理器知识库

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

i.MX Processors Knowledge Base

讨论

排序依据:
  This guide assumes that the developer has knowledge of the V4L2 API and has worked or is familiar with sensor drivers and their operation within the Linux kernel. This guide does not focus on the details of the sensor driver development that you want to port. It is assumed that you already have an existing driver for your sensor, before making the port. The version of the ISP's was 6.6.36 Linux BSP. If a different version is used, it is the developer's responsibility to review the API documentation for the corresponding version, since there may be changes that affect what is indicated in this guide. To port the camera sensor, the following steps must be taken as described in the following sections: Define sensor attributes and create instances. ISS Driver and ISP Media Server. Sensor Calibration Files. VVCAM Driver Creation. Device Tree Modifications. Define Sensor Attributes and Create Instances The following three steps are already implemented in CamDevice and are included for reference only. Step 1: Define the sensor attributes in the IsiSensor_s data structure. Step 2: Define the IsiSensorInstanceConfig_t configuration structure that will be used to create a new sensor instance. Step 3: Call the IsiCreateSensorIss() function to create a new sensor instance. ISS Driver and ISP Media Server Step 0 - Use a driver template as base code: Drivers can be found in $ISP_SOURCES_TOP/units/isi/drv/. For example, the ISP sources, come with the OV4656 and OS08a20 drivers. $ISP_SOURCES_TOP indicates the path of your working directory, where the respective sources are located. Step 1 - Add your <SENSOR> ISS Driver: Create the driver entry for your sensor in the path $ISP_SOURCES_TOP/units/isi/drv/<SENSOR>/source/<SENSOR>.c. Change all occurrences of the respective sensor name within the code, for instance, OV4656 -> <SENSOR>, respecting capital letters where applicable. Step 2 - Check the information on the IsiCamDrvConfig_s data structure: Data members defined in this data structure include the sensor ID (CameraDriverID) and the function pointer to the IsiSensor data structure. By using the address of the IsiCamDrvConfig_s structure, the driver can then access the sensor API attached to the function pointer. The following is an example of the structure: /***************************************************************************** * Each sensor driver needs to declare this struct for ISI load *****************************************************************************/ IsiCamDrvConfig_t IsiCamDrvConfig = {     .CameraDriverID = 0x0000,     .pIsiHalQuerySensor = <SENSOR>_IsiHalQuerySensorIss,     .pfIsiGetSensorIss = <SENSOR>_IsiGetSensorIss, };   Important Note: Modify the CameraDriverID according to the chip ID of your sensor. Apply this change to any Chip ID occurrence within the code. Step 3 - Check sensor macro definitions: In case there is any macro definition in the ISS Driver code, which involves specific properties of the sensor, you should modify it according to your requirements. For example: #define <SENSOR>_MIN_GAIN_STEP         (1.0f/16.0f)   Step 4 - Modify ISP Media Server build tools: Changes required in this step include: Add a CMakeLists.txt file in $ISP_SOURCES_TOP/units/isi/drv/<SENSOR>/ that builds your sensor module. Modify the CMakeLists.txt located at $ISP_SOURCES_TOP/units/isi/drv/CMakeLists.txt to include and reference your sensor directory. Modify the $ISP_SOURCES_TOP/appshell/ and $ISP_SOURCES_TOP/mediacontrol/ build tools, since by default they refer to the construction of a particular sensor, for example, the OV4656, so it is necessary to change the name of the corresponding sensor. Modify the $ISP_SOURCES_TOP/build-all-isp.sh script to reference the sensor modules and generate the corresponding binaries when building the ISP media server instance.   Step 5 - ISP Media Server run script: You need to add the operation modes defined for your sensor in the script. Each operating mode is associated with an order (mode 0, mode 1 ... mode N), a name used to execute the command in the terminal (e.g <sensor>_custom_mode_1), a resolution, and a specific calibration file for the sensor. The script is located at $ISP_SOURCES_TOP/imx/run.sh .   Step 6 - Sensor<X> config: At $ISP_SOURCES_TOP/units/isi/drv/ you can find the files to configure each sensor entry to the ISP, called Sensor0_Entry.cfg and Sensor1_Entry.cfg. There, the associated calibration files are indicated for each sensor operating mode, including the calibration files in XML format and the Dewarp Unit configuration files in JSON format. In addition, the .drv file generated for your sensor is referenced, creating the association between the respective /dev/video<X> node and the sensor driver module outputted from the ISP Media Server. In case you are using only one ISP channel, just modify Sensor0_Entry.cfg. In case you require both instances of the ISP, you will need to modify both files. Sensor Calibration Files It is a requirement for using the ISP, to have a calibration file in XML format, specific to the sensor you are using and according to the resolution and working mode. To obtain the calibration files in XML format, there are 3 options: Use the NXP ISP tuning tool for this you will need to ask for access or sign a NDA document. Pay NXP professional services to do the tune. Pay a third-party vendor to do the tune   VVCAM Driver Creation The changes indicated below are based on the assumption that there is a functional sensor driver in its base form, and that it is compatible with the V4L2 API. From now on we focus on applying the changes suggested in the NXP documentation, specifically to establish the communication of the VVCAM Driver (kernel side) and the ISI Layer. Step 0 - Create the sensor driver entry: Developers must add the driver code to the file located at $ISP_SOURCES_TOP/vvcam/v4l2/sensor/<sensor>/<sensor>_xxxx.c, along with a Makefile for the sensor driver module. In the same way, as indicated in the ISS Driver section, you can refer to one of the sample drivers that are included as part of the ISP sources, to review details about the implementation of the driver and the structure of the required Makefile.   Step 1 - Add the VVCAM mode info data structure array: This array stores all the supported modes information for your sensor. The ISI layer can get all the modes with the VVSENSORIOC_QUERY command. The following is an example of the structure, please fill in the information using the attributes of your sensor and the modes it supports. #include "vvsensor.h" . . .   static struct vvcam_mode_info_s <sensor>_mode_info[] = {         {         .index = 0,         .width = ... ,         .height = ... ,         .hdr_mode = ... ,         .bit_width = ... ,         .data_compress.enable = ... ,         .bayer_pattern = ... ,         .ae_info = {                        .                        .                        .                        },         .mipi_info = {                        .mipi_lane = ... ,                        },         },         {         .index = 1,         .         .         .         }, }; Step 2 - Define sensor client to i2c : Define the client_to_sensor macro (in case you don't have any already) and check the segments of the driver code that require this macro. #define client_to_<sensor>(client)\         container_of(i2c_get_clientdata(client), struct <sensor>, subdev)   Step 3 - Define the V4L2-subdev IOCTL function: Define and implement the <sensor>_priv_ioctl, which is used to receive the commands and parameters passed down by the user space through ioctl() and control the sensor. long <sensor>_priv_ioctl(struct v4l2_subdev *subdev, unsigned int cmd, void *arg) {         struct i2c_client *client = v4l2_get_subdevdata(subdev);         struct <sensor> *sensor = client_to_<sensor>(client);         struct vvcam_sccb_data_s reg;         uint32_t value = 0;         long ret = 0;           if(!sensor){                return -EINVAL;         }           switch (cmd) {         case VVSENSORIOC_G_CLK: {                ret = custom_implementation();                break;         }         case VIDIOC_QUERYCAP: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_QUERY: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_G_CHIP_ID: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_G_RESERVE_ID: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_G_SENSOR_MODE:{                ret = custom_implementation();                break;         }         case VVSENSORIOC_S_SENSOR_MODE: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_S_STREAM: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_WRITE_REG: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_READ_REG: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_S_EXP: {                ret = custom_implementation();                break;         }         case VVSENSORIOC_S_POWER:         case VVSENSORIOC_S_CLK:         case VVSENSORIOC_RESET:         case VVSENSORIOC_S_FPS:         case VVSENSORIOC_G_FPS:         case VVSENSORIOC_S_LONG_GAIN:         case VVSENSORIOC_S_GAIN:         case VVSENSORIOC_S_VSGAIN:         case VVSENSORIOC_S_LONG_EXP:         case VVSENSORIOC_S_VSEXP:          case VVSENSORIOC_S_WB:         case VVSENSORIOC_S_BLC:         case VVSENSORIOC_G_EXPAND_CURVE:                break;         default:                break;         }           return ret; }   As you can see in the example, some cases are implemented but others are not. Developers are free to implement the features they consider necessary, as long as a minimum base of operation of the driver is guaranteed (query commands, read and write registers, among others). It is the developer's responsibility to implement each custom function, for each case or scenario that may arise when interacting with the sensor. In addition to what was shown previously, a link must be created to make the ioctl connection with the driver in question. Link your priv_ioctl function on the v4l2_subdev_core_ops struct, as in the example below: static const struct v4l2_subdev_core_ops <sensor>_core_ops = {         .s_power       = v4l2_s_power,         .subscribe_event = v4l2_ctrl_subdev_subscribe_event,         .unsubscribe_event = v4l2_event_subdev_unsubscribe,      // IOCTL link         .ioctl = <sensor>_priv_ioctl, };   Step 4 - Verify your sensor's private data structure: After performing the modifications suggested, it would be a good practice to double-check your sensor's private data structure properties, in case there is one missing, and also check that the properties are initialized correctly on the driver's probe.   Step 5 - Modify VVCAM V4L2 sensor Makefile : At $ISP_SOURCES_TOP/vvcam/v4l2/sensor/Makefile, include your sensor object as follows: ... obj-m += <sensor>/ ... Important Note: There is a very common issue that appears when working with camera sensor drivers in i.MX8MP platforms. The kernel log message shows something similar to the following: mxc-mipi-csi2.<X>: is_entity_link_setup, No remote pad found! The link setup callback is required by the Media Controller when performing the linking process of the media entities involved in the capture process of the camera. Normally, this callback is triggered by the imx8-media-dev driver included as part of the Kernel sources. To make sure that the problem is not related to your sensor driver, verify the link setup callback is already created in the code, and if is not, you can add the following template: /* Function needed by i.MX8MP */ static int <sensor>_camera_link_setup(struct media_entity *entity,                                    const struct media_pad *local,                                    const struct media_pad *remote, u32 flags) {     /* Return always zero */         return 0; }   /* Add the link setup callback to the media entity operations struct */ static const struct media_entity_operations <sensor>_camera_subdev_media_ops = {         .link_setup = <sensor>_camera_link_setup, };     /* Verify the initialization process of the media entity ops in the sensor driver's probe function*/ static int <sensor>_probe(struct i2c_client *client, ...) {         /* Initialize subdev */         sd = &<sensor>->subdev;         sd->dev = &client->dev;         <sensor>->subdev.internal_ops = ...         <sensor>->subdev.flags |= ...         <sensor->subdev.entity.function = ...     /* Entity ops initialization */         <sensor->subdev.entity.ops = &<sensor>_camera_subdev_media_ops; } In most cases, adding the link setup function will solve the media controller issue, or at least it discards problems on the driver side. Device Tree Modifications On the Device Tree side, it is necessary to enable the ISP channels that will be used. Likewise, it is necessary to disable the ISI channels, which are normally the ones that connect to the MIPI_CSI2 ports to extract raw data from the sensor (in case the ISP is not used). A MIPI_CSI2 port can be mapped to either an ISI channel or an ISP channel, but not both simultaneously. In this guide, we focus on using the ISP, so any other custom configuration that you want to implement may vary from what is shown. In the code below, ISP channel 0 is enabled, and the connection is made to the port where the sensor is connected (mipi_csi_0). &mipi_csi_0 {         status = "okay";         port@0 {         // Example endpoint to <sensor>_ep                mipi0_sensor_ep: endpoint@1 {                        remote-endpoint = <&<sensor>_ep>;                };         }; };   &cameradev {         status = "okay"; };   &isi_0 {         status = "disabled"; };   &isi_1 {         status = "disabled"; };   &isp_0 {         status = "okay"; };   &isp_1 {         status = "disabled"; };   &dewarp {         status = "okay"; }; What is shown above does not represent a complete device tree file, is only a general skeleton of the points you should pay attention to when working with ISP channels. For simplicity, we omitted all the attributes that are normally defined when working with camera sensor drivers and their respective configurations in the i2c port of the hardware.   Note: Due to hardware restrictions when using ISP channels, it is recommended to use the isp_0 channel, when working with only one sensor. In case you need to use two sensors, you can enable both channels, taking into account the limitations regarding the output resolutions and the clock frequency when both channels are working simultaneously. What is not recommended is to use the isp_1 channel when working with a single sensor.   References ISP Independent Sensor Interface (ISI) API reference, I.MX8M Plus Camera Sensor Porting User guide: https://www.nxp.com/webapp/Download?colCode=IMX8MPCSPUG Sensor Calibration tool: https://www.nxp.com/webapp/Download?colCode=AN13565 i.MX8M Plus reference manual: https://www.nxp.com/webapp/Download?colCode=IMX8MPRM  
查看全文
The Gui-guilder doesn't provide remote debug function in IDE and we still need use Yocto to build project or copy binary to board rootfs. This knowledge base will provide a solution about how to use VSCode to remote debug LVGL project on i.MX93 EVK board.    Yocto toolchain: L6.6.x GUI GUILDER: v1.8.0   Need to open GUI GUILDER project in VSCode.   1.Scripts in VScode   1.1 build.sh Modify build.sh in <LVGL project>/ports/linux     #!/bin/sh toolchain=$1 if [ -z "$toolchain" ];then toolchain=/opt/fsl-imx-xwayland/6.1-mickledore/sysroots/x86_64-pokysdk-linux/usr/share/cmake/armv8a-poky-linux-toolchain.cmake if [ ! -r $toolchain ];then toolchain=/opt/fsl-imx-xwayland/6.1-langdale/sysroots/x86_64-pokysdk-linux/usr/share/cmake/armv8a-poky-linux-toolchain.cmake fi fi toolchain_path=$(echo $toolchain |sed -E 's,^(.*)/sysroots/.*,\1,') toolchain_arch=armv8a-poky-linux if [ ! -r $toolchain -o ! -r "$toolchain_path/environment-setup-$toolchain_arch" ];then echo "ERROR: Yocto Toolchain not installed?" exit 1 fi if [ -n "$BASH_SOURCE" ]; then ROOTDIR="`readlink -f $BASH_SOURCE | xargs dirname`" elif [ -n "$ZSH_NAME" ]; then ROOTDIR="`readlink -f $0 | xargs dirname`" else ROOTDIR="`readlink -f $PWD | xargs dirname`" fi BUILDDIR=$ROOTDIR/../build rm -fr $BUILDDIR mkdir $BUILDDIR . "$toolchain_path/environment-setup-$toolchain_arch" echo "start build..." cd $ROOTDIR/linux/lv_drivers/wayland/ cmake . make cd $BUILDDIR toolchain_path=/opt/fsl-imx-wayland/6.6-scarthgap/sysroots/x86_64-pokysdk-linux/usr/share/cmake/armv8a-poky-linux-toolchain.cmake cmake -G 'Ninja' .. -DCMAKE_TOOLCHAIN_FILE=$toolchain_path -Wno-dev -DLV_CONF_BUILD_DISABLE_EXAMPLES=1 -DLV_CONF_BUILD_DISABLE_DEMOS=1 -DCMAKE_CXX_FLAGS="-ggd3 -O0" -DCMAKE_BUILD_TYPE=Debug ninja if [ -e gui_guider ];then echo "Binary locates at $(readlink -f gui_guider)" ls -lh gui_guider fi # Copy binary to board scp $BUILDDIR/gui_guider root@192.168.31.243:/opt     1.2 tasks.json     { "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "./build.sh /opt/fsl-imx-wayland/6.6-scarthgap", "options": { "cwd": "${workspaceFolder}/ports/linux" }, "problemMatcher": [ "$gcc" ], } ] }       1.3 launch.json   miDebuggerServerAddress is board ip address.     { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "preLaunchTask": "Build", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/gui_guider", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}/", "environment": [], "externalConsole": false, "MIMode": "gdb", "logging": { "engineLogging": true, "trace": true, "traceResponse": true }, "debugStdLib":true, "miDebuggerPath":"/usr/bin/gdb-multiarch", //DO NOT USE GDB IN SDK!!!! "miDebuggerServerAddress": "192.168.31.243:12345", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true, "text": "set remotetimeout 100", } ] }] }       2. Launch gdbserver on board     export SHELL=/opt/gui_guider gdbserver 192.168.31.243:12345 /opt/gui_guider       3. Debug in VSCode   Click (gdb)launch, the source code will be compiled. Then you will see the breakpoint in program. Enjoy your debug~    
查看全文
Introduction Time Synchronization stands for the alignment of time within distributed nodes, pretty critical for real-time applications, control and measurement systems as voice and video networks; all of them being embedded applications. It needs the synchronization of frequency, phase and time between all the nodes and offers action coordination, high precision triggers and event reference or timestamping. [1] A Time Synchronization resource it's the ethernet standard for time PTP or IEEE 1588 standard, its study begin with the physical representation of time information: PPS; Pulse Per Second. An squared wave timed by the capable MACs, in i.MX families we have two MACs of which. Background Customers are interested in this signal, we have an i.MX 8M Plus kernel 5 resource but there is a new processor family using the next major kernel version; 6. [2] We will go through demonstrating PPS on i.MX 93 EVK in both MACs; FEC and EQOS. HW setup i.MX 93 EVK boot over eMMC. Connect power and debug receptacles. Hands-on for FEC or eth0 MAC uSDHC2 pin group conflicts with the pps output pin and you are ought to remove the uSDHC2 nodes and assign the event0 out pin to the FEC pin group as shown below. --- imx93-11x11-evk.dts 2024-08-23 18:19:56.344798901 +0200 +++ imx93-11x11-evk-pps.dts 2024-09-02 21:31:46.569477421 +0200 @@ -100,18 +100,6 @@ regulator-max-microvolt = <1800000>; }; - reg_usdhc2_vmmc: regulator-usdhc2 { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; - regulator-name = "VSD_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; - off-on-delay-us = <12000>; - enable-active-high; - }; - reg_vdd_12v: regulator-vdd-12v { compatible = "regulator-fixed"; regulator-name = "reg_vdd_12v"; @@ -770,21 +766,6 @@ status = "okay"; }; -&usdhc2 { - pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; - pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; - pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>; - cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>; - fsl,cd-gpio-wakeup-disable; - vmmc-supply = <&reg_usdhc2_vmmc>; - bus-width = <4>; - status = "okay"; - no-sdio; - no-mmc; -}; - &usdhc3 { pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_usdhc3_wlan>; @@ -860,14 +842,15 @@ MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x57e MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x57e MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x58e MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x57e MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x57e MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x57e MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x57e MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x58e MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x57e + MX93_PAD_SD2_DATA0__ENET1_1588_EVENT0_OUT 0x31e >; }; @@ -887,6 +870,7 @@ MX93_PAD_ENET2_TD3__GPIO4_IO16 0x51e MX93_PAD_ENET2_TXC__GPIO4_IO21 0x51e MX93_PAD_ENET2_TX_CTL__GPIO4_IO20 0x51e + MX93_PAD_SD2_DATA0__GPIO3_IO03 0x31e >; }; @@ -998,75 +982,6 @@ >; }; - pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { - fsl,pins = < - MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e - >; - }; - - pinctrl_usdhc2_gpio: usdhc2gpiogrp { - fsl,pins = < - MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e - >; - }; - - pinctrl_usdhc2_gpio_sleep: usdhc2gpiogrpsleep { - fsl,pins = < - MX93_PAD_SD2_CD_B__GPIO3_IO00 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582 - MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382 - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382 - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382 - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382 - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382 - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e - MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe - MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - pinctrl_usdhc2_sleep: usdhc2grpsleep { - fsl,pins = < - MX93_PAD_SD2_CLK__GPIO3_IO01 0x51e - MX93_PAD_SD2_CMD__GPIO3_IO02 0x51e - MX93_PAD_SD2_DATA0__GPIO3_IO03 0x51e - MX93_PAD_SD2_DATA1__GPIO3_IO04 0x51e - MX93_PAD_SD2_DATA2__GPIO3_IO05 0x51e - MX93_PAD_SD2_DATA3__GPIO3_IO06 0x51e - MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e - >; - }; - /* need to config the SION for data and cmd pad, refer to ERR052021 */ pinctrl_usdhc3: usdhc3grp { fsl,pins = < The driver also needs the following rework. --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -184,7 +184,8 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable) val |= (1 << FEC_T_TF_OFFSET | 1 << FEC_T_TIE_OFFSET); val &= ~(1 << FEC_T_TDRE_OFFSET); val &= ~(FEC_T_TMODE_MASK); - val |= (FEC_HIGH_PULSE << FEC_T_TMODE_OFFSET); + // val |= (FEC_HIGH_PULSE << FEC_T_TMODE_OFFSET); + val |= (FEC_TMODE_TOGGLE << FEC_T_TMODE_OFFSET); writel(val, fep->hwp + FEC_TCSR(fep->pps_channel)); /* Write the second compare event timestamp and calculate After booting the board, run these commands: $ ptp4l -A -4 -H -m -i eth0 & $ echo 1 > /sys/class/ptp/ptp0/pps_enable These will get the SD2_DATA0 or TP1009 running a square wave at 0.5 Hz through setting the ptp0 port with: -A    Select the delay mechanism automatically. Start with E2E and switch to P2P when a peer delay request is received. -4    Select the UDP IPv4 network transport. This is the default transport. -H    Select the hardware time stamping. -m    Print messages to the standard output. Run the next command to set the pps (1 Hz signal): $ echo "0 $(date +%s) 100000000 1 0" > /sys/class/ptp/ptp0/period The last because the current driver needs the actual date and a future start; in this case the signal will start within 100 ms, in order to work. You can try with different start times until the optimal value is found. [3]   Hands-on for EQOS or eth1 MAC This is reduced to the proper devicetree changes, and it does not have driver rework nor pps_enable control file. It uses SD2_CLK or TP1008, so DTS need this adjustment: --- imx93-11x11-evk.dts 2024-08-23 18:19:56.344798901 +0200 +++ imx93-11x11-evk-pps.dts 2024-09-02 21:31:46.569477421 +0200 @@ -100,18 +100,6 @@ regulator-max-microvolt = <1800000>; }; - reg_usdhc2_vmmc: regulator-usdhc2 { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; - regulator-name = "VSD_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; - off-on-delay-us = <12000>; - enable-active-high; - }; - reg_vdd_12v: regulator-vdd-12v { compatible = "regulator-fixed"; regulator-name = "reg_vdd_12v"; @@ -770,21 +766,6 @@ status = "okay"; }; -&usdhc2 { - pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; - pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; - pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>; - cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>; - fsl,cd-gpio-wakeup-disable; - vmmc-supply = <&reg_usdhc2_vmmc>; - bus-width = <4>; - status = "okay"; - no-sdio; - no-mmc; -}; - &usdhc3 { pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_usdhc3_wlan>; @@ -822,14 +802,15 @@ MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x57e MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x57e MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x58e MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x57e MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x57e MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x58e MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e + MX93_PAD_SD2_CLK__ENET_QOS_1588_EVENT0_OUT 0x31e >; }; @@ -849,6 +830,7 @@ MX93_PAD_ENET1_TD3__GPIO4_IO02 0x31e MX93_PAD_ENET1_TXC__GPIO4_IO07 0x31e MX93_PAD_ENET1_TX_CTL__GPIO4_IO06 0x31e + MX93_PAD_SD2_CLK__GPIO3_IO01 0x31e >; }; @@ -998,75 +982,6 @@ >; }; - pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { - fsl,pins = < - MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e - >; - }; - - pinctrl_usdhc2_gpio: usdhc2gpiogrp { - fsl,pins = < - MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e - >; - }; - - pinctrl_usdhc2_gpio_sleep: usdhc2gpiogrpsleep { - fsl,pins = < - MX93_PAD_SD2_CD_B__GPIO3_IO00 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582 - MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382 - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382 - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382 - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382 - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382 - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e - MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe - MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - pinctrl_usdhc2_sleep: usdhc2grpsleep { - fsl,pins = < - MX93_PAD_SD2_CLK__GPIO3_IO01 0x51e - MX93_PAD_SD2_CMD__GPIO3_IO02 0x51e - MX93_PAD_SD2_DATA0__GPIO3_IO03 0x51e - MX93_PAD_SD2_DATA1__GPIO3_IO04 0x51e - MX93_PAD_SD2_DATA2__GPIO3_IO05 0x51e - MX93_PAD_SD2_DATA3__GPIO3_IO06 0x51e - MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e - >; - }; - /* need to config the SION for data and cmd pad, refer to ERR052021 */ pinctrl_usdhc3: usdhc3grp { fsl,pins = < After boot, issue these commands: $ ptp4l -A -4 -H -m -i eth1 & $ echo "0 $(date +%s) 1000000000 1 0" > /sys/class/ptp/ptp1/period You will have an squared wave of 1 Hz running within 1 s with the same settings as the FEC setup.   Conclusion Both PPS can run in the same image changes and DTS changes, proven in imx-linux-nanbield branch, with the manifest imx-6.6.3-1.0.0.xml. And it's the start of testing IEEE 1588 and syncing capabilities of this i.MX 9 series processors. Sources [1] http://events17.linuxfoundation.org/sites/events/files/slides/elc_insop_2015.pdf [2] https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/i-MX8-serials-IEEE1588-1pps-test-procedure/ta-p/1490634 [3] https://github.com/nxp-imx/linux-imx/blob/b586a521770e508d1d440ccb085c7696b9d6d387/Documentation/ABI/testing/sysfs-ptp#L2
查看全文
Note: This guide is specifically for use with VS Code. For standalone with Segger software please refer to this guide. (How to Use Segger J-Link Plus with i.MX 8M Process... - NXP Community) In this guide we will describe the process to start using VS Code to debug an SDK application. The board used for this guide specifically is the i.MX 8M Nano EVK, but it also applies to all processors of the i.MX 8M Family. This guide covers the following topics: Hardware requirements Software requirements How to find, build, and download the i.MX SDK Debug Probe and i.MX 8M Nano EVK connection Create an SDK Application with MCUXpresso for VS Code Run and debug your SDK Application with MCUXpresso for VS Code Hardware requirements Evaluation Kit for the i.MX8M Nano Applications Processor (i.MX 8M Nano Evaluation Kit | NXP Semiconductors) Quick Start Guide for i.MX8M Nano (I.MX 8M Nano EVK Quick Start Guide (nxp.com)) J-Link Plus JTAG/SWD debug probe with USB interface (SEGGER J-Link PLUS) Features Download speed up to 1MB/s Unlimited breakpoints in flash memory Supports direct download into RAM and flash memory Supported NXP Devices Supported Devices - Search results "nxp" (segger.com) 9 Pin Cortex-M Adapter (9-Pin Cortex-M Adapter (segger.com)) Description Adapts from the 20-pin 0.1'' JTAG connector to a 9-pin 0.05'' Samtec FTSH connector as defined by Arm. Software requirements Windows 10 OS (host) J-Link Software and Documentation Pack for Windows (https://www.segger.com/products/debug-probes/j-link/models/j-link-plus/) i.MX 8M Nano SDK (Welcome | MCUXpresso SDK Builder (nxp.com)) VS Code for Windows (Installation Guide: Running Visual Studio Code on Windows) MCUXpresso Extension for VS Code (Installation Guide: Training: Walkthrough of MCUXpresso for VS Code - NXP Community)   How to find, build, and download the i.MX 8M Nano SDK Enter Welcome | MCUXpresso SDK Builder (nxp.com) Click on "Select Development Board"  Select EVK-MIMX8MN (MIMX8MN6xxxJZ) from Boards -> i.MX -> EVK-MIMX8MN Click on the Build MCUXpresso SDK button Click on Download SDK, you'll be redirected to the MCUXpresso SDK Dashboard Look for the i.MX 8M Nano SDK and click on Download SDK Click on Download SDK archive and documentation, accept the Software Terms and Conditions and the .zip file for the SDK will be downloaded. Debug Probe and i.MX 8M Nano EVK connection Connect the debug cable (USB-UART) to the board and the other end to your PC. Connect the power cable to the second USB-C port and to a wall socket. Don't turn on the board yet. Connect the JLink Plus to your PC with the USB cable. Connect the JLink Plus to the JTAG of the i.MX 8M Nano EVK board In this part we will need to identify pin number 1 from the 9 Pin Cortex-M adapter and from the i.MX 8M Nano EVK board. For the first one identifies pin 7 identifiable by a "non-connect pin". For the i.MX 8M Nano, you can identify easily with a number 1 in one corner of the connectors.    The whole setup should look similar to this:   Create an SDK Application with MCUXpresso for VS Code Before delving into the details of creating an SDK Application it is important to recognize the sections of VS Code User Interface. This will help us to describe accurately the buttons' position. Click on MCUXpresso for VS Code extension icon from the Activity Bar.  In the section “Quickstart Panel” located in the Side Bar click on “Import Repository.” On this window, go to “Local” and select your previously downloaded SDK folder location. Then, click on “Import.” Expand the section “Installed Repositories” from Side Bar and verify your selected SDK. Expand the section “Projects” from Side Bar and click on “Import Example from Repository” and complete the options: Choose a toolchain Choose a board Choose a template Name Location Finally, click on the "Create" button. Click on the gear icon located in the project folder to build the code. In “Projects” expand the “Settings” options and select “mcuxpresso-tools.json.” Here you will find a JSON file with different parameters. Defines the device that will be used to connect with the J-Link Plus. Code: “segger”: { “device”: “MIMX8MN6_M7” } Expand the section “Debug Probes” and verify that your J-Link Plus debug probe appears. Start SEGGER J-Link GDB Server. On section “Target Device” select MIMX8MN6_M7 and click “OK”. You will see the following window. Run and debug your SDK Application with MCUXpresso for VS Code Click on “Debug” located in the project folder, to start with the debugging session. In the Panel click on “Serial Monitor,” set it to the serial debug port with the lowest numbered port with the following settings: Baud rate: 115200 Line ending: None Click on "Start Monitoring" Use the debug controls to run the code. Verify your code output in the “Serial Monitor.”
查看全文
P3T1755 Demo   In this space I want to show you the things that you can create usign our products.   In  this demo I demostrate a use case creating a GUI for a Temperature Sensor.   We can create modern GUIs and more with LVGL combined with our powerful processors.               CPU USAGE As we can see  the CPU usage for this demo is around 2%   Pictures         This demo is based on the previous publused articles.   References: https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/Adding-support-to-P3T1755-on-Linux/ta-p/1855874 https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/How-to-run-LGVL-on-iMX-using-framebuffer/ta-p/1853768  
查看全文
Customer proposed to debug code on A core during development stage.  HW: i.MX93/i.MX8MP SW: L6.1.36, Real-time edge Feature: Besides debugging code, enabled compiling image by eclipse. cpu0 boot, then kick off/halt other secondary cpu, debug code on secondary cpu core. Auto reset board and connect jlink to be convenient for restarting debugging.  
查看全文
  Some customers want to expose their i3c device on the /dev, In order to develop their i3c APP or operation the i3c device like I2C. But in our default BSP code, we do not support this feature for I3C device, This article will introduce how to make the i3c device expose to the user space. Board : i.MX 93 EVK BSP Version : lf-6.1.55-2.2.0 I3C device : LSM6DSOXTR Step 1 : Rework the i.MX93 EVK Board, Install the R1010.      Step 2 : Apply the add_i3c_device_to_dev.patch file to the linux kernel code              Command : git apply add_i3c_device_to_dev.patch Step 3 : Re-compile the kernel Image file.              Command : make imx_v8_defconfig                                  make Step 4 : Boot your board with "imx93-11x11-evk-i3c.dtb" file and see if you can see the I3C device on the /dev directory. Result : We can see the i3c device is appeared in /dev directory, The i2c-8 is an i2c device mounted to the i3c bus. The i3c is backward compatible with i2c device. It will simulate the I2C signal loading i2c device.                 PS : You can also use the i2ctool detect i2c-8 device. As shown in the following picture:   Note : If you need the patch file, Please contact me any time for free.
查看全文
Ftrace is powerful tracing utility embedded in Linux kernel. It provides a very good method for kernel developer to get insights of the kernel behavior. While official kernel doc for ftrace is somehow long and complex, this document provides a quicker and simpler way to get start with ftrace.
查看全文
This guide is a continuation from our latest Debian 12 Installation Guide for iMX8MM, iMX8MP, iMX8MN and iMX93. Here we will describe the process to install the multimedia and hardware acceleration packages, specifically GPU, VPU and Gstreamer on i.MX8M Mini, i.MX8M Plus and i.MX8M Nano. The guide is based on the one provided by our colleague Build Ubuntu For i.MX8 Series Platform - NXP Community, which requires to previously build an image using Yocto Project with the following distro and image name. Distro name - fsl-imx-wayland Image name – imx-image-multimedia For more information please check our BSP documentation i.MX Yocto Project User’s Guide.   Hardware Requirements Linux Host Computer (Ubuntu 20.04 or later) USB Card reader or Micro SD to SD adapter SD Card Evaluation Kit Board for the i.MX8M Nano, i.MX8M Mini, i.MX8M Plus   Software Requirements Linux Ubuntu (20.04 tested) or Debian for Host Computer BSP version 6.1.55 built with Yocto Project   After built the image we can start the installation by following the steps below:   GPU Installation The GPU Installation consists of copy the files from packages imx-gpu-g2d, imx-gpu-viv, libdrm to the Debian system. As our latest installation guide, we will continue naming “mountpoint” to the directory where Debian system is mounted on our host machine. Regarding the path provided on each step, we put labels <build-path> and <machine> that you will need to change based on your environment. These are the paths that Yocto Project uses to save the packages. However, this could change on your environment and you can find the work directory from each package using the following command: bitbake -e <package-name> | grep ^WORKDIR= This command will show you the absolute path of the package work directory. 1. Install GPU Packages $ sudo cp -Pra <build-path>/tmp/work/armv8a-<machine>-poky-linux/imx-gpu-g2d/6.4.11.p2.2-r0/image/* mountpoint $ sudo cp -Pra <build-path>/tmp/work/armv8a-<machine>-poky-linux/imx-gpu-viv/1_6.4.11.p2.2-aarch64-r0/image/* mountpoint $ sudo cp -Pra <build-path>/tmp/work/armv8a-<machine>-poky-linux/libdrm/2.4.115.imx-r0/image/* mountpoint   2. Install Linux IMX Headers and IMX Parser $ sudo cp -Pra <build-path>/tmp/work/armv8a-<machine>-poky-linux/linux-imx-headers/6.1-r0/image/* mountpoint $ sudo cp -Pra <build-path>/tmp/work/armv8a-poky-linux/imx-parser/4.8.2-r0/image/* mountpoint   3. Use chroot $ sudo LANG=C.UTF-8 chroot mountpoint/ qemu-aarch64-static /bin/bash   4. Install Dependencies $ apt install libudev-dev libinput-dev libxkbcommon-dev libpam0g-dev libx11-xcb-dev libxcb-xfixes0-dev libxcb-composite0-dev libxcursor-dev libxcb-shape0-dev libdbus-1-dev libdbus-glib-1-dev libsystemd-dev libpixman-1-dev libcairo2-dev libffi-dev libxml2-dev kbd libexpat1-dev autoconf automake libtool meson cmake ssh net-tools network-manager iputils-ping rsyslog bash-completion htop resolvconf dialog vim udhcpc udhcpd git v4l-utils alsa-utils git gcc less autoconf autopoint libtool bison flex gtk-doc-tools libglib2.0-dev libpango1.0-dev libatk1.0-dev kmod pciutils libjpeg-dev   5. Create a folder for Multimedia Installation. Here we will clone all the multimedia repositories.  $ mkdir multimedia_packages $ cd multimedia_packages   6. Build Wayland $ git clone https://gitlab.freedesktop.org/wayland/wayland.git $ cd wayland $ git checkout 1.22.0 $ meson setup build --prefix=/usr -Ddocumentation=false -Ddtd_validation=true $ cd build $ ninja install   7. Build Wayland Protocols IMX $ git clone https://github.com/nxp-imx/wayland-protocols-imx.git $ cd wayland-protocols-imx $ git checkout wayland-protocols-imx-1.32 $ meson setup build --prefix=/usr -Dtests=false $ cd build $ ninja install   8. Build Weston $ git clone https://github.com/nxp-imx/weston-imx.git $ cd weston-imx $ git checkout weston-imx-11.0.3 $ meson setup build --prefix=/usr -Dpipewire=false -Dsimple-clients=all -Ddemo-clients=true -Ddeprecated-color-management-colord=false -Drenderer-gl=true -Dbackend-headless=false -Dimage-jpeg=true -Drenderer-g2d=true -Dbackend-drm=true -Dlauncher-libseat=false -Dcolor-management-lcms=false -Dbackend-rdp=false -Dremoting=false -Dscreenshare=true -Dshell-desktop=true -Dshell-fullscreen=true -Dshell-ivi=true -Dshell-kiosk=true -Dsystemd=true -Dlauncher-logind=true -Dbackend-drm-screencast-vaapi=false -Dbackend-wayland=false -Dimage-webp=false -Dbackend-x11=false -Dxwayland=false $ cd build $ ninja install   VPU Installation To install VPU and Gstreamer please follow the steps below: 1. Install firmware-imx $ sudo cp -Pra <build-path>/tmp/work/all-poky-linux/firmware-imx/1_8.22-r0/image/lib/* mountpoint/lib/   2. Install VPU Driver $ sudo cp -Pra <build-path>/tmp/work/armv8a-<machine>-poky-linux/imx-vpu-hantro/1.31.0-r0/image/* mountpoint $ sudo cp -Pra <build-path>/tmp/work/armv8a-<machine>-poky-linux/imx-vpuwrap/git-r0/image/* mountpoint   3. Use chroot $ sudo LANG=C.UTF-8 chroot mountpoint/ qemu-aarch64-static /bin/bash   4. Install dependencies for Gstreamer Plugins $ apt install libgirepository1.0-dev gettext liborc-0.4-dev libasound2-dev libogg-dev libtheora-dev libvorbis-dev libbz2-dev libflac-dev libgdk-pixbuf-2.0-dev libmp3lame-dev libmpg123-dev libpulse-dev libspeex-dev libtag1-dev libbluetooth-dev libusb-1.0-0-dev libcurl4-openssl-dev libssl-dev librsvg2-dev libsbc-dev libsndfile1-dev   5. Change directory to multimedia packages. $ cd multimedia-packages   6. Build gstreamer $ git clone https://github.com/nxp-imx/gstreamer -b lf-6.1.55-2.2.0 $ cd gstreamer $ meson setup build --prefix=/usr -Dintrospection=enabled -Ddoc=disabled -Dexamples=disabled -Ddbghelp=disabled -Dnls=enabled -Dbash-completion=disabled -Dcheck=enabled -Dcoretracers=disabled -Dgst_debug=true -Dlibdw=disabled -Dtests=enabled -Dtools=enabled -Dtracer_hooks=true -Dlibunwind=disabled -Dc_args=-I/usr/include/imx $ cd build $ ninja install   7. Build gst-plugins-base $ git clone https://github.com/nxp-imx/gst-plugins-base -b lf-6.1.55-2.2.0 $ cd gst-plugins-base $ meson setup build --prefix=/usr -Dalsa=enabled -Dcdparanoia=disabled -Dgl-graphene=disabled -Dgl-jpeg=disabled -Dopus=disabled -Dogg=enabled -Dorc=enabled -Dpango=enabled -Dgl-png=enabled -Dqt5=disabled -Dtheora=enabled -Dtremor=disabled -Dvorbis=enabled -Dlibvisual=disabled -Dx11=disabled -Dxvideo=disabled -Dxshm=disabled -Dc_args=-I/usr/include/imx $ cd build $ ninja install   8. Build gst-plugins-good $ git clone https://github.com/nxp-imx/gst-plugins-good -b lf-6.1.55-2.2.0 $ cd gst-plugins-good $ meson setup build --prefix=/usr -Dexamples=disabled -Dnls=enabled -Ddoc=disabled -Daalib=disabled -Ddirectsound=disabled -Ddv=disabled -Dlibcaca=disabled -Doss=enabled -Doss4=disabled -Dosxaudio=disabled -Dosxvideo=disabled -Dshout2=disabled -Dtwolame=disabled -Dwaveform=disabled -Dasm=disabled -Dbz2=enabled -Dcairo=enabled -Ddv1394=disabled -Dflac=enabled -Dgdk-pixbuf=enabled -Dgtk3=disabled -Dv4l2-gudev=enabled -Djack=disabled -Djpeg=enabled -Dlame=enabled -Dpng=enabled -Dv4l2-libv4l2=disabled -Dmpg123=enabled -Dorc=enabled -Dpulse=enabled -Dqt5=disabled -Drpicamsrc=disabled -Dsoup=enabled -Dspeex=enabled -Dtaglib=enabled -Dv4l2=enabled -Dv4l2-probe=true -Dvpx=disabled -Dwavpack=disabled -Dximagesrc=disabled -Dximagesrc-xshm=disabled -Dximagesrc-xfixes=disabled -Dximagesrc-xdamage=disabled -Dc_args=-I/usr/include/imx $ cd build $ ninja install   9. Build gst-plugins-bad $ git clone https://github.com/nxp-imx/gst-plugins-bad -b lf-6.1.55-2.2.0 $ cd gst-plugins-bad $ meson setup build --prefix=/usr -Dintrospection=enabled -Dexamples=disabled -Dnls=enabled -Dgpl=disabled -Ddoc=disabled -Daes=enabled -Dcodecalpha=enabled -Ddecklink=enabled -Ddvb=enabled -Dfbdev=enabled -Dipcpipeline=enabled -Dshm=enabled -Dtranscode=enabled -Dandroidmedia=disabled -Dapplemedia=disabled -Dasio=disabled -Dbs2b=disabled -Dchromaprint=disabled -Dd3dvideosink=disabled -Dd3d11=disabled -Ddirectsound=disabled -Ddts=disabled -Dfdkaac=disabled -Dflite=disabled -Dgme=disabled -Dgs=disabled -Dgsm=disabled -Diqa=disabled -Dkate=disabled -Dladspa=disabled -Dldac=disabled -Dlv2=disabled -Dmagicleap=disabled -Dmediafoundation=disabled -Dmicrodns=disabled -Dmpeg2enc=disabled -Dmplex=disabled -Dmusepack=disabled -Dnvcodec=disabled -Dopenexr=disabled -Dopenni2=disabled -Dopenaptx=disabled -Dopensles=disabled -Donnx=disabled -Dqroverlay=disabled -Dsoundtouch=disabled -Dspandsp=disabled -Dsvthevcenc=disabled -Dteletext=disabled -Dwasapi=disabled -Dwasapi2=disabled -Dwildmidi=disabled -Dwinks=disabled -Dwinscreencap=disabled -Dwpe=disabled -Dzxing=disabled -Daom=disabled -Dassrender=disabled -Davtp=disabled -Dbluez=enabled -Dbz2=enabled -Dclosedcaption=enabled -Dcurl=enabled -Ddash=enabled -Ddc1394=disabled -Ddirectfb=disabled -Ddtls=disabled -Dfaac=disabled -Dfaad=disabled -Dfluidsynth=disabled -Dgl=enabled -Dhls=enabled -Dkms=enabled -Dcolormanagement=disabled -Dlibde265=disabled -Dcurl-ssh2=disabled -Dmodplug=disabled -Dmsdk=disabled -Dneon=disabled -Dopenal=disabled -Dopencv=disabled -Dopenh264=disabled -Dopenjpeg=disabled -Dopenmpt=disabled -Dhls-crypto=openssl -Dopus=disabled -Dorc=enabled -Dresindvd=disabled -Drsvg=enabled -Drtmp=disabled -Dsbc=enabled -Dsctp=disabled -Dsmoothstreaming=enabled -Dsndfile=enabled -Dsrt=disabled -Dsrtp=disabled -Dtinyalsa=disabled -Dtinycompress=enabled -Dttml=enabled -Duvch264=enabled -Dv4l2codecs=disabled -Dva=disabled -Dvoaacenc=disabled -Dvoamrwbenc=disabled -Dvulkan=disabled -Dwayland=enabled -Dwebp=enabled -Dwebrtc=disabled -Dwebrtcdsp=disabled -Dx11=disabled -Dx265=disabled -Dzbar=disabled -Dc_args=-I/usr/include/imx $ cd build $ ninja install   10. Build imx-gst1.0-plugin $ git clone https://github.com/nxp-imx/imx-gst1.0-plugin -b lf-6.1.55-2.2.0 $ cd imx-gst1.0-plugin $ meson setup build --prefix=/usr -Dplatform=MX8 -Dc_args=-I/usr/include/imx $ cd build $ ninja install   11. Exit chroot $ exit   Verify Installation For verification process, boot your target from the SD Card. (Review your specific target documentation) 1. Verify Weston For this verification you will need to be root user. # export XDG_RUNTIME_DIR=/run/user/0 # weston   2. Verify VPU and Gstreamer Use the following Gstreamer pipeline for Hardware Accelerated VPU Encode. # gst-launch-1.0 videotestsrc ! video/x-raw, format=I420, width=640, height=480 ! vpuenc_h264 ! filesink location=test.mp4   Then you can reproduce the file with this command: # gplay-1.0 test.mp4   Finally, you have installed and verified the GPU, VPU and Multimedia packages. Now, you can start testing audio and video applications.
查看全文
The following steps allow to make use of device tree overlay files, a definition of device tree overlay provided by kernel.org is the next:  "A Devicetree’s overlay purpose is to modify the kernel’s live tree, and have the modification affecting the state of the kernel in a way that is reflecting the changes. Since the kernel mainly deals with devices, any new device node that result in an active device should have it created while if the device node is either disabled or removed all together, the affected device should be deregistered." Knowing that, in this post will be used as an example the baseboard "i.MX 93 EVK" and will be added with device tree overlay an LVDS panel, adding an automatic detection from u-boot, and will be used a host with linux version Ubuntu 20.04.2. Note: It only works for linux kernel version 6.6.3-nanbield onward. Linux device-tree overlay from linux-imx   This section explains all about device tree overlay compilation and building, to create a .dtso file, the equivalent of .dts for overlays, adding some difference between them, using as base the linux-imx repository. It can be downloaded from the following repository:   git clone https://github.com/nxp-imx/linux-imx.git -b <branch version>   Branch version used by this post "lf-6.6.3-1.0.0". Device tree source overlay (.dtso)    It can be similar to a device tree source (.dts) but it had little difference between them, there are some difference in the next list: There's another type of files to be included, if is used pinmux it's necessary adding it with "#include "imx93-pinfunc.h"" and libraries from dt-bindings, it depends on the type of device tree to implement "#include <dt-bindings/<library>>" At initialization it needs to add: "/dts-v1/;"  "/plugin/;" Addition of "fragment" nodes, it allow override parts of a device tree,  it can be a specific node or create a new node. following structure it's the structure of a fragment:   { /* ignored properties by the overlay */ fragment@0 { /* first child node */ target=<phandle>; /* phandle target of the overlay */ or target-path="/path"; /* target path of the overlay */ __overlay__ { property-a; /* add property-a to the target */ node-a { /* add to an existing, or create a node-a */ ... }; }; } fragment@1 { /* second child node */ ... }; /* more fragments follow */ }   kernel.org Overlays can't delete a property or a node when it's applied, so can't be used "/delete-node/" nor "/delete-prop/", but it can be added to the node "status = "disabled";" to disable it.  Using as an example the file imx93-11x11-evk-boe-wxga-lvds-panel.dts located in the previous repository file direction <linux-imx path>/arch/arm64/boot/dts/freescale/ using it as a base tree:   // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright 2022 NXP */ #include "imx93-11x11-evk.dts" / { lvds_backlight: lvds_backlight { compatible = "pwm-backlight"; pwms = <&adp5585pwm 0 100000 0>; enable-gpios = <&adp5585gpio 8 GPIO_ACTIVE_HIGH>; power-supply = <&reg_vdd_12v>; status = "okay"; brightness-levels = < 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>; default-brightness-level = <80>; }; ... }; ... &adv7535 { status = "disabled"; }; ...   imx93-11x11-evk-boe-wxga-lvds-panel.dts Using the previous points and making use of fragments, if we want adapt the node lvds_backlight as fragment, it will be  added in the section of overlay, and adding it to a target-path "/":   #include <dt-bindings/interrupt-controller/irq.h> #include "imx93-pinfunc.h" #include <dt-bindings/gpio/gpio.h> /dts-v1/; /plugin/; / { fragment@0 { target-path = "/"; __overlay__ { lvds_backlight: lvds_backlight { compatible = "pwm-backlight"; pwms = <&adp5585pwm 0 100000 0>; enable-gpios = <&adp5585gpio 8 GPIO_ACTIVE_HIGH>; power-supply = <&reg_vdd_12v>; status = "okay"; brightness-levels = < 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>; default-brightness-level = <80>; }; }; }; ... };   imx93-11x11-evk-test-lvds-panel.dtso In the case of adding a property to an existing node, it will look in the following way using as example the node adv7535.   ... / { ... fragment@2 { target = <&adv7535>; __overlay__ { status = "disabled"; }; }; ... };   imx93-11x11-evk-boe-wxga-lvds-panel.dts At the end of this post, will be attach the complete file used for LVDS panel named as imx93-11x11-evk-test-lvds-panel.dtso Build device tree blob for overlay (dtbo)   To compile the previous .dtso it's necessary to include it to linux-imx repository, linux device tree overlay was included in BSP from version 6.6.3-nanbield onward in Makefile, so it's only necessary adding it as files to be compiled as .dtso, at the end of the post will be a patch file named as linux-imx-makefile.patch to add LVDS-panel to Makefile from branch lf-6.6.3-1.0.0 Add previously file imx93-11x11-evk-test-lvds-panel.dtso to path <linux-imx path>/arch/arm64/boot/dts/freescale/ Add imx93-11x11-evk-test-lvds-panel.dtso as file to be compiled in Makefile, it is located in the next path <linux-imx path>/arch/arm64/boot/dts/freescale/Makefile, it can be added with the next sentence format: <overlay without extension>-dtbs := <file to be overlayed>.dtb <overlay>.dtbo Example of how to add LVDS panel to makefile  imx93-11x11-evk-test-lvds-panel-dtbs := imx93-11x11-evk.dtb imx93-11x11-evk-test-lvds-panel.dtbo Makefile From main path, make the configuration to be compiled with the following bash command: $ cd <linux-imx path>/ $ make -j$(nproc --all) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- imx_v8_defconfig​ Compile overlay to use $ make -j $(nproc --all) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- freescale/<overlay>.dtbo​ as example for LVDS panel $ make -j $(nproc --all) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- freescale/imx93-11x11-evk-test-lvds-panel.dtbo It will compile the device tree blob overlay to use. Copy .dtbo generated in memory used by i.MX 93, it can be sending it from scp. scp ./​<overlay>.dtbo​ root@<ip>:/run/media/<memory section used> u-boot   This section explain the procedure to load a device tree overlay, it will be from u-boot explaining commands used and using the LVDS panel as an example. Before applying overlay   Before applying, it's necessary had a device tree loaded so looking around in the process of booting in a i.MX 93 from u-boot, this process is defined by the enviroment variable "bsp_bootcmd" that calls the variable mmcboot, and looking what does these variables, it can be look in the following sentence:    bsp_bootcmd=echo Running BSP bootcmd ...; mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if test ${sec_boot} = yes; then if run loadcntr; then run mmcboot; else run netboot; fi; else if run loadimage; then run mmcboot; else run netboot; fi; fi; fi; fi; mmcboot=echo Booting from mmc ...; run mmcargs; if test ${sec_boot} = yes; then if run auth_os; then run boot_os; else echo ERR: failed to authenticate; fi; else if test ${boot_fit} = yes || test ${boot_fit} = try; then bootm ${loadaddr}; else if run loadfdt; then run boot_os; else echo WARN: Cannot load the DT; fi; fi;fi;   but reducing it in a normal situation, ignoring if else case and echoes, it can be simplify to:   mmc dev ${mmcdev}; run loadimage; run mmcargs; run loadfdt; run boot_os;   the device tree is load is in the section "run loadfdt" with fatload in his definition:   loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile}   So, it's necessary to applying device tree overlay after "run loadfdt". How to apply an overlay   To load correctly an overlay it's necessary to following some steps: Load flattened device tree (fdt). (executed by loadfdt) Configure fdt address.  In some cases it's necessary to expand fdt memory size Load overlay Apply overlay The full sentence to apply it, it's the following u-boot command:   u-boot=> setexpr fdtovaddr ${fdt_addr} + 0xF0000; setexpr fdt_buffer 16384; fdt addr ${fdt_addr} && fdt resize ${fdt_buffer}; fatload mmc ${mmcdev}:${mmcpart} ${fdtovaddr} <overlay>.dtbo && fdt apply ${fdtovaddr};   First of all, setexpr it's just to create a new variable, in this case these variable is an integer. Spliting the previously command we can found the steps to applying it. "fdt addr ${fdt_addr};" used to configure fdt address, and point to the space of memory previously charged. "fdt resize ${fdt_buffer};" expand fdt memory size, is used as a value 16384 just to get the enough space to charge dtbo, this number was related with 2 14 "fatload mmc ${mmcdev}:${mmcpart} ${fdtovaddr} <overlay>.dtbo" Load device tree overlay using fdovaddr, that is fdt_addr adding an offset of memory space.  "fdt apply ${fdtovaddr};" apply device tree overlay Remembering about load overlay needs to be executed after loadfdt, it's possible to save the previous command to a variable and executing it after loadfdt with setexpr, in this case using as example lvds test.   u-boot=> setenv loadoverlay "setexpr fdtovaddr ${fdt_addr} + 0xF0000; setexpr fdt_buffer 16384; fdt addr $\{fdt_addr\} && fdt resize $\{fdt_buffer\}; fatload mmc $\{mmcdev\}:$\{mmcpart\} $\{fdtovaddr\} imx93-11x11-evk-test-lvds-panel.dtbo && fdt apply $\{fdtovaddr\};"   and modifying mmcboot with loadoverlay after loadfdt   u-boot=> setenv mmcboot "run mmcargs; run loadfdt; run loadoverlay; run boot_os;"   to save the environment variables created, it can be saved from u-boot wit the following command.   u-boot=> saveenv   At the end, boot imx93   u-boot=> boot   The LVDS panel should be working using the original dtb (imx93-11x11-evk.dtb) applied the overlay. Automatize u-boot LVDS Panel   This section explain how can be automatize the u-boot load overlay using an LVDS panel, it can vary depending the device to used for, the method used is detecting it in u-boot initialization and if found any device it will generate an environment variable. All the steps was using as a base uboot-imx repository, it can be downloaded from the following repository, at the end of this post will be a patch with the changes.   git clone https://github.com/nxp-imx/uboot-imx.git -b <branch version>   Branch version used "lf-6.6.3-1.0.0". Base   Knowing more about LVDS Panel used by imx93 it's really hard know more information about registers, so in this example will be limited to detect that is connected the address to a corresponding bus from touch controller.  To know i2c address and bus used by LVDS panel it was used searching it from the original device tree in the next section:   &lpi2c1 { exc80h60: touch@2a { compatible = "eeti,exc80h60"; reg = <0x2a>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ctp_int>; /* * Need to do hardware rework here: * remove R131, short R181 */ interrupt-parent = <&gpio2>; interrupts = <21 IRQ_TYPE_LEVEL_LOW>; reset-gpios = <&pcal6524 17 GPIO_ACTIVE_HIGH>; status = "okay"; }; };   imx93-11x11-evk-boe-wxga-lvds-panel.dts Previous node is related with touch controller from LVDS using lpi2c1, the first channel of i2c corresponding to i2c bus 0, and the register used express the address used to be detected by device tree, in this case was the address 0x2A. u-boot generating a trigger   About how it can be detected touch controller from u-boot, this procedure use a function named as "board_late_init", it can be found by his definition from u-boot readme:   Board initialization settings: ------------------------------ During Initialization u-boot calls a number of board specific functions to allow the preparation of board specific prerequisites, e.g. pin setup before drivers are initialized. To enable these callbacks the following configuration macros have to be defined. Currently this is architecture specific, so please check arch/your_architecture/lib/board.c typically in board_init_f() and board_init_r(). - CONFIG_BOARD_EARLY_INIT_F: Call board_early_init_f() - CONFIG_BOARD_EARLY_INIT_R: Call board_early_init_r() - CONFIG_BOARD_LATE_INIT: Call board_late_init()   u-boot README In the case of i.MX 93 this function can be found in the next path <u-boot path>/board/freescale/imx93_evk/imx93_evk.c. Using the library included, "uclass.h", it will create a function that, if detect in the bus 0 (LVDS i2c bus) the address 0x2A (i2c LVDS address), it will create an environment variable with the overlay used, it can be set with the function env_set(<String with the name of the variable>, <String with the content of the variable>), the following function can detect and create the environment variable mentioned, creating it with the name "device-tree-overlay" with the content "lvds-panel".   #define LVDS_TOUCH_I2C_BUS 0 #define LVDS_TOUCH_I2C_ADDR 0x2A static void detect_display_connected(void) { struct udevice *bus = NULL; struct udevice *i2c_dev = NULL; int ret; ret = uclass_get_device_by_seq(UCLASS_I2C, LVDS_TOUCH_I2C_BUS, &bus); if (ret) { printf("%s: Can't find bus\n", __func__); } else { ret = dm_i2c_probe(bus, LVDS_TOUCH_I2C_ADDR, 0, &i2c_dev); if (ret) { printf("%s: Can't find device id=0x%x\n", __func__, LVDS_TOUCH_I2C_ADDR); } else { env_set("device-tree-overlay", "lvds-panel"); } } }   imx93_evk.c At the end, add this function to the previously mention, named as board_late_init, in the section CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG, like the following snipped from code:   int board_late_init(void) { #ifdef CONFIG_ENV_IS_IN_MMC board_late_mmc_env_init(); #endif env_set("sec_boot", "no"); #ifdef CONFIG_AHAB_BOOT env_set("sec_boot", "yes"); #endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG env_set("board_name", "11X11_EVK"); env_set("board_rev", "iMX93"); detect_display_connected(); #endif return 0; }   imx93_evk.c Now, when it's starting u-boot after flashing, it will generate the environment variable as trigger if something it's connected with that i2c address, else it doesn't do anything. u-boot applying device tree overlay through event   As was explained in the section "How to apply device tree overlay", applying the device tree overlay automatically after configure the trigger it's easy, just adding an if/else case for this example, it can be more ways to applying it, even it's possible adding more of one device tree overlay, but in this example will load one.  Using u-boot command "test -e <environment variable>" it will detect if exist this environment variable, adding it to an if/else sentence it can create the event and applying the overlay if was detected or not, for this solution will be added this if/else as input if exists loadoverlay variable with the following structure:   u-boot=> if test -e ${device-tree-overlay}; then <case exists device-tree-overlay variable> else <case doesn't exists device-tree-overlay variable>; fi;   adding it to loadoverlay, it will be written like the following command:   u-boot=> setenv loadoverlay "if test -e ${device-tree-overlay}; then setexpr fdtovaddr ${fdt_addr} + 0xF0000; setexpr fdt_buffer 16384; fdt addr ${fdt_addr} && fdt resize $\{fdt_buffer\}; fatload mmc ${mmcdev}:${mmcpart} $\{fdtovaddr\} imx93-11x11-evk-test-lvds-panel.dtbo; fdt apply $\{fdtovaddr\} ; else echo no overlay; fi;"   A no recommended method it's that it can be saved the environment, and changing mmcboot variable with the following command:   u-boot=> setenv mmcboot "run mmcargs; run loadfdt; run loadoverlay; run boot_os;"; saveenv;   The problem about just saving it, it still necessary compile u-boot to load auto-detection of LVDS panel and flashing, another way to add the event trigger, it's adding it to u-boot as initial environment variable, it can be added in the header file of imx93, it is located in the next path <u-boot path>/include/configs/imx93_evk.h, line number 60, it can be added with the same string but it's recommended follow the same structure, like the following definition:   /* Initial environment variables */ #define CFG_EXTRA_ENV_SETTINGS \ ... "loadoverlay=echo loading overlays from mmc ...; " \ "if test -e ${device-tree-overlay}; then " \ "setexpr fdtovaddr ${fdt_addr} + 0xF0000; " \ "setexpr fdt_buffer 16384; " \ "fdt addr ${fdt_addr} && fdt resize ${fdt_buffer}; " \ "fatload mmc ${mmcdev}:${mmcpart} ${fdtovaddr} imx93-11x11-evk-test-lvds-panel.dtbo && fdt apply ${fdtovaddr}; " \ "else " \ "echo no overlay; " \ "fi;\0" \ ...   imx93_evk.h it also it's necessary to change mmcboot environment variable adding loadoverlay after executing loadfdt.    /* Initial environment variables */ #define CFG_EXTRA_ENV_SETTINGS \ .. "mmcboot=echo Booting from mmc ...; " \ "run mmcargs; " \ "if test ${sec_boot} = yes; then " \ "if run auth_os; then " \ "run run boot_os; " \ "else " \ "echo ERR: failed to authenticate; " \ "fi; " \ "else " \ "if test ${boot_fit} = yes || test ${boot_fit} = try; then " \ "bootm ${loadaddr}; " \ "else " \ "if run loadfdt; then " \ "run loadoverlay; " \ "run boot_os; " \ "else " \ "echo WARN: Cannot load the DT; " \ "fi; " \ "fi;" \ "fi;\0" \ ...   imx93_evk.h To build u-boot, copy the following commands in main path from u-boot   $ cd <u-boot path> $ make -j $(nproc --all) clean PLAT=imx93 CROSS_COMPILE=aarch64-linux-gnu- $ make -j $(nproc --all) ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- imx93_11x11_evk_defconfig $ make -j $(nproc --all) PLAT=imx93 CROSS_COMPILE=aarch64-linux-gnu-   generating the files u-boot.bin and u-boot-spl.bin located in <uboot-imx path>/ and <uboot-imx path>/spl Build imx-boot image using imx-mkimage   To build the binary necessary to flash to iMX 93 EVK it's necessary build a file named as flash.bin, it can building using the next repository using the branch used for this example:    $ git clone https://github.com/nxp-imx/imx-mkimage.git -b lf-6.6.3_1.0.0   to build imx-boot image it's necessary adding some files to the path <imx-mkimage path>/iMX93, including 2 generated by u-boot, u-boot.bin and u-boot-spl.bin, move these files to iMX93 directory.   $ cp <uboot-imx path>/u-boot.bin <uboot-imx path>/spl/u-boot-spl.bin <imx-mkimage path>/iMX93/   follow the steps from imx linux users guide section 4.5.13 and imx linux release notes section 1.2 to build flash.bin, as an example of compile, there's the steps to compile for imx93. Get mx93a1-ahab-container.img $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-sentinel-0.11.bin $ chmod +x firmware-sentinel-0.11.bin $ ./firmware-sentinel-0.11.bin $ cp firmware-sentinel-0.11/mx93a1-ahab-container.img <imx-mkimage path>/iMX93/​ Get lpddr4_imem_1d_v202201.bin, lpddr4_dmem_2d_v202201.bin, lpddr4_imem_1d_v202201.bin and lpddr4_imem_2d_v202201.bin $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.23.bin $ chmod +x firmware-imx-8.23.bin $ ./firmware-imx-8.23.bin $ cp firmware-imx-8.23/firmware/ddr/synopsys/lpddr4_dmem_1d_v202201.bin firmware-imx-8.23/firmware/ddr/synopsys/lpddr4_dmem_2d_v202201.bin firmware-imx-8.23/firmware/ddr/synopsys/lpddr4_imem_1d_v202201.bin firmware-imx-8.23/firmware/ddr/synopsys/lpddr4_imem_2d_v202201.bin <imx-mkimage path>/iMX93/​ Get bl31.bin $ git clone https://github.com/nxp-imx/imx-atf.git -b lf-6.6.3-1.0.0 $ cd imx-atf $ make -j $(nproc --all) PLAT=imx93 CROSS_COMPILE=aarch64-linux-gnu- $ cp <imx-atf path>/build/imx93/release/bl31.bin <imx-mkimage path>/iMX93​ Compile flash.bin from imx-mkimage $ cd <imx-mkimage path>/ $ make SOC=iMX9 REV=A1 flash_singleboot​ it will generate the binary flash.bin located in the path <imx-mkimage path>/iMX93/flash.bin. Flashing u-boot   Flashing just u-boot image using flash.bin, will be used uuu.exe, it can be downloaded from the his repositroy, try using the most recent version taged as "Latest"    https://github.com/nxp-imx/mfgtools/releases   make sure is using i.MX 93 EVK in boot mode download and connect it to your host from download USB port, using uuu.exe run the next code:   .\uuu.exe -b emmc .\flash.bin   or it can be flashed the full image with flash.bin binary.   .\uuu.exe -b emmc_all .\flash.bin ..\uuu\imx-image-full-imx93evk.wic   after that, starting be will using the created u-boot environment. Result   Inside u-boot, when it's connected the LVDS panel, it will create the variable named "device-tree-overlay" and will be charged automatically LVDS panel overlay, enabling it, if not it will working normally using DSI as output. Note: Ensure to have imx93-11x11-evk-test-lvds-panel.dtbo in memory. Reference   Device tree overlay: https://docs.kernel.org/devicetree/overlay-notes.html  
查看全文
On this tutorial we will review the implementation of Flutter on the i.MX8MP using the Linux Desktop Image. Please find more information about Flutter using the following link: Flutter: Option to create GUIs for Embedded System... - NXP Community Requirements: Evaluation Kit for the i.MX 8M Plus Applications Processor. (i.MX 8M Plus Evaluation Kit | NXP Semiconductors) NXP Desktop Image for i.MX 8M Plus (GitHub - nxp-imx/meta-nxp-desktop at lf-6.1.1-1.0.0-langdale) Note: This tutorial is based on the NXP Desktop Image with Yocto version 6.1.1 – Langdale. Steps: 1. First, run commands to update packages. $ sudo apt update $ sudo apt upgrade 2. Install Flutter for Linux using the following command. $ sudo snap install flutter --classic 3. Run the command to verify the correct installation. $ flutter doctor With this command you will find information about the installation. The important part for our purpose is the parameter "Linux toolchain - develop for Linux desktop". 4. Run the command “flutter create .” to create a flutter project, this framework will create different folders and files used to develop the application.  $ cd Documents $ mkdir flutter_hello $ cd flutter_hello $ flutter create .​ 5. Finally, you can run the “hello world” application using: $ flutter run Verify the program behavior incrementing the number displayed on the window.  
查看全文
This article is now outdated - SCFW 1.16.0 fixes this issue and has now been released. All customers who are experiencing stability issues with the processors outlined below should update to SCFW >1.16.0. ------------------------------------------------------------------------------------------------------------------------------------- The i.MX 8QM and i.MX 8QP has been revised with lower clock speeds and higher core voltages to help improve instability issues found with the part. Old parts that have not been derated have an "FF" moniker in the part number, whereas new parts, releasing in June 2024, have an "FE" moniker. An example can be found below. SCFW (System Controller Firmware) 1.16.0, which will be released with the Q2 Linux Factory BSP (LF6.6.y_2.0.0), will make the necessary changes to increase core voltage for CPU and GPU cores in the 8QM/8QP, as well as reduce clock speeds. It may not be immediately apparent what changes must be made to derate these processors before the new parts and new SCFW version is released. To assist with these issues, we are providing the changes below as a workaround until SCFW 1.16.0 is released.     Recommended Changes until SCFW 1.16.0 is released 1. Increase voltages in pmic_init(). This function is found inside the respective board.c file within the SCFW porting kit. This is assuming that the customer has routed their VDD_A72 to PMIC_0 on SW3 and SW4, and routed their VDD_GPU0 and VDD_GPU1 to PMIC_1 on SW1 through SW4. +/* Set VDD_A72 to 1.1375V (1138mV) */ +BRD_ERR(PMIC_SET_VOLTAGE(PMIC_0_ADDR, PF8100_SW3, 1138, REG_RUN_MODE)) +BRD_ERR(PMIC_SET_VOLTAGE(PMIC_0_ADDR, PF8100_SW4, 1138, REG_RUN_MODE)) +/* Set VDD_GPU0 and VDD_GPU1 to 1.03125V (1032mV) */ +BRD_ERR(PMIC_SET_VOLTAGE(PMIC_1_ADDR, PF8100_SW1, 1032, REG_RUN_MODE)) +BRD_ERR(PMIC_SET_VOLTAGE(PMIC_1_ADDR, PF8100_SW2, 1032, REG_RUN_MODE)) +BRD_ERR(PMIC_SET_VOLTAGE(PMIC_1_ADDR, PF8100_SW3, 1032, REG_RUN_MODE)) +BRD_ERR(PMIC_SET_VOLTAGE(PMIC_1_ADDR, PF8100_SW4, 1032, REG_RUN_MODE))   2. Add +37.5mV offset for VDD_A72, +31.25mV offset for VDD_GPU0/VDD_GPU1. This is done in the function board_set_voltage, found in board.c of the respective processor in the SCFW porting kit. This ensures that voltages are set correctly if a frequency change occurs (like going from overdrive to nominal mode on GPU). /*--------------------------------------------------------------------------*/ /* Set the voltage for the given SS. */ /*--------------------------------------------------------------------------*/ sc_err_t board_set_voltage(sc_sub_t ss, uint32_t new_volt, uint32_t old_volt) { sc_err_t err = SC_ERR_NONE; pmic_id_t pmic_id[2] = {0U, 0U}; uint32_t pmic_reg[2] = {0U, 0U}; uint8_t num_regs = 0U; +// A72 cores are running on 1.1375V instead of 1.10V +if ((ss == SC_SUBSYS_A72) && (new_volt == 1100)) { +board_print(3, "Changing voltage from 1100 to 1138"); +new_volt = 1138; +} +// GPU is running on 1.03125V instead of 1.00V +if ((ss == SC_SUBSYS_GPU_0 || SC_SUBSYS_GPU_1) && (new_volt == 1000)) { +board_print(3, "Changing voltage from 1000 to 1032"); +new_volt = 1032; +} board_print(3, "board_set_voltage(%s, %u, %u)\n", snames[ss], new_volt, old_volt); board_get_pmic_info(ss, pmic_id, pmic_reg, &num_regs);   3. Remove 1.6GHz from Linux DTS OPP Table for A72 core. This is found in the device tree of the board. These are typically found in /arch/arm64/boot/dts/freescale/. /* opp-1596000000 { opp-hz = /bits/ 64 <1596000000>; opp-microvolt = <1100000>; clock-latency-ns = <150000>; opp-suspend; }; */ 4. Disable GPU overdrive mode - set to nominal mode using sysfs in Linux userland echo "nominal" > /sys/bus/platform/drivers/galcore/gpu_govern
查看全文
The HSM Coding-Signing is new. When we follow the instructions in Code-Signing Tool User’s Guide , still has something to overcome, most of them are related to the OS. Actually, Code-Signing Tool User’s Guide  can not give detail every “obvious” step. The purpose of this document is to share the experiences on my system. Hope those experience can give you some clues on your system.     25JUL2024 - add pkcs11 proxy                         HSM Code-Signing Journey_25JUL2024.pdf                          HSM Code-Signing Journey_25JUL2024.txt  
查看全文
i.MX93 eMMC Secondary Boot          i.MX93 eMMC Secondary Boot.zip   i.MX8MP eMMC Secondary Boot           i.MX8MP eMMC Secondary Boot.zip i.MX8MM SDCARD Secondary Boot Demo https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/i-MX8MM-SDCARD-Secondary-Boot-Demo/ta-p/1500011   i.MX8QXP eMMC Secondary Boot https://community.nxp.com/t5/i-MX-Community-Articles/i-MX8QXP-eMMC-Secondary-Boot/ba-p/1257704#M45    i.MX6 SDCARD Secondary Boot Demo           i.MX6_SDCARD_Secondary_Boot_Demo.pdf      
查看全文
1 - Introduction: The Ultra Secured Digital Host Controller (uSDHC) provides the interface between the host processor and the SD/SDIO/MMC cards. Most recent versions provides the ability to automatically select a quantized delay (in fractions of the clock period) regardless of on-chip variations such as process, voltage, and temperature (PVT). The auto tuning is performed during runtime at hardware level, no software enablement is needed to drive this feature. 2 - Failure description: SDIO cards can implement an optional feature that uses DATA[1] to signal the card's interrupt to the i.MX device, this feature can be enabled by the SDIO card device and does not depends on i.MX uSDHC driver configuration. NXP Linux BSP is enabling the auto tuning for high SDIO frequencies (SDR104 and SDR50). Out of reset uSDHC_VEND_SPEC2 register is configured to use DATA[3:0] for calibration, this setup can conflict with the SDIO interrupt as DATA[1] signal can be asserted asynchronously. SDIO failures can be observed when running SDIO applications that requires high usage of the SDIO interface (e.g Download of large files), SDIO controller cannot return an accurate DLL causing failures such as "CMD53 read error". Failure can be observed on i.MX8MM EVK and i.MX8MN EVK boards, both devices are running 88w8987 Wi-Fi chipset at 208Mhz (SDR104). Users can observe an SDIO crash followed by error message below at Linux Kernel level. [ 401.945627] cmd53 read error=-84 [ 401.974677] moal_read_data_sync: read registers failed 3 - Impacted devices: The following devices are impacted by this limitation. - i.MX6 Family:   i.MX6SL, i.MX6SLL, i.MX6SX, i.MX6UL, i.MX6ULZ and i.MX6ULL. - All i.MX7 and i.MX7ULP family:   i.MX7D, i.MX7S and i.MX7ULP. - All i.MX8M Family:   i.MX8MQuad, i.MX8M Mini, i.MX8M Nano, i.MX8M Nano UL and i.MX8M Plus. - All i.MX8/8X Family:   i.MX8DQXP, i.MX8DX and i.MX8QM. NXP Linux BSP is enabling the auto tuning for SDR104 and SDR50 modes. Other operation modes are not impacted by this limitation. Users can poll uSDHCx_CLK_TUNE_CTRL_STATUS register when running SDIO applications to confirm. TAP_SEL_PRE field is updated automatically during run time and constant variations can point to an incorrect delay cell calculated by the uSDHC controller.   All NXP Wi-Fi chipsets are enabling SDIO interrupt during firmware load, failures can be observed with any Wi-Fi vendor enabling SDIO asynchronous interrupt. 4 - Software changes: Recommendation is to enable auto tuning for DATA[0] and CMD signals only, DATA[1] should not be used for auto calibration to avoid a possible conflict with SDIO interrupt. This setup can only be used if SDIO interface length are well matched. Software patches can be found at codeaurora.org. Fix is already included in L5.10.52-2.1.0 BSP, users can add fsl,sdio-interrupt-enabled property to uSDHC device tree node to enable SW workaround. https://github.com/nxp-imx/linux-imx/commit/3b3d6dec05277f7786d813592a31ea4a1ce60a74 https://github.com/nxp-imx/linux-imx/commit/b9b5a43df1d709809b2b654ad8f8181b00a4ee55 https://github.com/nxp-imx/linux-imx/commit/95a846af9f82dc6ea60064d9d12d5d2378e23941      
查看全文
We are pleased to announce that Config Tools for i.MX v16.0 are now available. Downloads & links To download the installer for all platforms, please login to our download site via:  https://www.nxp.com/design/designs/config-tools-for-i-mx-applications-processors:CONFIG-TOOLS-IMX Please refer to  Documentation  for installation and quick start guides. For further information about DDR config and validation, please go to this  blog post. Release Notes Full details on the release (features, known issues...) The product is based on Eclipse 2023-12 Framework – Enable the Peripherals tool in the Config Tools for i.MX – Enable the Clocks tool in the Config Tools for i.MX – A new command-line argument (- UpdateCode) has been added. It performs the same action as the Update Code button in the user interface. It must be used with -HeadlessTool. DDR tool – CA bus driver strength and ODT configuration for the mScale processors are added. – [MX 93/MX 91] The UART configuration from UI is added. – MX 91 DDR tool update for Config tools – MX 93 PF 09 DDR tool support is added. SerDes tool – MX 95 SerDes tool support is enabled. Pins tool – Simultaneous routing detection (routing of one signal may result in multiple signals being routed based on the same register settings) is added. In that case, such signals are offered to be added into the configuration. – Support of internal pins that are not available in the package is added.
查看全文
Hello! In this time, we will look how the i.MX93 GPIOs IRQs works, also I will focus on Cortex M33 side with SDK 2_16_0 but also tested on 2_15.   We can see in this other post, how the i.MX8M family works, but for i.MX93 this is a little different because there are a Secure/Non-Secure options and Privilege/Non-Privilege.   According to reference Manual and SDK LED example, we must to set the PCNS and ICNS registers to 0x00 to set in Secure access.    Materials Used: i.MX93EVK Jumper cable to connect GPIO2_IO02 with GPIO2_IO03 SDK 2_16_0 from MCUXpresso SDK Builder Source power for i.MX93EVK USB C Cable for serial debug USB C Cable to transfer .bin ro EVK   The Cortex-M33 processor supports Secure and Non-secure security states, Thread and Handler operating modes, and can run in either Thumb or Debug operating states. In addition, the processor can limit or exclude access to some resources by executing code in privileged or unprivileged mode. Code can execute as privileged or unprivileged. Unprivileged execution limits or excludes access to some resources appropriate to the current security state. Privileged execution has access to all resources available to the security state. Handler mode is always privileged. Thread mode can be privileged or unprivileged. You can find this information in the ARM documentation.   To resume this post, we will focus just in the necessary registers to configure properly a GPIO as IRQ input.   On this example, we will take the i.MX93EVK board. The GPIO2_IO02 will be configured as an output and the GPIO2_IO03 will be configured as an input with Rising edge IRQ. On each GPIO2_IO02 Rising edge, the software will detect an IRQ.     At first, we need to configure our IOMUX: void BOARD_InitPins(void) { IOMUXC_SetPinMux(IOMUXC_PAD_GPIO_IO02__GPIO2_IO02, 0U); IOMUXC_SetPinMux(IOMUXC_PAD_GPIO_IO03__GPIO2_IO03, 0U); IOMUXC_SetPinMux(IOMUXC_PAD_UART2_RXD__LPUART2_RX, 0U); IOMUXC_SetPinMux(IOMUXC_PAD_UART2_TXD__LPUART2_TX, 0U); IOMUXC_SetPinConfig(IOMUXC_PAD_GPIO_IO02__GPIO2_IO02, IOMUXC_PAD_DSE(15U) | IOMUXC_PAD_FSEL1(2U) | IOMUXC_PAD_PD_MASK); IOMUXC_SetPinConfig(IOMUXC_PAD_GPIO_IO03__GPIO2_IO03, IOMUXC_PAD_PD_MASK); IOMUXC_SetPinConfig(IOMUXC_PAD_UART2_RXD__LPUART2_RX, IOMUXC_PAD_PD_MASK); IOMUXC_SetPinConfig(IOMUXC_PAD_UART2_TXD__LPUART2_TX, IOMUXC_PAD_DSE(15U)); }   Then, we can start to code. Using as an starting point we can use the SDK/boards/mcimx93evk/driver_examples/rgpio/led_output example. Our definitions (PIN_OUT_RGPIO and PIN_IN_RGPIO are the same GPIO2 but it is just for good practice):😞 /******************************************************************************* * Definitions ******************************************************************************/ #define PIN_OUT_RGPIO GPIO2 #define PIN_IN_RGPIO GPIO2 #define PIN_OUT_RGPIO_PIN 2U #define PIN_IN_RGPIO_PIN 3U   Then, our IRQ handler: void Reserved73_IRQHandler(void) { RGPIO_ClearPinsInterruptFlags(PIN_IN_RGPIO, kRGPIO_InterruptOutput0, 1U << PIN_IN_RGPIO_PIN); PRINTF("\r\n IRQ.........\r\n"); SDK_ISR_EXIT_BARRIER; }   Why Reserved73_IRQHandler? That is the correspondent for GPIO2, you can look this on SDK/devices/MIMX9352/gcc in the file called startup_MIMX9352_cm33.S:   Basically, the interruption will clear the IRQ flag and print a little message.   Now, here we have the complete main function, we will break down the most important points. int main(void) { /* Define the init structure for the output pin*/ rgpio_pin_config_t pin_out_config = { kRGPIO_DigitalOutput, 0, }; rgpio_pin_config_t pin_in_config = { kRGPIO_DigitalInput, 0, }; /* Board pin, clock, debug console init */ /* clang-format off */ const clock_root_config_t rgpioClkCfg = { .clockOff = false, .mux = 0, // 24Mhz Mcore root buswake clock .div = 1 }; /* clang-format on */ BOARD_InitBootPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); CLOCK_SetRootClock(EXAMPLE_RGPIO_CLOCK_ROOT, &rgpioClkCfg); CLOCK_EnableClock(EXAMPLE_RGPIO_CLOCK_GATE); CLOCK_EnableClock(kCLOCK_Gpio2); /* Set PCNS register value to 0x0 to prepare the RGPIO initialization */ PIN_OUT_RGPIO->PCNS = 0x0; PIN_IN_RGPIO->ICNS = 0x0; /* Print a note to terminal. */ PRINTF("\r\n RGPIO Driver example\r\n"); PRINTF("\r\n An IRQ will happen each GPIO2_IO02 Rising edge\r\n"); /* Init output PIN GPIO. */ RGPIO_PinInit(PIN_OUT_RGPIO, PIN_OUT_RGPIO_PIN, &pin_out_config); /* Init Input with IRQ Pin GPIO*/ RGPIO_SetPinInterruptConfig(PIN_IN_RGPIO, PIN_IN_RGPIO_PIN, kRGPIO_InterruptOutput0, kRGPIO_InterruptRisingEdge); EnableIRQ(GPIO2_0_IRQn); RGPIO_PinInit(PIN_IN_RGPIO, PIN_IN_RGPIO_PIN, &pin_in_config); while (1) { SDK_DelayAtLeastUs(1000000U, SystemCoreClock); RGPIO_PortToggle(PIN_OUT_RGPIO, 1u << PIN_OUT_RGPIO_PIN); } }   As we can see, we need set the GPIO2 PCNS register to 0x00:   Pin Control Nonsecure (PCNS) Configures secure or nonsecure access protection for each pin. You can write to this register only in the Secure-Privilege state if it is not locked (LOCK[PCNS] = 0).   Also the ICNS register to 0x00.   Interrupt Control Nonsecure (ICNS) Configures secure and nonsecure access protection for each interrupt, or DMA request. You can update this register only in the Secure-Privilege state if it is not locked (LOCK[ICNS] = 0).   Now, we can compile and run the example. On each GPIO2_IO02 Rising edge, the CM33 will detect an IRQ in GPIO2_IO03 (short those pads as showed in the image at first of the post).     I will attach the full .c file.   I hope this information can helps to everyone.   Best regards, --... ...-- Salas.
查看全文
This document is about to build an image by Yocto , and it will disable a function that normal user can’t use command line of “ su ”.
查看全文
The purpose of this document is to provide a guide on how to export new symbols using the Bazel Android server instead of the build_abi.sh script. For a better reference how to build Android i.MX image please look at the next chapter 3 Building the Android Platform for i.MX in the Android User's Guide 1. Compile full AOSP or only kernel Build full AOSP: $ source build/envsetup.sh $ lunch evk_8mp-eng $ ./imx-make.sh -j8  Only build the kernel: $ ./imx-make.sh kernel -j8 2. Generic Kernel Image GKI Development Download GKI outside of android_build (MY_ANDROID). # Make sure MY_ANDROID is set to the android_build folder. $ export MY_ANDROID=`pwd` # mkdir gki && cd gki (Make sure folder gki is not inside of ${MY_ANDROID}) $ repo init -u https://android.googlesource.com/kernel/manifest -b common-android14-6.1 $ repo sync $ cd common 3. Export New Symbols Switch the kernel in this common folder from AOSP to its device, and apply the patches required for your project. In this case Android $ cd common $ git remote add device https://github.com/nxp-imx/linux-imx.git $ git remote update $ git fetch device --tags $ git checkout android-14.0.0_1.2.0 $ cd .. $ ln -s ${MY_ANDROID}/vendor/nxp-opensource/verisilicon_sw_isp_vvcam verisilicon_sw_isp_vvcam $ ln -s ${MY_ANDROID}/vendor/nxp-opensource/nxp-mwifiex nxp-mwifiex $ BUILD_FOR_GKI=yes BUILD_CONFIG=common/build.config.imx $ EXT_MODULES_MAKEFILE="verisilicon_sw_isp_vvcam/vvcam/v4l2/Kbuild" $ EXT_MODULES="nxp-mwifiex/mxm_wifiex/wlan_src" Note: Be sure that your Symbolic Link is pointing to the correct folder Open the Makefile in the following path ../gki/nxp-mwifiex/mxm_wifiex/wlan_src/ and erase some ifreq lines that will generate a No such file or directory error. #Automatically determine Android version from build information to streamline diff --git a/mxm_wifiex/wlan_src/Makefile b/mxm_wifiex/wlan_src/Makefile index 3ec5308..7b6ca47 100644 --- a/mxm_wifiex/wlan_src/Makefile +++ b/mxm_wifiex/wlan_src/Makefile @@ -139,20 +139,7 @@ CONFIG_ANDROID_KERNEL=y ifeq ($(ANDROID_PRODUCT_OUT),1) ccflags-y += -DANDROID_SDK_VERSION=$(ANDROID_SDK_VERSION) else -include $(ANDROID_BUILD_TOP)/build/make/core/build_id.mk -ifeq ($(shell echo "$(BUILD_ID)" | cut -c1),R) - ccflags-y += -DANDROID_SDK_VERSION=30 -else ifeq ($(shell echo "$(BUILD_ID)" | cut -c1),S) - ccflags-y += -DANDROID_SDK_VERSION=31 -else ifeq ($(shell echo "$(BUILD_ID)" | cut -c1),T) - ccflags-y += -DANDROID_SDK_VERSION=33 -else ifeq ($(shell echo "$(BUILD_ID)" | cut -c1),U) - ccflags-y += -DANDROID_SDK_VERSION=34 -else - # Default optimization or actions - ANDROID_SDK_VERSION := 0 - ccflags-y += -DANDROID_SDK_VERSION -endif +ccflags-y += -DANDROID_SDK_VERSION=34 endif endif endif -- Then you could update the symbol list by typing the following command. $ tools/bazel run //common:imx_abi_update_symbol_list After the build process is successful, you should get an output like the image below. Build GKI locally. $ tools/bazel run //common:kernel_aarch64_dist  You could follow the next chapters to update the GKI image to your boot image.
查看全文
Preface With i.MX android, it is often infeasible to directly build an OTA package with a newer android version and apply that OTA package to a device running old version of Android. For example, the OTA package buit with i.MX android-13.0.0_2.0.0 release for evk_8mm cannot be direclty applied on the evk_8mm board running the image built with i.MX android-11.0.0_1.0.0. In this article, the reason why directly cross-version OTA is infeasible in i.mx android is firstly explained. Then what should be takein into consideration and done before cross-version OTA are described.   The way Google update the system for its device Once Google first time releases a device, it is called a "launch device". it has: codename. Take pixel 3a xl as an example, the codename is bonito Android version. For pixel 3a xl, it's Android 9.0 kernel version. For pixel 3a xl, it's 4.9 PRODUCT_SHIPPING_API_LEVEL. For pixel 3a xl, it is set to be 28, the same as the SDK version of that Android version. FCM target level. For pixel 3a xl, it's 3 After the system code is updated to a new version, an OTA package can be built with the lunch target aosp_bonito-user or aosp_bonito-userdebug for pixel 3a xl, let's call the updated device "retrofit device" codename is not changed. its device configuration still can be found in "device/google/bonito/" Android version. it is the version the OTA updated to. Four android versions are supported, here they are android 9, 10, 11, 12, which means pixel 3a xl can at most upgraded to android12. "device/google/bonito/" is introduced in android9, and removed in android13. kernel version. not changed after OTA PRODUCT_SHIPPING_API_LEVEL. Not changed in OTA, so after the OTA, the value of property "ro.product.first_api_level" is different from the SDK version. FCM target level. not changed after OTA. The FCM target level is in the device manifest.xml, corresponds to a specific version of system compatibility.matrix.xml, so HALs provided by this device does not need to have much changes if the FCM target level is not changed. This is the way Google maintains the system for their devices. This is not the way i.MX Android devices are maintained. The way i.MX Android update the system to a new version for maintained device when the code is upaded to a new version for maintained imx devices, all the device are taken as "launch device", so compaired to the previous version, in the new system for the device: the kernel version is changed PRODUCT_SHIPPING_API_LEVEL is changed FCM target level is changed. Physical partitions may also be changed The FCM target level change means there may be some big changes in the HALs provided by this device. The PRODUCT_SHIPPING_API_LEVEL change means quite many code logic based on the property "ro.product.first_api_level" execute in different flow. Fro the partition changes, the OTA package directly build with this updated code often cannot be applied, for example, a new image for the new partition cannot be applied on the board running old system, as it does not have the partition for the image. Things cannot be changed during OTA To make things more clear that why direct cross-version OTA is infeasible, it is necessary to know that there are things cannot be changed during OTA. 1. physical partitions cannot be changed during OTA. related features are: * dynamic partition * gki * boot header version 2. user data on theuserdata partition should not be changed, or data loss may occur during OTA. the related features are: * encryption options encryption options should not be changed, to make new version of android can recognize the data encrypted by the old version of android. For some  fs_mgr encrypt options, the product_shipping_api_level impacts on the final encryption parameters passed to the kernel. take a look at the following code, even with the same fs_mgr encryption option, if the first_api_level is different, the final encryption parameter is different in different android version. android10 system/extras/libfscrypt/fscrypt.cpp if (filenames_encryption_mode == FS_ENCRYPTION_MODE_AES_256_CTS) { // Use legacy padding with our original filenames encryption mode. return FS_POLICY_FLAGS_PAD_4; } else if (filenames_encryption_mode == FS_ENCRYPTION_MODE_ADIANTUM) { // ...snip... return (FS_POLICY_FLAGS_PAD_16 | FS_POLICY_FLAG_DIRECT_KEY); } // ...snip... return FS_POLICY_FLAGS_PAD_16; android11 system/extras/libfscrypt/fscrypt.cpp if (!is_gki && options->version == 1 && options->filenames_mode == FSCRYPT_MODE_AES_256_CTS) { options->flags |= FSCRYPT_POLICY_FLAGS_PAD_4; } else { options->flags |= FSCRYPT_POLICY_FLAGS_PAD_16; } android12 system/extras/libfscrypt/fscrypt.cpp if (first_api_level <= __ANDROID_API_Q__ && options->version == 1 && options->filenames_mode == FSCRYPT_MODE_AES_256_CTS) { options->flags |= FSCRYPT_POLICY_FLAGS_PAD_4; } else { options->flags |= FSCRYPT_POLICY_FLAGS_PAD_16; }  The fscrypt version will also impact the result. If not sepcified, the default "version" would be "v1" if the "product_shipping_api_level <= 29" or the default "version" would be "v2". Some fscrypt functions like "casefold" and "project id" will depend on fscrypt "v2", these functions are enabled by including the "$(call inherit-product, $(SRC_TARGET_DIR)/product/emulated_storage.mk)" in "device/nxp". The "emulated_storage.mk" must not be included if fscrypt "v1" is used.  * the userdata partition filesystem type ext4 (used before i.mx android 13.0.0) f2fs (used from i.mx android 13.0.0) * The filesystem for the emulated storage on the userdata partition sdcardfs fuse 3. The boot control info in misc partition should be able to be recognized before and after OTA related feature is: * bootcontrol HAL 4. The bootargs passed by u-boot to kernel cannot be changed if the bootloader is not updated The related feature is: * bootconfig is used to pass boot args from android12.0.0_1.0.0. used with vendor boot header v4.   it should be known that if dual bootloader of postinstall is used, bootloader can be updated.   For these related features. Google does not implement or change them for a "retrofit device", just imlement for change the features for a "launch device", makes direct cross-version OTA feasible for them, because things cannot be changed during OTA are the same between different android versions. For i.mx android, to implement new features for all maintaied devices, things can be changed during OTA are often changed when update to a new version of android. which makes direct cross-version OTA infeasible.    For the ease of reference, list some feature change history here: * physical partition change history   P9.0.0_2.3.0 10.0.0_1.0.0 10.0.0_2.0.0 11.0.0_1.0.0 12.0.0_1.0.0 12.1.0_1.0.0 13.0.0_1.0.0 14.0.0_1.0.0 bootloader_a/b 4MB 4MB 4MB 4MB 4MB 16MB 16MB 16MB dtbo_a/b 4MB 4MB 4MB 4MB 4MB 4MB 4MB 4MB boot_a/b 48MB 48MB 64MB 64MB 64MB 64MB 64MB 64MB init_boot_a/b - -   -   - 8MB 8MB vendor_boot_a/b - -   64MB 64MB 64MB 64MB 64MB misc 4MB 4MB 4MB 4MB 4MB 4MB 4MB 4MB metadata 2MB 2MB 2MB 2MB 16MB 16MB 64MB 64MB presistdata 1MB 1MB 1MB 1MB 1MB 1MB 1MB 1MB super - - 7168MB 3584MB 4096MB 4096MB 4096MB 4096MB fbmisc 1MB 1MB 1MB 1MB 1MB 1MB 1MB 1MB vbmeta_a/b 1MB 1MB 1mb 1MB 1MB 1MB 1MB 1MB system_a/b 2560MB 1536MB - -   - - - vendor_a/b 256MB 512MB - -   - - - product_a/b - 1792MB - -   - - -   boot_a/b: 48MB → 64MB, Image becames bigger ater enabling some debug options vendor_boot_a/b: boot header v3. Vendor boot and boot header v3 are MUST to enable GKI feature.  init_boot_a/b: The init binary in ramdisk is moved from boot.img to init_boot.img. flash gki image from Google does not impact on the vendor modifications on init.   for the metadata partition: 2MB → 16MB, requirement of vts "-m vts_gsi_boot_test -t MetadataPartition#MinimumSize" 16MB → 64MB, to make the partition be formated as f2fs, 32MB is not enough, 64MB is used. metadata partition was firstly mounted in android11, when enable the user data checkpoint feature * gki feature history Firstly introduced in android11. Some codes are built into modules, put the modules in vendor_boot_a/b partition. vendor_boot_a/b partitions are also firstly introduced in android11 GKI prebuilt binary was integrated from android12   The way to handle cross-version OTA for i.mx android Here are the steps align the partitions within the OTA base code and the OTA target code if the product may be in the development stage, and the OTA base  code can be modified: reserve partitions in OTA base code. for example, OTA from 10 to 11, reserver the vendor_boot partition in android10 partitiont able although there is not vendor_boot.img. change the selinux rules to have update_engine to be able to update this partition. enlarge some partitions in the OTA base code as in the OTA target code. for examples, the bootloader partitions is 16MB in android13. if OTA from android12 to android13 and the android 12 code can be modified, enlarge the bootloader partition to 16MB. as data in userdata and metadata partition is not touched during OTA, modify the mount options of userdata and metadata partitions in OTA target code to be the same as the one in OTA base code. if the product partitions are already shipped, only the OTA target code can be modified:  as data in userdata and metadata partition is not touched during OTA, modify the mount options of userdata and metadata partitions in OTA target code to be the same as the one in the OTA base code. change the partition size to align with the OTA base code partitions like vendor_boot and/or init_boot may need to be removed. remove/change the features related to the removed or changed partitions if dual bootloader is not used: recently in android version update, vendor_boot and init_boot partitions are added, this is related to boot image header version, the images in these partitions are loaded and verified by uboot, so if dual bootloader is not used, uboot code related to these things need to be changed. check the code related to "struct boot_img_hdr" in uboot. the a/b slot metadata format may be changed between the OTA base code and the OTA target code , this a/b slot metadata is accessed by both Android bootctrl HAL and uboot, as dual bootloader is not used, uboot is not upaded, the updated Android bootctrl HAL should also use the same format to access the file. a postinstall mechanism can be used to update the uboot images, but as there is no fallback for the update failure, the risks need to be evaluated. check whether the OTA package can be applied and whether the updated system can boot up an failure example: OTA from android10 to android12, the system fail to boot up because of the PRODUCT_SHIPPING_API_LEVEL/"ro.product.first_api_level" value difference, different encryption options are used for userdata partitions. so the PRODUCT_SHIPPING_API_LEVEL value need to be changed to be the same as the one in the OTA base code. as PRODUCT_SHIPPING_API_LEVEL is changed, the FCM target version and related HALs may also need to be changed, including changes in device manifest.xml and compatibility_matrix.xml. need to check the commit history about what is changed together with the FCM target version change.   For dynamic partitions, there are something to be noticed: OTA from the image without dynamic partitions to use dynamic partitions: Refer to the code in android10.0.0_2.0.0, there is a demonstration to update 10.0.0_1.0.0 to 10.0.0_2.0.0. In 0.0.0_1.0.0, dynamic partition is not enabled. check the variable "TARGET_USE_RETROFIT_DYNAMIC_PARTITION" and related configurations. OTA from dynamic partitions to virtual A/B, for example, OTA from android10 to android11 inherit the file "build/make/target/product/virtual_ab_ota_retrofit.mk" the first time when update from android10 to android11 with OTA, inherit the "build/make/target/product/virtual_ab_ota_retrofit.mk", the BOARD_NXP_DYNAMIC_PARTITIONS_SIZE is set as dynamic paritition is used. the second time, the device is runing android11 with retrofit virtual A/B feature, this time OTA again, but not cross version, inherit "build/make/target/product/virtual_ab_ota.mk" instead, and the BOARD_NXP_DYNAMIC_PARTITIONS_SIZE  can be set as virtual A/B feature is used. Devices that were upgraded to dynamic partitions can’t retrofit virtual A/B. if there are new dynamic partitions in OTA target code, like vendor_dlkm, no additional changes need to be made for it. Then the customers need to do full xTS test to guarantee the quality.  
查看全文