由评测者“华仔stm32”提供。
前面实现了手工用CAN发送数据的测试,下面用C编程来发送数据。
1、新建can.c:
#include #include #include #include #include #include #include #include #include int main(int argc, char const *argv[]) { int s, nbytes; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame[2] = {{0}};
s = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (s == -1){ printf("open can error!"); return -1;
} strcpy(ifr.ifr_name, "can0"); ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex; bind(s , (struct sockaddr *)&addr, sizeof(addr)); //禁用过滤规则,本进程不接收报文,只负责发送 setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
frame[0].can_id = 0x11;
frame[0].can_dlc = 1;
frame[0].data[0] = 0x11;
frame[1].can_id =0x22;
frame[1].can_dlc = 1;
frame[1].data[0] = 0x22; while(1)
{
nbytes = write(s, &frame[0], sizeof(frame[0])); if(nbytes != sizeof(frame[0]))
{ printf("Send Error frame[0]!\n"); break;
} sleep(1);
nbytes = write(s, &frame[1], sizeof(frame[1])); if(nbytes != sizeof(frame[1]))
{ printf("Send Error frame[1]!\n"); break;
} sleep(1);
} close(s); return 0;
}
交叉编译后上传给开发板,打开CAN分析仪。开发板上手工开启can0:
root@myd-y6ull14x14:~# ip link set can0 type can bitrate 500000
root@myd-y6ull14x14:~# ifconfig can0 up
[ 3303.387293] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
运行cat_test_send:
由评测者“华仔stm32”提供。
开发板的外设I2C是常用的外设之一,温湿度传感器、OLED等都是经过i2c的总线驱动,今天驱动常用的OLED ssd1306。
1、硬件接线如下图,J14的19脚为SDA,20脚为SCL:
(备注)手册上有误,手册上写的是i2c2,但是在设备管理器里面是i2c1。
2、在ubuntu上创建ssd1306.c、ssd1306.h、main.c,以及字库。
ssd1306.c:
#include "ssd1306.h" void SSD1306_init(void) { m_font_offset = 2; //I2C init ssd1306_i2c_devfd = open(SSD1306_I2C_DEVFILE, O_RDWR); if(ioctl(ssd1306_i2c_devfd, I2C_SLAVE, SSD1306_I2C_ADDR)<0 ) { printf("SSD1306 ioctl error : %s\r\n", strerror(errno)); } SSD1306_sendCommand(0xAE); //display off SSD1306_sendCommand(0xA6); //Set Normal Display (default) SSD1306_sendCommand(0xAE); //DISPLAYOFF SSD1306_sendCommand(0xD5); //SETDISPLAYCLOCKDIV SSD1306_sendCommand(0x80); // the suggested ratio 0x80 SSD1306_sendCommand(0xA8); //SSD1306_SETMULTIPLEX SSD1306_sendCommand(0x3F); SSD1306_sendCommand(0xD3); //SETDISPLAYOFFSET SSD1306_sendCommand(0x0); //no offset SSD1306_sendCommand(0x40|0x0); //SETSTARTLINE SSD1306_sendCommand(0x8D); //CHARGEPUMP SSD1306_sendCommand(0x14); SSD1306_sendCommand(0x20); //MEMORYMODE SSD1306_sendCommand(0x00); //0x0 act like ks0108 SSD1306_sendCommand(0xA1); //SEGREMAP Mirror screen horizontally (A0) SSD1306_sendCommand(0xC8); //COMSCANDEC Rotate screen vertically (C0) SSD1306_sendCommand(0xDA); //0xDA SSD1306_sendCommand(0x12); //COMSCANDEC SSD1306_sendCommand(0x81); //SETCONTRAST SSD1306_sendCommand(0xCF); // SSD1306_sendCommand(0xd9); //SETPRECHARGE SSD1306_sendCommand(0xF1); SSD1306_sendCommand(0xDB); //SETVCOMDETECT SSD1306_sendCommand(0x40); SSD1306_sendCommand(0xA4); //DISPLAYALLON_RESUME SSD1306_sendCommand(0xA6); //NORMALDISPLAY SSD1306_clearDisplay(); SSD1306_sendCommand(0x2E); //Stop scroll SSD1306_sendCommand(0x20); //Set Memory Addressing Mode SSD1306_sendCommand(0x00); //Set Memory Addressing Mode ab Horizontal addressing mode SSD1306_setFont(font8x8); } void SSD1306_setFont(const uint8_t* font) { m_font = font; m_font_width = pgm_read_byte(&m_font[0]); } void SSD1306_sendCommand(unsigned char command) { uint8_t val[2]; val[0] = SSD1306_Command_Mode; val[1] = command; if( write(ssd1306_i2c_devfd, &val, 2) < 0 ) { printf("I2C write error\n"); } } void SSD1306_setBrightness(unsigned char Brightness) { SSD1306_sendCommand(SSD1306_Set_Brightness_Cmd); SSD1306_sendCommand(Brightness); } void SSD1306_setHorizontalMode() { addressingMode = HORIZONTAL_MODE; SSD1306_sendCommand(0x20); //set addressing mode SSD1306_sendCommand(0x00); //set horizontal addressing mode } void SSD1306_setPageMode() { addressingMode = PAGE_MODE; SSD1306_sendCommand(0x20); //set addressing mode SSD1306_sendCommand(0x02); //set page addressing mode } void SSD1306_setTextXY(unsigned char row, unsigned char col) { SSD1306_sendCommand(0xB0 + row); //set page address SSD1306_sendCommand(0x00 + (m_font_width*col & 0x0F)); //set column lower addr SSD1306_sendCommand(0x10 + ((m_font_width*col>>4)&0x0F)); //set column higher addr } void SSD1306_clearDisplay() { unsigned char i,j; SSD1306_sendCommand(SSD1306_Display_Off_Cmd); //display off for(j=0;j<8;j++) { SSD1306_setTextXY(j,0); { for(i=0;i<16;i++) //clear all columns { SSD1306_putChar(' '); } } } SSD1306_sendCommand(SSD1306_Display_On_Cmd); //display on SSD1306_setTextXY(0,0); } void SSD1306_sendData(unsigned char Data) { uint8_t val[2]; val[0] = SSD1306_Data_Mode; val[1] = Data; if( write(ssd1306_i2c_devfd, &val, 2) < 0 ) { printf("I2C write error\n"); } } int SSD1306_putChar(unsigned char ch) { if (!m_font) return 0; //Ignore non-printable ASCII characters. This can be modified for //multilingual font. if(ch < 32 || ch > 127) { ch = ' '; } unsigned char i = 0; for(i=0;i0) { char_buffer[i++] = long_num % 10; long_num /= 10; } f=f+i; for(; i > 0; i--) { SSD1306_putChar('0'+ char_buffer[i - 1]); } return f; } unsigned char SSD1306_putFloat(float floatNumber,unsigned char decimal) { unsigned int temp=0; float decy=0.0; float rounding = 0.5; unsigned char f=0; if(floatNumber<0.0) { SSD1306_putString("-"); floatNumber = -floatNumber; f +=1; } unsigned char i=0; for (i=0; i 0) { SSD1306_putChar('.'); f +=1; } decy = floatNumber-temp;//decimal part, for(i=0;i
ssd1306.h:
#ifndef SSD1306_H #define SSD1306_H #define pgm_read_byte(addr) (*(unsigned char *)(addr)) #define OLEDFONT(name) static const uint8_t name[] #include#include #include #include #include #include #include "font8x8.h" #include "font5x7.h" #define SSD1306_Max_X 127 //128 Pixels #define SSD1306_Max_Y 63 //64 Pixels #define PAGE_MODE 01 #define HORIZONTAL_MODE 02 #define SSD1306_Address 0x3C #define SSD1306_Command_Mode 0x00//0x80 #define SSD1306_Data_Mode 0x40 #define SSD1306_Display_Off_Cmd 0xAE #define SSD1306_Display_On_Cmd 0xAF #define SSD1306_Normal_Display_Cmd 0xA6 #define SSD1306_Inverse_Display_Cmd 0xA7 #define SSD1306_Activate_Scroll_Cmd 0x2F #define SSD1306_Dectivate_Scroll_Cmd 0x2E #define SSD1306_Set_Brightness_Cmd 0x81 #define Scroll_Left 0x00 #define Scroll_Right 0x01 #define Scroll_2Frames 0x7 #define Scroll_3Frames 0x4 #define Scroll_4Frames 0x5 #define Scroll_5Frames 0x0 #define Scroll_25Frames 0x6 #define Scroll_64Frames 0x1 #define Scroll_128Frames 0x2 #define Scroll_256Frames 0x3 /////////////////////////////////////////// // modify this for platform-compatibility // I2C device args /////////////////////////////////////////// #define SSD1306_I2C_DEVFILE "/dev/i2c-1" // Raspberry Pi (Pin 3 5) //#define SSD1306_I2C_DEVFILE "/dev/i2c-0" // Galileo Gen1 #define SSD1306_I2C_ADDR 0x3c // ==(SSD1306_Address) static int ssd1306_i2c_devfd = 0; const uint8_t* m_font; // Current font. static uint8_t m_font_offset = 2; // Font bytes for meta data. static uint8_t m_font_width; // Font witdth. static uint8_t m_col; // Cursor column. static uint8_t m_row; // Cursor row (RAM). static char addressingMode; void SSD1306_init(void); void SSD1306_setNormalDisplay(); void SSD1306_setInverseDisplay(); // modified void SSD1306_sendCommand(unsigned char command); void SSD1306_sendData(unsigned char Data); void SSD1306_setPageMode(); void SSD1306_setHorizontalMode(); void SSD1306_setTextXY(unsigned char Row, unsigned char Column); void SSD1306_clearDisplay(); void SSD1306_setBrightness(unsigned char Brightness); int SSD1306_putChar(unsigned char c); void SSD1306_putString(const char *string); unsigned char SSD1306_putNumber(long n); unsigned char SSD1306_putFloat(float floatNumber,unsigned char decimal); void SSD1306_drawBitmap(unsigned char *bitmaparray,int bytes); void SSD1306_setHorizontalScrollProperties( int direction, unsigned char startPage, unsigned char endPage, unsigned char scrollSpeed); void SSD1306_activateScroll(); void SSD1306_deactivateScroll(); void SSD1306_setFont(const uint8_t* font); #endif
字库:
#ifndef FONT8x8_H
#define FONT8x8_H // 8x8 Font ASCII 32 - 127 Implemented // Users can modify this to support more characters (glyphs) OLEDFONT(font8x8) = { 0x08, // width 0x08, // height 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //0x00,0x00,0x00,0x00,0x5F,0x00,0x00,0x00, // ! 0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00, // " 0x00,0x24,0x7E,0x24,0x24,0x7E,0x24,0x00, // # 0x00,0x2E,0x2A,0x7F,0x2A,0x3A,0x00,0x00, // $ 0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00, // % 0x00,0x20,0x54,0x4A,0x54,0x20,0x50,0x00, // & 0x00,0x00,0x00,0x04,0x02,0x00,0x00,0x00, // ' 0x00,0x00,0x00,0x3C,0x42,0x00,0x00,0x00, // ( 0x00,0x00,0x00,0x42,0x3C,0x00,0x00,0x00, // ) 0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00, // * 0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00, // + 0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00, // , 0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // - 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // . 0x00,0x40,0x20,0x10,0x08,0x04,0x00,0x00, // / 0x3C,0x62,0x52,0x4A,0x46,0x3C,0x00,0x00, // 0 0x44,0x42,0x7E,0x40,0x40,0x00,0x00,0x00, // 1 0x64,0x52,0x52,0x52,0x52,0x4C,0x00,0x00, // 2 0x24,0x42,0x42,0x4A,0x4A,0x34,0x00,0x00, // 3 0x30,0x28,0x24,0x7E,0x20,0x20,0x00,0x00, // 4 0x2E,0x4A,0x4A,0x4A,0x4A,0x32,0x00,0x00, // 5 0x3C,0x4A,0x4A,0x4A,0x4A,0x30,0x00,0x00, // 6 0x02,0x02,0x62,0x12,0x0A,0x06,0x00,0x00, // 7 0x34,0x4A,0x4A,0x4A,0x4A,0x34,0x00,0x00, // 8 0x0C,0x52,0x52,0x52,0x52,0x3C,0x00,0x00, // 9 0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00, // : 0x00,0x00,0x80,0x64,0x00,0x00,0x00,0x00, // ; 0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00, // < 0x00,0x28,0x28,0x28,0x28,0x28,0x00,0x00, // = 0x00,0x00,0x44,0x28,0x10,0x00,0x00,0x00, // > 0x00,0x04,0x02,0x02,0x52,0x0A,0x04,0x00, // ? 0x00,0x3C,0x42,0x5A,0x56,0x5A,0x1C,0x00, // @ 0x7C,0x12,0x12,0x12,0x12,0x7C,0x00,0x00, // A 0x7E,0x4A,0x4A,0x4A,0x4A,0x34,0x00,0x00, // B 0x3C,0x42,0x42,0x42,0x42,0x24,0x00,0x00, // C 0x7E,0x42,0x42,0x42,0x24,0x18,0x00,0x00, // D 0x7E,0x4A,0x4A,0x4A,0x4A,0x42,0x00,0x00, // E 0x7E,0x0A,0x0A,0x0A,0x0A,0x02,0x00,0x00, // F 0x3C,0x42,0x42,0x52,0x52,0x34,0x00,0x00, // G 0x7E,0x08,0x08,0x08,0x08,0x7E,0x00,0x00, // H 0x00,0x42,0x42,0x7E,0x42,0x42,0x00,0x00, // I 0x30,0x40,0x40,0x40,0x40,0x3E,0x00,0x00, // J 0x7E,0x08,0x08,0x14,0x22,0x40,0x00,0x00, // K 0x7E,0x40,0x40,0x40,0x40,0x40,0x00,0x00, // L 0x7E,0x04,0x08,0x08,0x04,0x7E,0x00,0x00, // M 0x7E,0x04,0x08,0x10,0x20,0x7E,0x00,0x00, // N 0x3C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // O 0x7E,0x12,0x12,0x12,0x12,0x0C,0x00,0x00, // P 0x3C,0x42,0x52,0x62,0x42,0x3C,0x00,0x00, // Q 0x7E,0x12,0x12,0x12,0x32,0x4C,0x00,0x00, // R 0x24,0x4A,0x4A,0x4A,0x4A,0x30,0x00,0x00, // S 0x02,0x02,0x02,0x7E,0x02,0x02,0x02,0x00, // T 0x3E,0x40,0x40,0x40,0x40,0x3E,0x00,0x00, // U 0x1E,0x20,0x40,0x40,0x20,0x1E,0x00,0x00, // V 0x3E,0x40,0x20,0x20,0x40,0x3E,0x00,0x00, // W 0x42,0x24,0x18,0x18,0x24,0x42,0x00,0x00, // X 0x02,0x04,0x08,0x70,0x08,0x04,0x02,0x00, // Y 0x42,0x62,0x52,0x4A,0x46,0x42,0x00,0x00, // Z 0x00,0x00,0x7E,0x42,0x42,0x00,0x00,0x00, // [ 0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00, // 0x00,0x00,0x42,0x42,0x7E,0x00,0x00,0x00, // ] 0x00,0x08,0x04,0x7E,0x04,0x08,0x00,0x00, // ^ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, // _ 0x3C,0x42,0x99,0xA5,0xA5,0x81,0x42,0x3C, // ` 0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00, // a 0x00,0x7E,0x48,0x48,0x48,0x30,0x00,0x00, // b 0x00,0x00,0x38,0x44,0x44,0x44,0x00,0x00, // c 0x00,0x30,0x48,0x48,0x48,0x7E,0x00,0x00, // d 0x00,0x38,0x54,0x54,0x54,0x48,0x00,0x00, // e 0x00,0x00,0x00,0x7C,0x0A,0x02,0x00,0x00, // f 0x00,0x18,0xA4,0xA4,0xA4,0xA4,0x7C,0x00, // g 0x00,0x7E,0x08,0x08,0x08,0x70,0x00,0x00, // h 0x00,0x00,0x00,0x48,0x7A,0x40,0x00,0x00, // i 0x00,0x00,0x40,0x80,0x80,0x7A,0x00,0x00, // j 0x00,0x7E,0x18,0x24,0x40,0x00,0x00,0x00, // k 0x00,0x00,0x00,0x3E,0x40,0x40,0x00,0x00, // l 0x00,0x7C,0x04,0x78,0x04,0x78,0x00,0x00, // m 0x00,0x7C,0x04,0x04,0x04,0x78,0x00,0x00, // n 0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00, // o 0x00,0xFC,0x24,0x24,0x24,0x18,0x00,0x00, // p 0x00,0x18,0x24,0x24,0x24,0xFC,0x80,0x00, // q 0x00,0x00,0x78,0x04,0x04,0x04,0x00,0x00, // r 0x00,0x48,0x54,0x54,0x54,0x20,0x00,0x00, // s 0x00,0x00,0x04,0x3E,0x44,0x40,0x00,0x00, // t 0x00,0x3C,0x40,0x40,0x40,0x3C,0x00,0x00, // u 0x00,0x0C,0x30,0x40,0x30,0x0C,0x00,0x00, // v 0x00,0x3C,0x40,0x38,0x40,0x3C,0x00,0x00, // w 0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00, // x 0x00,0x1C,0xA0,0xA0,0xA0,0x7C,0x00,0x00, // y 0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00, // z 0x00,0x08,0x08,0x76,0x42,0x42,0x00,0x00, // { 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // | 0x00,0x42,0x42,0x76,0x08,0x08,0x00,0x00, // } 0x00,0x00,0x04,0x02,0x04,0x02,0x00,0x00, // ~ }; #endif
main.c:
#include "ssd1306.h"
int main() { SSD1306_init(); SSD1306_clearDisplay(); SSD1306_setBrightness(255); SSD1306_setPageMode(); SSD1306_setTextXY(0,0); SSD1306_putString("HELLO MYD-Y6ULX!"); SSD1306_setTextXY(1,0); SSD1306_putString("SSD1306 DEMO"); SSD1306_setTextXY(2,0); SSD1306_putString("2022-11-07"); close(ssd1306_i2c_devfd); return 0; }
makefile:
vpath %.c src #查找依赖时如果遇到%.c,则自动到src目录下寻找
D_SRC = src CC=arm-linux-gnueabihf-gcc D_INC = -I./inc D_OBJ = obj D_MK = build TATGET = ssd1306test SRC_C = $(foreach dir, $(D_SRC), $(wildcard $(dir)/*.c)) OBJ_C = $(addprefix $(D_OBJ)/,$(patsubst %.c,%.o,$(notdir $(SRC_C)))) $(TATGET):$(OBJ_C) $(CC) -o $(D_MK)/$@ $^ $(D_OBJ)/%.o:%.c #自动去src目录下找.c结尾的文件。 $(CC) -c -Wall $(D_INC) $< -o $@ .PHONY: clean clean: rm -f $(D_OBJ)/* $(TATGET) $(D_MK)/*
编译后上传给开发板,执行后就顺利驱动了OLED ssd1306了。
由评测者“华仔stm32”提供。
1、采用 Linux 系统常用的 cansend、candump 命令进行 SocketCAN 的通讯测试。这里测试使用的两块开发板对接测试。
将开发的J10 座子的 CANH、CANL 引脚和CAN分析仪的CANH、CANL 相连,如下图:
root@myd-y6ull14x14:~# ip link set can0 type can bitrate 500000 triple-sampling on
root@myd-y6ull14x14:~# ifconfig can0 up
5、开发板发送数据,CAN分析仪成功收到数据:
root@myd-y6ull14x14:~# cansend can0 100#01.02.03.04.05.06.07.08
6、开发板CAN设置为接收模式:
root@myd-y6ull14x14:~# candump can0
7、CAN分析仪发送数据,不管是标准,还是扩展开发板成功接收到:
MYD-Y6ULX-V2 标配CAN总线,在工控方面那是相当的专业!
由评测者“华仔stm32”提供。
由于开机自动设置的IP地址跟本地IP不在一个网段上,同时也方便虚拟机的连接设置,因此,需要要设置给它一个静态的 ip,不因 MAC 地址的改变而改变,设置固定 ip 方法调试。开发板启动时会自动获取 ip,最简单的方法是直接设置一个 ip 给它。这样我们就可以直接使用这个 ip 了。
【方法】修改/etc/rc.local文件如下:
保存后重启,就可以固定为设置的地址了:
由评测者“mameng”提供。
MYC-J1028X核心板尺寸82*45mm,基于NXP LS1028A处理器,板卡采用12层高密度PCB设计,沉金工艺生产,独立的接地信号层,无铅。核心板和底板采用314PIN MXM3.0金手指连接器连接,性价比高。Layerscape® LS1028A系列工业应用处理器专为实现工业物联网而设计,它集成了 3D图像功能、支持TSN的以太网、高性能PCIe® Gen 3.0 接口。4
CPU的频率调节模式:
1. Performance. 不考虑耗电,只用最高频率。
2. Interactive. 直接上最高频率,然后看CPU负荷慢慢降低。
3. Powersave. 通常以最低频率运行,流畅度会受影响,一般不会用这个吧!
4. Userspace. 可以在用户空间手动调节频率。
5. Ondemand. 定期检查负载,根据负载来调节频率。
开发板通过串口登录系统:
查看MYC-J1028X 开发板设置CPU调频策略指令:
root@forlinx:/# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling默认情况下开发板启动后CPU调频策略为ondemand。
root@localhost:/sys/devices/system/cpu/cpufreq# lscpu Architecture: aarch64 Byte Order: Little Endian CPU(s): 2 On-line CPU(s) list: 0,1 Thread(s) per core: 1 Core(s) per socket: 2 Socket(s): 1 NUMA node(s): 1 Vendor ID: ARM Model: 3 Model name: Cortex-A72 Stepping: r0p3 CPU max MHz: 1500.0000 CPU min MHz: 300.0000 BogoMIPS: 50.00 L1d cache: unknown size L1i cache: unknown size L2 cache: unknown size NUMA node0 CPU(s): 0,1 Flags: fp asimd evtstrm crc32 cpuid如果想使用其它策略,以高性能模式为例,返回根目率,可以进行如下设置,root@forlinx:/# systemctl disable ondemand.service
由评测者“华仔stm32”提供。
利用网络获取天气预报,先要找到api,我这里在网上找到了一个链接。
新建weather.py文件,内容如下:
# 导入json、requests包 import json import requests # 请求天气信息 weather_url = "http://www.tianqiapi.com/api?version=v6&appid=23035354&appsecret=8YvlPNrz" response = requests.get(weather_url) try: response.raise_for_status() except response.HTTPError: print("请求信息出错") # 将json文件格式导入成python的格式 response.encoding = response.apparent_encoding weather_data = json.loads(response.text) print("地点:%s" % weather_data["city"]) print("日期:" + weather_data["date"]) print("\t温度:" + weather_data["tem"]) print("\t天气:" + weather_data["wea"] + "\n")
这里需要安装requests模块,pip3 install 是安装不了的,需要这样安装:
pip3 install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com requests
安装好模块后,执行python3 weather.py。效果如下:
root@myd-y6ull14x14:~# python3 weather.py 地点:桂林 日期:2022-12-04 温度:7 天气:多云
由评测者“华仔stm32”提供。
在开发调试阶段,烧写固件是很麻烦的事,这里linux的uboot提供了网络启动的功能,从网络服务器里把zImage、设备树.dtb读入到指定的内存地址,来实现不用频繁的烧写固件。
一、ubnutu服务器上创建tfptp服务。
1、需要在 Ubuntu 上搭建 TFTP 服务器,需要安装 tftp-hpa 和 tftpd-hpa,命令如下:
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd
2、创建用于存文件的文件夹,我这里创在如下目录:
developer@EASY-EAI-Develop:~/linux/tftpboot$ pwd /home/developer/linux/tftpboot
3、给这个目录改写权限
chomd 777 /home/developer/linux/tftpboot
4、打开/etc/default/tftpd-hpa 文件,将其修改为如下所示内容:
# /etc/default/tftpd-hpa TFTP_USERNAME="tftp" TFTP_DIRECTORY="/home/developer/linux/tftpboot" #这里指定存放文件夹的绝对目录 TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="--secure -l -c -s"
5、新建文件/etc/xinetd.d/tftp,如果没有/etc/xinetd.d 目录的话自行创建,然后在里面输入如下内容:
developer@EASY-EAI-Develop:~/linux/tftpboot$ cat /etc/xinetd.d/tftp service tftp { disable = no 138 socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /tftpboot -c per_source = 11 cps = 100 2 }
6、重新服务
sudo /etc/init.d/xinetd reload
sudo /etc/init.d/xinetd restart
sudo service tftp-hpa restart
这样tftp服务端就建好了,把需要下载的镜像与设备树拷到这里目录里,最好也给予读取的权限:
developer@EASY-EAI-Develop:~/linux/tftpboot$ ls
myd-y6ull-emmc.dtb zImage```
二、配置uboot
1、开发板重启,按回军键,进入uboot:
U-Boot 2020.04-5.10.9-1.0.0+g25276d37 (Aug 23 2022 - 02:44:07 +0000) CPU: i.MX6ULL rev1.1 528 MHz (running at 396 MHz) CPU: Industrial temperature grade (-40C to 105C) at 39C Reset cause: POR Model: Freescale i.MX6 ULL 14x14 EVK Board Board: MX6ULL 14x14 EVK DRAM: 512 MiB board_init ok MMC: FSL_SDHC: 0, FSL_SDHC: 1 Loading Environment from MMC... OK Display: MYIR-LCD-7-800x480 (800x480) Video: 800x480x16 In: serial Out: serial Err: serial switch to partitions #0, OK mmc1(part 0) is current device flash target is MMC:1 Net: Warning: ethernet@02188000 (eth0) using random MAC address - fe:42:30:04:1b:ea eth0: ethernet@02188000 [PRIME] Fastboot: Normal Normal Boot Hit any key to stop autoboot: 0 =>
2、设置ip地址,服务端ip地址:
=> setenv ipaddr 192.168.3.182 => setenv serverip 192.168.3.186 => saveenv
注意,网络地址环境变量的设置要根据自己的实际情况,确保 Ubuntu 主机和开发板的 IP地址在同一个网段内,比如我现在的开发板和电脑都在 192.168.3.0 这个网段内,所以设置开发板的 IP 地址为 192.168.3.181,我的 Ubuntu 主机的地址为 192.168.3.186,因此 serverip 就是192.168.3.186。ethaddr 为网络 MAC 地址,是一个 48bit 的地址,如果在同一个网段内有多个开发板的话一定要保证每个开发板的 ethaddr 是不同的,否则通信会有问题!设置好网络相关的环境变量以后就可以使用网络相关命令了。(我这里的好象mac、gatewayip不用设也可以)
3、把网线插入ETH1。
4、下载zImage、myd-y6ull-emmc.dtb
=> tftp 80800000 zImage ethernet@02188000 Waiting for PHY auto negotiation to complete.... done Using ethernet@02188000 device TFTP from server 192.168.3.186; our IP address is 192.168.3.182 Filename 'zImage'. Load address: 0x80800000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ############################################## 1 MiB/s done Bytes transferred = 9249832 (8d2428 hex) => tftp 83000000 myd-y6ull-emmc.dtb Using ethernet@02188000 device TFTP from server 192.168.3.186; our IP address is 192.168.3.182 Filename 'myd-y6ull-emmc.dtb'. Load address: 0x83000000 Loading: ### 2.8 MiB/s done Bytes transferred = 35213 (898d hex) =>
5、然后用bootz启动 (注意 两个地址之间要打一个空格键,我没有打,弄了好久才好):
=>bootz 80800000 - 83000000
这样系统就启动起来了:
由评测者“ALSET”提供。
完美体育·(中国)手机网页版的MYD-Y6ULX-V2开发板,是完美体育·(中国)手机网页版的经典王牌产品。作为一款嵌入式linux入门级的开发板,在测试C++程序的时候发现,有的程序在板上运行,表现为程序启动后无反应。查看日志信息也没有错误信息,经过检查后发现是开发板的运行环境和SDK不一致所致。
由评测者“ALSET”提供。
电子发烧友网推出了一款完美体育·(中国)手机网页版的产品:MYD-Y6ULX-V2开发板,该开发板被完美体育·(中国)手机网页版称之为经典王牌产品。是一款嵌入式linux入门级的开发板,说入门级是因为其性能在众多的板子里面已经不是很优秀了,但是其板子的硬件基础和系统都非常经典规范和之前的ARM开发具有很好的继承性,它的开发资源非常丰富,文档也非常细致,很适合初学者入门学习。能够通过该开发板快速的掌握嵌入式ARM Linux上的开发。
一、相关技术文档资料
二、开发主机环境准备
三、安装开发工具包
由评测者“华仔stm32”提供。
挂载SATA硬盘时,看了一下我的开发板的硬盘,只剩下1.2G了,所以就想起挂载nfs网络文件系统,这样就不会出现硬盘空间不足了。
网络文件系统,常被称为NFS(Network File System),它是一种非常便 捷的在服务器与客户端通过网络共享文件的方式,具体见下图。
我们常常通过NFS给开发板共享开发主机编写的应 用程序,在本节内容将介绍如何在开发板和开发主机之间共享目录。我们要构 建的使用NFS文件系统的实验环境架构如下图所示。
在这样的环境中,开发板与开发主机接入到同一个局域网中,然后开发主机 提供NFS服务,开发板通过NFS与开发主机连接共享文件。开发主机生成的目标板应 用程序放在NFS的共享文件夹内,开发板访问该文件夹执行应用程序进行测试。
如何利用NFS搭建NFS环境。主要包含连接网络、主机开启NFS服务 以及开发板挂载文件系统三个步骤。
在虚拟机上创建共享目录:/home/developer/linux/nfs
开发板的挂载目录:/mnt
Ubuntu系统默认没有安装NFS服务,需要使用如下命令安装NFS服务端软件:
#以下命令在主机上运行 sudo apt install nfs-kernel-server
安装NFS服务后,会新增一个/etc/exports文件(即/etc目录下名字为exports的文件),NFS服务根 据它的配置来运行,其默认内容可通过命令cat /etc/exports查看,它默认包含了一些配置 的范例,内容如所示。
在/etc/exports文件末尾添加如下语句并保存, 注意如下语句写到/etc/exports文件是在同一行 "/home/developer/linux/nfs"为主机共享目录的绝对地址
/home/developer/linux/nfs *(rw,sync,no_root_squash)
修改完/etc/exports文件并保存后,可使用exportfs命令更新配置:
#以下命令在主机上运行 sudo exportfs -arv
该命令的参数说明如下:
若配置正常,该命令执行后会列出共享的目录项,本示例的执行结果见下图。
使用showmount –e 可查看当前NFS服务器的加载情况,具体见下图。
#以下命令在主机上运行 developer@EASY-EAI-Develop:~/linux/nfs$ showmount -e Export list for EASY-EAI-Develop: /home/developer/linux/nfs *
开发板上的固件已经安装好了nfs客户端了。如果没有,则sudo apt install nfs-common -y就可以
在开发板上执行“showmount -e +“NFS服务器IP””命令。注意在不同网络环境下,NFS服务器IP可能不一样,以实际情况为准。
root@myd-y6ull14x14:~# showmount -e 192.168.3.186 Export list for 192.168.3.186: /home/developer/linux/nfs *
临时挂载NFS文件系统
使用mount命令挂载NFS服务器的共享目录到开发板/mnt目录下:
注意:需要把下面的192.168.3.186设置为用户实际网络环境下的NFS服务器IP
#以下命令在开发板上运行 /mntmyd-y6ull14x14:~# sudo mount -t nfs 192.168.3.186:/home/developer/linux/nfs
以上命令使用的各个参数如下:
若挂载成功,终端不会有输出,Linux的哲学思想是“没有消息便是好消息
root@myd-y6ull14x14:~# cd /mnt root@myd-y6ull14x14:/mnt# ls root@myd-y6ull14x14:/mnt# sudo touch test.txt root@myd-y6ull14x14:/mnt# ls test.txt
developer@EASY-EAI-Develop:~/linux/nfs$ ls test.txt
当客户机在网络上无法找到NFS共享的目录时,如开发主机关机时,在NFS的客户机 的终端常常会输出一些提示,或在使用ls命令查看共享目录会导致长时间等待,这时可以对目录使用umount命令取消挂载,示例如下:
#以下命令在开发板上运行 sudo umount /mnt ```使用该命令时以要取消挂载的目录作为参数即可,没有输出表示执行正常。如果 在当前挂载的目录进行umount操作,会提示“device is busy”。建议取消挂 载时,先切换到家目录“~”,在进行umount操作。
最后感谢野火、原子哥的网站提供详细的教程。