鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)

这篇具有很好参考价值的文章主要介绍了鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、简介

        在网络编程的时候,不管是客户端还是服务端,都离不开Socket。那什么是Socket,这里做个简单介绍。详细的内容,可以参考这篇文章:WIFI学习一(socket介绍)_wifi socket_t_guest的博客-CSDN博客

         socket在计算机领域,被翻译为“套接字”。它是计算机之间进行通信的一种约定一种方式,通过这种方式,一台计算机可以接收或向另外一台计算机收发数据。

        socket是基于“打开open –> 读写write/read –> 关闭close”模式来设计的。socket可以看做是一种特殊的文件,通过一下socket函数来实现打开关闭读/写IO

        socket客户端编程的总体流程可以归结为以下步骤,初始化socket连接服务器(connect)读/写(write/read)关闭(close)

鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)

 二、API介绍

      socket

        函数功能:

        创建一个socket描述符,用来唯一标识一个socket。后续需要通过该描述符进行读写操作

        函数原型:

int socket(int domain, int type, int protocol)

        参数:

        domain:IP地址类型。常用的类型有AF_INET(IPV4)、AF_INET6(IPV6)。

        type:数据传输方式/套接字类型。常用的类型有SOCK_STREAM(流格式套接字/面向连接的套接字 TCPSOCK_DGRAM(数据报套接字/无连接的套接字 UDP

鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)

        protocol:传输协议。 默认为0,系统自动推演使用的协议。也可以手动输入,常用的协议有,IPPROTO_TCPIPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。type和protocol不可以随意组合,如SOCK_STREAM不可以跟IPPROTO_UDP组合。

        返回值:

        NULL:失败

        其他值:Sockcet描述符

        实例:

int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);  //创建TCP套接字
 
int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);  //创建UDP套接字

      lwip_connect

        函数功能:

        客户端通过该函数与服务端建立连接

        函数原型:

#define lwip_connect      connect
int connect(int fd, const struct sockaddr *addr, socklen_t len)

        参数:

        fd:socket描述符,socket()函数返回

        addr:要连接的服务端相关信息,包括IP和端口等

        len:服务端相关信息的长度

        返回值:

        -1:失败

        0:成功

        实例:

    int sock_fd; 

    struct sockaddr_in socket_addr;
    memset(&socket_addr, 0, sizeof(socket_addr));

    socket_addr.sin_family = AF_INET;	//IPV4
    socket_addr.sin_port = htons(_PROT_);	//端口
    socket_addr.sin_addr.s_addr = inet_addr("192.168.3.198");	//IP地址转换

    socklen_t addr_length = sizeof(socket_addr);

    LOG_I( "connect port:%d, addr:%s",_PROT_,inet_ntoa(socket_addr.sin_addr));

    int ret  = 0;

    ret = lwip_connect(sock_fd, (struct sockaddr *)&socket_addr, addr_length);
    if(ret < 0) //失败{}

         如果网关即为服务端,这里相关信息可以这么写。

struct netif *sta_if = netifapi_netif_find("wlan0"); 
socket_addr.sin_addr.s_addr = inet_addr(ipaddr_ntoa(&sta_if->gw));    //网关IP

      lwip_write

        函数功能:

        向套接字写数据

        函数原型:

ssize_t lwip_write(int s, const void *data, size_t size)

        参数:

        s:socket描述符,socket()函数返回

        data:要发送的数据

        size:要发送数据的长度

        返回值:

        -1:失败

        其他值:成功发送的字节数

        实例:

int sock_fd;
const char *send_data = "This is a socket client test!\r\n";
if(lwip_write(sock_fd,send_data, strlen(send_data)) != -1)    //发送成功
{}

      lwip_read

        函数功能:

        从套接字中读取数据阻塞等待

        函数原型:

ssize_t lwip_read(int s, void *mem, size_t len)

        参数:

        s:socket描述符,socket()函数返回

        mem:接收到的数据存储的地址

        len:最大接收数据长度

        返回值:

        -1:失败

        其他值:成功则返回读取到的字节数,遇到文件结尾则返回0

        实例:

int sock_fd; 
char recvBuf[512] = {0};
if((temp_len = lwip_read(sock_fd, recvBuf, sizeof(recvBuf))) > 0) //读成功
{}

      lwip_close

        函数功能:

        关闭之前打开的套接字

        函数原型:

int closesocket(int s)

        参数:

        s:socket描述符,socket()函数返回

        返回值:

        0:成功

        其他值:失败

        实例:

int sock_fd; 
closesocket(sock_fd);

      sendto

        函数功能:

        发送数据到服务器端(一般用于UDP)。

        函数原型:

ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)

        参数:

        fd:socket描述符,socket()的返回值。

        buf:要发送的数据

        len:要发送数据的长度

        flags:默认0

        addr:服务端相关信息。

        alen:服务端信息长度

        返回值:

        -1:失败

        其他值:成功发送的字节数

        实例:

int sock_fd;

//服务器的地址信息
struct sockaddr_in send_addr;
socklen_t addr_length = sizeof(send_addr);

//初始化预连接的服务端地址
send_addr.sin_family = AF_INET;
send_addr.sin_port = htons(_PROT_);
send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");
addr_length = sizeof(send_addr);
sendto(sock_fd, send_data, strlen(send_data), 0, (struct sockaddr *)&send_addr, addr_length);

      recvfrom

        函数功能:

        接收socket传输过来的数据(一般用于UDP),阻塞等待

        函数原型:

ssize_t recvfrom(int s, void *mem, size_t len, int flags,
                 struct sockaddr *from, socklen_t *fromlen)

        参数:

        s:socket描述符,socket()函数返回

        mem:接收到的数据存放的地址

        len:最大接收数据长度、

        flags:默认为0。

        addr:服务端相关信息。

        alen:服务端信息长度

        返回值:

        -1:失败

        其他值:接收到的数据长度

        实例:

    int sock_fd;    //在sock_fd 进行监听,在 new_fd 接收新的链接
    char recvBuf[512] = {0};
    
    //服务器的地址信息
    struct sockaddr_in send_addr;
    socklen_t addr_length = sizeof(send_addr);

    //初始化预连接的服务端地址
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(_PROT_);
    send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");
    addr_length = sizeof(send_addr);


    recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&send_addr, &addr_length);

      lwip_setsockopt

        函数功能:

        设置套接字描述符选项

        函数原型:

#define lwip_setsockopt   setsockopt
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)

        参数:

        s:socket描述符,socket()函数返回

        level:选项定义的层次

SOL_SOCKET,套接字层
IPPROTO_TCP,TCP层
IPPROTO_IP,IP层
IPPROTO_IPV6,IPV6层

        optname:需要设置的选项。这里只介绍常用的选项。在level为SOL_COCKET(套接字层)时,optname可选一下值:

/*设置发送超时*/
#define SO_SNDTIMEO     0x1005 /* send timeout */
/*设置接收超时*/
#define SO_RCVTIMEO     0x1006 /* receive timeout */

         optval:指向存放选项待设置新值的缓冲区

        optlen:缓冲区长度

        返回值:

        -1:失败

        0:成功

        实例:

struct timeval timeout;
timeout.tv_sec  = 30;   //秒
timeout.tv_usec = 0;    //微秒
if (setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
    LOG_I(lwip_socket_example, "Setsockopt failed - set rcvtimeo\n");
}

      htonl()、htons()、ntohl()、ntohs()

        函数功能:

        在编程的时候,往往会遇到网络字节顺序主机顺序的问题。这时就需要以上四个函数进行调节了。

htonl()--"Host to Network Long"
 
ntohl()--"Network to Host Long"
 
htons()--"Host to Network Short"
 
ntohs()--"Network to Host Short"

        主机顺序大端或小端大端就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端(高位在前,低位在后)。小端就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端(低位在前,高位在后)。

        网络字节序:4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作大端字节序。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序

        函数原型:

uint32_t htonl(uint32_t hostlong);

        参数:

        转换前的值

        返回值:

        转换后的值

        实例:

server_sock.sin_addr.s_addr = htonl(INADDR_ANY);    //地址,随意分配

        

     inet_addr()      

        函数功能:   

        转换网络主机地址(192.168.x.x)为网络字节序排序地址

        函数原型:

in_addr_t inet_addr(const char* cp)

        参数:

        cp:网络主机地址(192.168.x.x)

        返回值:

        -1:失败。当cp无效时(255.255.255.0或其他)返回-1.

        其他值:网络字节排序地址

        实例:

send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");

     inet_aton()      

        函数功能:   

        将主机地址(192.168.x.x)转化为二进制数值

        注:这个函数转换完后不能用于网络传输,还需要调用htonshtonl函数才能将主机字节顺序转换为网络字节顺序

        函数原型:

int inet_aton(const char* cp, struct in_addr* inp)

        参数:

        cp:输入值,网络主机地址(192.168.x.x)

        inp:输出值,转换后的二进制数值

        返回值:

        0:主机地址无效

        其他值:主机地址有效

        实例:

struct sockaddr_in sin1;	
inet_aton("127.0.0.1", &sin1.sin_addr);

     inet_ntoa()      

        函数功能:   

        将网络字节排序的地址转换为ASICC(x.x.x.x)。

        注:该字符串的空间为静态分配,这意味着在第二次调用该函数时,上一次调用的输出值将会被覆盖

        函数原型:

char *inet_ntoa(struct in_addr in)

        参数:

        in:类型为in_addr。网络字节排序地址。

typedef uint32_t in_addr_t;

        返回值:

        转化的字符串

        实例:

struct in_addr addr1,addr2;

addr1 = inet_addr("192.168.0.74");
addr2 = inet_addr("211.100.21.179");

printf("%s : %s\n", inet_ntoa(addr1), inet_ntoa(addr2)); //不可以这么用,结果会被覆盖  
printf("%s\n", inet_ntoa(addr1));   
printf("%s\n", inet_ntoa(addr2));

输出结果:
192.168.0.74 : 192.168.0.74          //从这里可以看出,printf里的inet_ntoa只运行了一次。

192.168.0.74  

211.100.21.179 

     ipaddr_ntoa()      

        函数功能:   

        将网络地址类型的地址转换为ASICC(x.x.x.x)。

        注:ipaddr_ntoa和inet_ntoa的功能相同,都是将传参转换为字符串。但是传参的数据类型不同ipaddr_ntoa参数的类型为ip_addr_t的指针,而inet_ntoa参数为uint32_t类型的整型

        函数原型:

char *ipaddr_ntoa(const ip_addr_t *addr)

        参数:

        addr:网络地址

        返回值:

        转化的字符串

        实例:

lwip_netif = netifapi_netif_find("ap0");  //获取网络借口,用于IP操作
LOG_I("ip addr:%s",ipaddr_ntoa(&lwip_netif->ip_addr));

     ipaddr_aton()      

        函数功能:   

        将主机地址(192.168.1.1)转化为网络字节类型

        函数原型:

int ipaddr_aton(const char *cp, ip_addr_t *addr)

        参数:

        cp:输入值,网络主机地址(192.168.x.x)

        addr:输出值,网络地址,类型为ip_addr_t.

typedef struct ip_addr {
  union {
    ip6_addr_t ip6;
    ip4_addr_t ip4;
  } u_addr;
  /** @ref lwip_ip_addr_type */
  u8_t type;
} ip_addr_t;

        返回值:

        0:成功

        其他值:失败

        实例:

struct netif *lwip_netif = NULL;
ipaddr_ntoa("192.168.1.1",&lwip_netif->ip_addr));

     inet_pton()      

        函数功能:   

        将点分十进制的IP地址(192.168.x.x)转化为用于网络传输的数据格式

        函数原型:

int inet_pton(int af, const char *src, void *dst)

        参数:

        af:地址族,AF_INET(IPV4)、AF_INET6(IPV6)。

        src:输入值,点分十进制的IP地址(192.168.x.x)

        dst:输出值,用于网络传输的数据格式

        返回值:

        -1:异常

        0:输入值异常

        1:成功

        实例:

struct sockaddr_in socket_addr;
inet_pton(AF_INET, "192.168.1.110", &socket_addr.sin_addr); 
/*
代替socket_addr.sin_addr.s_addr = inet_addr("192.168.1.110");	//IP地址转换
*/

     inet_ntop()      

        函数功能:   

        将用于网络传输的数据格式转化为点分十进制的IP地址格式(192.168.x.x)

        函数原型:

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)

        参数:

        af:地址族,AF_INET(IPV4)、AF_INET6(IPV6)。

        src:输入值,网络传输数据格式的数据

        dst:输出值,IP地址格式(192.168.x.x)

        size:输入值,目标存储单元大小。

        返回值:

        0:成功

        其他值:失败。ENOSPC size长度太小。

        实例:

char str[INET_ADDRSTRLEN];
struct sockaddr_in socket_addr;

char *ptr = inet_ntop(AF_INET,&socket_addr.sin_addr, str, sizeof(str));      
// 代替 ptr = inet_ntoa(socket_addr.sin_addr)

三、实例

        这里分别创建一个TCP和一个UDP

         现在BUILD.gn文件中添加如下代码

    include_dirs = [
        "//utild/native/lite/include",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
        "//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
    ]
/*TCP*/


#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "wifi_device.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include "lwip/sockets.h"

#define LOG_I(fmt, args...)   printf("<%8ld> - [SOCKET_CLIENT]:"fmt"\r\n",osKernelGetTickCount(),##args);
#define LOG_E(fmt, args...)   printf("<%8ld>-[SOCKET_CLIENT_ERR]>>>>>>>>>>>>:"fmt"\r\n",osKernelGetTickCount(), ##args);

#define _PROT_ 7682


static const char *send_data = "Hello! I'm BearPi-HM_Nano UDP Client!\r\n";

static void SocketClientTask(void)
{
    int sock_fd;    //在sock_fd 进行监听,在 new_fd 接收新的链接
    char recvBuf[512] = {0};

    //连接Wifi
    extern int drv_wifi_connect(const char *ssid, const char *psk);
    drv_wifi_connect("Harmony_test_ap", "123123123");

    LOG_I("wifi connect success");

    //创建socket
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        LOG_E("create socket failed!\r\n");
        exit(1);
    }

    LOG_I("socket TCP create done");

    struct sockaddr_in socket_addr;
    memset(&socket_addr, 0, sizeof(socket_addr));

    socket_addr.sin_family = AF_INET;	//IPV4
    socket_addr.sin_port = htons(_PROT_);	//端口
    socket_addr.sin_addr.s_addr = inet_addr("192.168.3.198");	//IP地址转换
    // socket_addr.sin_addr.s_addr = inet_addr(ipaddr_ntoa(&sta_if->gw));    //网关IP

    socklen_t addr_length = sizeof(socket_addr);

    LOG_I( "connect port:%d, addr:%s",_PROT_,inet_ntoa(socket_addr.sin_addr));

    int ret  = 0;
    do{
        ret = lwip_connect(sock_fd, (struct sockaddr *)&socket_addr, addr_length);
        if(ret != 0) //失败
        {
            LOG_I("socket connect fail");
            // lwip_close(sock_fd);    //关闭socket
            osDelay(100);
        }
    }while(ret != 0);

    LOG_I("socket connect success");

    struct timeval timeout;
    timeout.tv_sec = 5;       //秒
    timeout.tv_usec = 0;     //微秒
    if (lwip_setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) //设置接收超时
    {
        LOG_E("Setsockopt failed - set rcvtimeo\n");
    }

    LOG_I("set socket receive timeout:%d",timeout.tv_sec);

    int temp_len = 0;

    while(1)
    {
        bzero(recvBuf, sizeof(recvBuf));

        if(lwip_write(sock_fd,send_data, strlen(send_data)) != -1)
        {
            LOG_I("socket write success");
        }
        else
        {
            LOG_E("socket write fail");
        }

        temp_len = 0;
        if((temp_len = lwip_read(sock_fd, recvBuf, sizeof(recvBuf))) > 0) //读成功
        {
            LOG_I( "TCP client >>>>>read>>>>> data,len:%d,data:%s", temp_len, recvBuf);
        }
        else
        {
            LOG_E("socket client read fail");
        }
    }

    //关闭这个 socket
    closesocket(sock_fd);
}

void app_socket_client_init(void)
{
    osThreadAttr_t attr;

    attr.name = "UDPClientTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)SocketClientTask, NULL, &attr) == NULL)
    {
        LOG_E("[UDPClientDemo] Falied to create UDPClientTask!\n");
    }
}
/*UDP*/


#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "wifi_device.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include "lwip/sockets.h"

#define LOG_I(fmt, args...)   printf("<%8ld> - [SOCKET_CLIENT]:"fmt"\r\n",osKernelGetTickCount(),##args);
#define LOG_E(fmt, args...)   printf("<%8ld>-[SOCKET_CLIENT_ERR]>>>>>>>>>>>>:"fmt"\r\n",osKernelGetTickCount(), ##args);

#define _PROT_ 7682


static const char *send_data = "This is a UDP client test!\r\n";

static void SocketClientTask(void)
{
    int sock_fd;    //在sock_fd 进行监听,在 new_fd 接收新的链接
    char recvBuf[512] = {0};

    //连接Wifi
    extern int drv_wifi_connect(const char *ssid, const char *psk);
    drv_wifi_connect("Harmony_test_ap", "123123123");

    LOG_I("wifi connect success");


    //创建socket
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        LOG_E("create socket failed!\r\n");
        exit(1);
    }

    LOG_I("socket UDP create done");

    //服务器的地址信息
    struct sockaddr_in send_addr;
    socklen_t addr_length = sizeof(send_addr);

    //初始化预连接的服务端地址
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(_PROT_);
    send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");
    addr_length = sizeof(send_addr);

    //总计发送 count 次数据
    while (1)
    {
        bzero(recvBuf, sizeof(recvBuf));

        //发送数据到服务远端
        sendto(sock_fd, send_data, strlen(send_data), 0, (struct sockaddr *)&send_addr, addr_length);

        LOG_I("socket send done");

        //线程休眠一段时间
        sleep(10);
        // osDelay(500);

        LOG_I("socket wait receive data");

        //接收服务端返回的字符串
        recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&send_addr, &addr_length);
        LOG_I("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf);
    } 

    //关闭这个 socket
    closesocket(sock_fd);
}

void app_socket_client_init(void)
{
    osThreadAttr_t attr;

    attr.name = "UDPClientTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)SocketClientTask, NULL, &attr) == NULL)
    {
        LOG_E("[UDPClientDemo] Falied to create UDPClientTask!\n");
    }
}

        结果:因为使用的版本为1.0版本的SDK,TCP有问题,所以,这里先看UDP的结果,后续TCP会更换更改版本的SDK补上。

鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)

 鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)文章来源地址https://www.toymoban.com/news/detail-449799.html

到了这里,关于鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Hi3861鸿蒙物联网项目实战:智能安防报警

    华清远见FS-Hi3861开发套件,支持HarmonyOS 3.0系统。开发板主控Hi3861芯片内置WiFi功能,开发板板载资源丰富,包括传感器、执行器、NFC、显示屏等,同时还配套丰富的拓展模块。开发板配套丰富的学习资料,包括全套开发教程、视频课程、7大项目实战案例 可以帮助学员系统性学

    2024年02月09日
    浏览(35)
  • 鸿蒙OS Hi3861的芯片实际开发中遇到的问题

    优点: 比较适合开发者快速开发,上面的硬件操作的函数封装很简单,非常适合初学者使用封装好的函数调用硬件管脚,比如I2c gpio spi sdio 都被封装了,特别简单,中文注释,而且还提供了无线wifi 的封装函数,当然也有http 解析啊什么的,可以使用在简单的物联网控制的简单

    2024年02月09日
    浏览(38)
  • 鸿蒙OS2.0 设备开发之Hi3861-基础功能汇总

    这是一篇讲解在 鸿蒙2.0全量源码中开发Hi3861 的常用功能汇总,可帮助我们 快速配置GPIO 如,如何实现 PWM、I2C、ADC 等。 1.1 输出 分两步,使能、配置输出值; 需要注意的是,有些GPIO还需要设置复用功能,可能默认不是普通GPIO模式。 这时候就需要使用 hi_io_set_func 函数;以

    2024年02月07日
    浏览(38)
  • 使用FS_Hi3861鸿蒙开发板编译时常见的一些问题

    本文档支持的是下面的产品 华清远见 FS-Hi3861 https://gitee.com/HiSpark/hi3861_hdu_iot_application/blob/master/src/vendor/hqyj/fs_hi3861/doc/%E5%8D%8E%E6%B8%85%E8%BF%9C%E8%A7%81%20FS_Hi3861%E5%BC%80%E5%8F%91%E6%8C%87%E5%AF%BC.md 目录 在添加第三方库完成后,再次编译报错,提示“undefined reference to ******” 编译的时候,

    2024年02月08日
    浏览(42)
  • HI3861学习笔记(12)——GPIO输入接口使用

    HI3861V100 芯片有 15 个 GPIO,引脚分布如下: 以下 GPIO 接口位于 baseiot_hardwareinterfaceskitswifiiot_litewifiiot_gpio.h 。 业务BUILD.gn中包含路径 功能 初始化GPIO外设 函数定义 unsigned int GpioInit(void) 参数 无 返回 错误码 功能 设置GPIO输出方向 函数定义 unsigned int GpioSetDir(WifiIotGpioIdx id,

    2024年02月09日
    浏览(28)
  • Hi3861开发环境搭建 ||避坑指南|| [适用于几乎所有以Hi3861为主控的开发板]

    前言: 这几天为了搭建Hi3861的开发环境,看了不少官方文档和视频,但是依然折腾了很久才配置好编译、上传都能正常的环境,这其中踩了不少坑,希望通过这篇文章能让大家少踩点。 当然其实主要问题还是源码更新、视频教程更新还有文档更新速度没匹配上 参考海思社区

    2024年02月05日
    浏览(45)
  • Hi3861 OpenHarmony 运行Hello World

    海思 hi3861 有2个型号:  Hi3861LV100 低功耗版 低功耗MCU Wi-Fi芯片,适用于智能门锁、智能猫眼等低功耗物联网智能产品。 Hi3861V100 标准版 MCU Wi-Fi芯片,适用于大小家电、电工照明等常电类物联网智能产品。 系统默认的是标准版,低功耗版好像是需要改下设置。越简单越好的原

    2024年02月20日
    浏览(29)
  • Hi3861 硬件 i2c 驱动 oled

    最近想用 3861 做个有意思的东西,记录一下开发过程。今天使用 3861 的硬件 i2c 驱动 oled。 硬件平台:Bearpi-Nano 软件SDK:润和sdk 我之前写过一篇基于 stm32cubemx 快速使用 iic 接口 oled 的过程,里面有现成的 oled 接口,我们只要直接拿过来替换掉底层接口就行。  STM32CubeMX驱动4脚

    2023年04月23日
    浏览(32)
  • Hi3861开发第一节:环境搭建,并顺利完成编译

    步骤一:下载devicetool-windows-tool-3.1.0.400.zip版,下载网址:https://device.harmonyos.c om/cn/develop/ide#download 步骤二:解压DevEco Device Tool压缩包,双击安装包程序,点击\\\"下一步\\\"进行安装(如果之前有 安装过,会弹出先卸载之前版本在安装,请按照要求先卸载); 步骤三:设置DevEco

    2024年02月09日
    浏览(28)
  • 鸿蒙LiteOs读源码教程+向LiteOS中添加一个简单的基于线程运行时的短作业优先调度策略

    【找到了一种简单易懂的实验实现方式,适合基础较薄弱的同学,见第二部分】 最终效果如下: 依次创建了3个任务线程,以One、Two、Three指代,时间分别为15秒、30秒、10秒。 如果按生成顺序输出应该是:One-Two-Three,但我们修改了OsPriQueueEnqueue函数,由原先的“先进先出”,

    2024年02月05日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包