会飞的猪_2020 发表于 2024-3-11 15:26:06

ChatGPT真是解释代码的好帮手。

它解释代码的能力很强大...
特别是看那些看不懂的内容的时候。












cctv180 发表于 2024-3-11 16:25:06

这个我熟悉,下面代码基本都是gpt生成的好用到嫑嫑的。
/*
*********************************************************************************************************
*
*    模块名称: utils_lib
*    文件名称: utils_lib.c
*    版   本: V1.1
*    说   明: 实用工具库
*    修改记录:
*               V1.12024-02-23    dump_hex改为utils_lib
*                                 增加 mem_fill 使用指定的值填充内存块
*                                 增加 find_PowerOf2 查找与给定数值最接近的2的幂
*
*               V1.02023-09-13    首版
*    参考资料:
                C 语言内存 dump 函数
*               https://murphy.tech/posts/de9ea2d9.html
*********************************************************************************************************
*/

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#if 1
#include "bsp.h"
#endif

#include "utils_lib.h"

// 定义一个宏,用于检查字符是否可打印
#define IS_PRINT(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')

// 定义常量字符串,提高可读性和可维护性
#define TXT_OFFSET "| Offset |"
#define TXT_HEX_8 " 00 01 02 03 04 05 06 07 "
#define TXT_HEX_16 " 00 01 02 03 04 05 06 0708 09 0A 0B 0C 0D 0E 0F "
#define TXT_HEX_32 " 00 01 02 03 04 05 06 0708 09 0A 0B 0C 0D 0E 0F10 11 12 13 14 15 16 1718 19 1A 1B 1C 1D 1E 1F "
#define TXT_ASCII "| ASCII |"

/**
* 打印十六进制和ASCII表示的数据块。
*
* @param buf    要打印的数据块的指针
* @param size   数据块的大小(以字节为单位)
* @param number 每行打印的字节数(8、16、32等)
*/
void dump_hex(const void *_buf, uint32_t _size, uint32_t _number)
{
    uint8_t *buffer = (uint8_t *)_buf;
    const char *hex_table = (_number == 32) ? TXT_HEX_32 : ((_number == 8) ? TXT_HEX_8 : (_number = 16, TXT_HEX_16));
    printf("\r\n%s%s%s\r\n", TXT_OFFSET, hex_table, TXT_ASCII); // hex table
    printf("== base address 0x%08X length %d ==\r\n", (uint32_t)buffer, _size);

    for (uint32_t i = 0; i < _size; i += _number)
    {
      printf("%08X: ", i);

      for (uint32_t j = 0; j < _number; j++)
      {
            if (j % 8 == 0)
            {
                printf(" ");
            }
            if (i + j < _size)
            {
                printf("%02X ", buffer);
            }
            else
            {
                printf("   ");
            }
      }

      printf(" ");
      for (uint32_t j = 0; j < _number; j++)
      {
            if (i + j < _size)
            {
                printf("%c", IS_PRINT(buffer) ? buffer : '.');
            }
      }
      printf("\r\n");
    }
}

/**
* 使用指定的值填充内存块。
*
* @param ptr   指向要填充的内存块的指针。
* @param value 要填充的值,可以是8位、16位、32位或64位。
* @param num   要填充值的数量。
* @param size要填充值多少个字节。
*/
void mem_fill(void *_ptr, uint64_t _value, size_t _num, size_t _size)
{
    unsigned char *p = (unsigned char *)_ptr; // 转换指针以便逐字节操作

    while (_num-- > 0) // 遍历每个值
    {
      for (size_t j = 0; j < _size; ++j)
      {                                              // 遍历每个值的每个字节
            *p++ = (unsigned char)(_value >> (j * 8)); // 从value中提取字节并填充
      }
    }
}

/**
* 查找与给定数值最接近的2的幂。
*
* @param _num 输入的数值。根据此数值查找最接近的2的幂。
* @param _findNext 控制查找方向的标志。
*               如果为true,查找不小于_num的最小2的幂;
*               如果为false,查找小于_num的最大2的幂。
* @return uint32_t 返回符合条件的2的幂。对于_num为0时,根据_findNext返回0或1。
*/
uint32_t find_PowerOf2(uint32_t _num, _Bool _findNext)
{
    if (_num == 0)
    {
      return _findNext ? 1 : 0; // 对于_num为0,返回0或1取决于_findNext的值。
    }
    if (_num == 1)
    {
      return _findNext ? 1 : 0; // 对于_num为1,寻找下一个2的幂返回1,否则返回0。
    }

    // 如果_num本身是2的幂
    if ((_num & (_num - 1)) == 0)
    {
      return _num;
    }

    // 启用 STM32 硬件提供的计算前导零指令 CLZ
    // return (0x80000000UL >> (__clz(_num) - 1)); //向上取整为2次幂
    // return (0x80000000UL >> __clz(_num)); // 向下取整为2次幂

    _num |= _num >> 1; // 将高位至少保留两位1
    _num |= _num >> 2;
    _num |= _num >> 4;
    _num |= _num >> 8;
    _num |= _num >> 16;
    _num++; // 最终结果是原始值向上取整到的最小2的幂

    return _findNext ? _num : _num >> 1; // 根据_findNext标志返回适当的2的幂
}

#if defined(__SHELL_H__) && DEBUG_MODE == 1

#include <stdlib.h> // 为了使用strtoul函数
// 适配器函数,用于将dump_hex适配为shell命令
int _cmd_dump_hex(int argc, char **argv)
{
    /* 检查参数数量 */
    if (argc != 3)
    {
      printf("Usage: dump_hex <address> <size>\r\n");
      return -1;
    }

    /* 解析命令行参数 */
    uint32_t address = (uint32_t)strtoul(argv, NULL, 0);
    uint32_t size = strtoul(argv, NULL, 10);

    /* 调用原始的dump_hex函数 */
    dump_hex((const void *)address, size, 16);

    return 0;
}
// 使用SHELL_EXPORT_CMD宏注册命令
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), dump_hex, _cmd_dump_hex, "Dump memory in hex");

// 适配器函数,用于将memset_custom适配为shell命令
int _cmd_memfill(int argc, char **argv)
{
    /* 检查参数数量 */
    if (argc != 5)
    {
      printf("Usage: memfill <address> <value> <num> <byte*x>\r\n");
      return -1;
    }

    /* 解析命令行参数 */
    void *ptr = (void *)strtoul(argv, NULL, 0);
    uint64_t value = strtoull(argv, NULL, 0);
    size_t num = strtoul(argv, NULL, 0);
    size_t size = strtoul(argv, NULL, 0);

    mem_fill(ptr, value, num, size); // 调用memset_custom函数

    return 0;
}
// 使用SHELL_EXPORT_CMD宏注册命令
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), mem_fill, _cmd_memfill, "fill memory");

#endif // #if defined(__SHELL_H__) && DEBUG_MODE == 1

会飞的猪_2020 发表于 2024-3-11 16:50:17

本帖最后由 会飞的猪_2020 于 2024-3-11 16:53 编辑

cctv180 发表于 2024-3-11 16:25
这个我熟悉,下面代码基本都是gpt生成的好用到嫑嫑的。
/*
*********************** ...
它连letter-shell的代码也能生成吗?
你这个我看着特别熟悉...
像是这里的代码。。
easy-log

cctv180 发表于 2024-3-11 17:09:42

本帖最后由 cctv180 于 2024-3-11 17:12 编辑

会飞的猪_2020 发表于 2024-3-11 16:50
它连letter-shell的代码也能生成吗?
你这个我看着特别熟悉...
像是这里的代码。。

没错导入shell也是他自动匹配的,好用的很,里面打印命令提示我简单修过。{:8:}

补充 dump_hex 原始代码在头里面有写来源哈不是EasyLogger抠的,你可以看我的同名gayhub

li1069136863 发表于 2024-3-13 08:43:23

是4.0版本吗

soyshell 发表于 2024-3-13 09:27:30

是 4.0版本吗?我用3.5版本的chatgpt,回答的内容,没有你的这么详细。
页: [1]
查看完整版本: ChatGPT真是解释代码的好帮手。