基于cubemx 的 h750vb 移植LUA解释器_AsuH的博客-程序员秘密

技术标签: stm32  lua  

因为我想实现的功能是在把 *.lua文件丢到FLASH虚拟的U盘里,重新上电后运行。
网上的资料不多,而且大多没有关于dofile函数的实现。
所以,我整理了一下,形成了这篇博客。
  1. 创建stm32cubemx的H750vb工程,并完成外设的驱动:
    在这里插入图片描述

     这部分网上有很多实现方法这里不在赘述:
    
    • usart驱动
    • spi flash驱动 这里我使用的是spi2口
    • fatfs文件系统 并 挂载spi flash分区
    • usb的msc模式

    修改堆栈大小。 stack size设为0x2000; heap size设为0x4000.

  2. 去Lua官网下载源文件
    http://www.lua.org/download.html
    我使用的是当前最新版本 5.4.3,将加载到自己的工程中(不添加lua.c和luac.c)。
    移植过程可参考:
    https://www.cnblogs.com/yangfengwu/p/9315841.html
    同时参考armfly大神的分享,及其在H7-TOOL中的实现方法:
    http://www.armbbs.cn/forum.php?mod=viewthread&tid=97441
    启用MicroLIB库,同时增加 lua_sys.c 文件代码如下:

#include "usart.h"
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <ff.h>
/*lua相关*/
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"



FATFS fs;
FIL g_file;
/*
*********************************************************************************************************
*    函 数 名: 无
*    功能说明: 此处,重写了 stdio 中定义的与文件操作的相关函数,使其满足Lua解释器的文件调用操作,
*             暂时只实现了读取功能。
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
extern _ARMABI int remove(const char * /*filename*/) __attribute__((__nonnull__(1)));
   /*
    * causes the file whose name is the string pointed to by filename to be
    * removed. Subsequent attempts to open the file will fail, unless it is
    * created anew. If the file is open, the behaviour of the remove function
    * is implementation-defined.
    * Returns: zero if the operation succeeds, nonzero if it fails.
    */
extern _ARMABI int rename(const char * /*old*/, const char * /*new*/) __attribute__((__nonnull__(1,2)));
   /*
    * causes the file whose name is the string pointed to by old to be
    * henceforth known by the name given by the string pointed to by new. The
    * file named old is effectively removed. If a file named by the string
    * pointed to by new exists prior to the call of the rename function, the
    * behaviour is implementation-defined.
    * Returns: zero if the operation succeeds, nonzero if it fails, in which
    *          case if the file existed previously it is still known by its
    *          original name.
    */
extern _ARMABI FILE *tmpfile(void);
   /*
    * creates a temporary binary file that will be automatically removed when
    * it is closed or at program termination. The file is opened for update.
    * Returns: a pointer to the stream of the file that it created. If the file
    *          cannot be created, a null pointer is returned.
    */
extern _ARMABI char *tmpnam(char * /*s*/);
   /*
    * generates a string that is not the same as the name of an existing file.
    * The tmpnam function generates a different string each time it is called,
    * up to TMP_MAX times. If it is called more than TMP_MAX times, the
    * behaviour is implementation-defined.
    * Returns: If the argument is a null pointer, the tmpnam function leaves
    *          its result in an internal static object and returns a pointer to
    *          that object. Subsequent calls to the tmpnam function may modify
    *          the same object. if the argument is not a null pointer, it is
    *          assumed to point to an array of at least L_tmpnam characters;
    *          the tmpnam function writes its result in that array and returns
    *          the argument as its value.
    */

//extern _ARMABI int fclose(FILE * /*stream*/) __attribute__((__nonnull__(1)));
_ARMABI int fclose(FILE * stream)
   /*
    * causes the stream pointed to by stream to be flushed and the associated
    * file to be closed. Any unwritten buffered data for the stream are
    * delivered to the host environment to be written to the file; any unread
    * buffered data are discarded. The stream is disassociated from the file.
    * If the associated buffer was automatically allocated, it is deallocated.
    * Returns: zero if the stream was succesfully closed, or nonzero if any
    *          errors were detected or if the stream was already closed.
    */
{
    
    FIL *fp;
    FRESULT result;

    fp = (FIL *)stream;
    result = f_close(fp);

    if (result != FR_OK)
    {
    
        return result;
    }
    return 0;
}

extern _ARMABI int fflush(FILE * /*stream*/);
   /*
    * If the stream points to an output or update stream in which the most
    * recent operation was output, the fflush function causes any unwritten
    * data for that stream to be delivered to the host environment to be
    * written to the file. If the stream points to an input or update stream,
    * the fflush function undoes the effect of any preceding ungetc operation
    * on the stream.
    * Returns: nonzero if a write error occurs.
    */

_ARMABI FILE *fopen(const char * filename /*filename*/,
                           const char * mode /*mode*/)
   /*
    * opens the file whose name is the string pointed to by filename, and
    * associates a stream with it.
    * The argument mode points to a string beginning with one of the following
    * sequences:
    * "r"         open text file for reading
    * "w"         create text file for writing, or truncate to zero length
    * "a"         append; open text file or create for writing at eof
    * "rb"        open binary file for reading
    * "wb"        create binary file for writing, or truncate to zero length
    * "ab"        append; open binary file or create for writing at eof
    * "r+"        open text file for update (reading and writing)
    * "w+"        create text file for update, or truncate to zero length
    * "a+"        append; open text file or create for update, writing at eof
    * "r+b"/"rb+" open binary file for update (reading and writing)
    * "w+b"/"wb+" create binary file for update, or truncate to zero length
    * "a+b"/"ab+" append; open binary file or create for update, writing at eof
    *
    * Opening a file with read mode ('r' as the first character in the mode
    * argument) fails if the file does not exist or cannot be read.
    * Opening a file with append mode ('a' as the first character in the mode
    * argument) causes all subsequent writes to be forced to the current end of
    * file, regardless of intervening calls to the fseek function. In some
    * implementations, opening a binary file with append mode ('b' as the
    * second or third character in the mode argument) may initially position
    * the file position indicator beyond the last data written, because of the
    * NUL padding.
    * When a file is opened with update mode ('+' as the second or third
    * character in the mode argument), both input and output may be performed
    * on the associated stream. However, output may not be directly followed
    * by input without an intervening call to the fflush fuction or to a file
    * positioning function (fseek, fsetpos, or rewind), and input be not be
    * directly followed by output without an intervening call to the fflush
    * fuction or to a file positioning function, unless the input operation
    * encounters end-of-file. Opening a file with update mode may open or
    * create a binary stream in some implementations. When opened, a stream
    * is fully buffered if and only if it does not refer to an interactive
    * device. The error and end-of-file indicators for the stream are
    * cleared.
    * Returns: a pointer to the object controlling the stream. If the open
    *          operation fails, fopen returns a null pointer.
    */
{
    
    /*
        fatfs官网有兼容方式定义格式
        http://elm-chan.org/fsw/ff/doc/open.html

        POSIX        FatFs
        "r"            FA_READ
        "r+"        FA_READ | FA_WRITE
        "w"            FA_CREATE_ALWAYS | FA_WRITE
        "w+"        FA_CREATE_ALWAYS | FA_WRITE | FA_READ
        "a"     FA_OPEN_APPEND | FA_WRITE
        "a+"    FA_OPEN_APPEND | FA_WRITE | FA_READ
        "wx"    FA_CREATE_NEW | FA_WRITE
        "w+x"   FA_CREATE_NEW | FA_WRITE | FA_READ
    */
    FRESULT result;
    BYTE ff_mode;

    if (strcmp(mode, "r") == 0)         ff_mode = FA_READ;
    else if (strcmp(mode, "r+") == 0)   ff_mode = FA_READ | FA_WRITE;
    else if (strcmp(mode, "w") == 0)    ff_mode = FA_CREATE_ALWAYS | FA_WRITE;
    else if (strcmp(mode, "w+") == 0)   ff_mode = FA_CREATE_ALWAYS | FA_WRITE | FA_READ;
    else if (strcmp(mode, "a") == 0)    ff_mode = FA_OPEN_APPEND | FA_WRITE;
    else if (strcmp(mode, "a+") == 0)   ff_mode = FA_OPEN_APPEND | FA_WRITE | FA_READ;
    else if (strcmp(mode, "wx") == 0)   ff_mode = FA_CREATE_NEW | FA_WRITE;
    else if (strcmp(mode, "w+x") == 0)  ff_mode = FA_CREATE_NEW | FA_WRITE | FA_READ;

    /* 打开文件 */
    f_close(&g_file);
    result = f_open(&g_file, filename, ff_mode);
    if (result == FR_OK)
    {
    
        return (FILE *)&g_file;
    }

    return 0;
}

_ARMABI FILE *freopen(const char * filename /*filename*/,
                    const char * mode /*mode*/,
                    FILE * stream /*stream*/)
   /*
    * opens the file whose name is the string pointed to by filename and
    * associates the stream pointed to by stream with it. The mode argument is
    * used just as in the fopen function.
    * The freopen function first attempts to close any file that is associated
    * with the specified stream. Failure to close the file successfully is
    * ignored. The error and end-of-file indicators for the stream are cleared.
    * Returns: a null pointer if the operation fails. Otherwise, freopen
    *          returns the value of the stream.
    */  
{
      
    return 0;
}

extern _ARMABI void setbuf(FILE * __restrict /*stream*/,
                    char * __restrict /*buf*/) __attribute__((__nonnull__(1)));
   /*
    * Except that it returns no value, the setbuf function is equivalent to the
    * setvbuf function invoked with the values _IOFBF for mode and BUFSIZ for
    * size, or (if buf is a null pointer), with the value _IONBF for mode.
    * Returns: no value.
    */
extern _ARMABI int setvbuf(FILE * __restrict /*stream*/,
                   char * __restrict /*buf*/,
                   int /*mode*/, size_t /*size*/) __attribute__((__nonnull__(1)));
   /*
    * may be used after the stream pointed to by stream has been associated
    * with an open file but before it is read or written. The argument mode
    * determines how stream will be buffered, as follows: _IOFBF causes
    * input/output to be fully buffered; _IOLBF causes output to be line
    * buffered (the buffer will be flushed when a new-line character is
    * written, when the buffer is full, or when input is requested); _IONBF
    * causes input/output to be completely unbuffered. If buf is not the null
    * pointer, the array it points to may be used instead of an automatically
    * allocated buffer (the buffer must have a lifetime at least as great as
    * the open stream, so the stream should be closed before a buffer that has
    * automatic storage duration is deallocated upon block exit). The argument
    * size specifies the size of the array. The contents of the array at any
    * time are indeterminate.
    * Returns: zero on success, or nonzero if an invalid value is given for
    *          mode or size, or if the request cannot be honoured.
    */

extern _ARMABI size_t fread(void * ptr /*ptr*/,
                    size_t size/*size*/, size_t nmemb/*nmemb*/, FILE * stream /*stream*/)
   /*
    * reads into the array pointed to by ptr, up to nmemb members whose size is
    * specified by size, from the stream pointed to by stream. The file
    * position indicator (if defined) is advanced by the number of characters
    * successfully read. If an error occurs, the resulting value of the file
    * position indicator is indeterminate. If a partial member is read, its
    * value is indeterminate. The ferror or feof function shall be used to
    * distinguish between a read error and end-of-file.
    * Returns: the number of members successfully read, which may be less than
    *          nmemb if a read error or end-of-file is encountered. If size or
    *          nmemb is zero, fread returns zero and the contents of the array
    *          and the state of the stream remain unchanged.
    */
{
    
    FRESULT result;
    uint32_t br = 0;
    FIL *fp;

    fp = (FIL *)stream;   

    result = f_read(fp, ptr, nmemb,  &br);
    if (result == FR_OK)
    {
    
        return br;
    }

    return 0;
}

extern _ARMABI int setvbuf(FILE * __restrict /*stream*/,
                   char * __restrict /*buf*/,
                   int /*mode*/, size_t /*size*/) __attribute__((__nonnull__(1)));
   /*
    * may be used after the stream pointed to by stream has been associated
    * with an open file but before it is read or written. The argument mode
    * determines how stream will be buffered, as follows: _IOFBF causes
    * input/output to be fully buffered; _IOLBF causes output to be line
    * buffered (the buffer will be flushed when a new-line character is
    * written, when the buffer is full, or when input is requested); _IONBF
    * causes input/output to be completely unbuffered. If buf is not the null
    * pointer, the array it points to may be used instead of an automatically
    * allocated buffer (the buffer must have a lifetime at least as great as
    * the open stream, so the stream should be closed before a buffer that has
    * automatic storage duration is deallocated upon block exit). The argument
    * size specifies the size of the array. The contents of the array at any
    * time are indeterminate.
    * Returns: zero on success, or nonzero if an invalid value is given for
    *          mode or size, or if the request cannot be honoured.
    */

extern _ARMABI size_t fwrite(const void * __restrict /*ptr*/,
                    size_t /*size*/, size_t /*nmemb*/, FILE * __restrict /*stream*/) __attribute__((__nonnull__(1,4)));
   /*
    * writes, from the array pointed to by ptr up to nmemb members whose size
    * is specified by size, to the stream pointed to by stream. The file
    * position indicator (if defined) is advanced by the number of characters
    * successfully written. If an error occurs, the resulting value of the file
    * position indicator is indeterminate.
    * Returns: the number of members successfully written, which will be less
    *          than nmemb only if a write error is encountered.
    */

extern _ARMABI int fseek(FILE * /*stream*/, long int /*offset*/, int /*whence*/) __attribute__((__nonnull__(1)));
   /*
    * sets the file position indicator for the stream pointed to by stream.
    * For a binary stream, the new position is at the signed number of
    * characters specified by offset away from the point specified by whence.
    * The specified point is the beginning of the file for SEEK_SET, the
    * current position in the file for SEEK_CUR, or end-of-file for SEEK_END.
    * A binary stream need not meaningfully support fseek calls with a whence
    * value of SEEK_END.
    * For a text stream, either offset shall be zero, or offset shall be a
    * value returned by an earlier call to the ftell function on the same
    * stream and whence shall be SEEK_SET.
    * The fseek function clears the end-of-file indicator and undoes any
    * effects of the ungetc function on the same stream. After an fseek call,
    * the next operation on an update stream may be either input or output.
    * Returns: nonzero only for a request that cannot be satisfied.
    */
_ARMABI int fseek(FILE *stream, long int offset, int whence)
{
    
    return 0;
}

extern _ARMABI long int ftell(FILE * /*stream*/) __attribute__((__nonnull__(1)));
   /*
    * obtains the current value of the file position indicator for the stream
    * pointed to by stream. For a binary stream, the value is the number of
    * characters from the beginning of the file. For a text stream, the file
    * position indicator contains unspecified information, usable by the fseek
    * function for returning the file position indicator to its position at the
    * time of the ftell call; the difference between two such return values is
    * not necessarily a meaningful measure of the number of characters written
    * or read.
    * Returns: if successful, the current value of the file position indicator.
    *          On failure, the ftell function returns -1L and sets the integer
    *          expression errno to an implementation-defined nonzero value.
    */
_ARMABI long int ftell(FILE *stream)  
{
    
    FIL *fp;

    fp = (FIL *)stream;   

    return fp->fptr;
}

extern _ARMABI void clearerr(FILE * /*stream*/) __attribute__((__nonnull__(1)));
   /*
    * clears the end-of-file and error indicators for the stream pointed to by
    * stream. These indicators are cleared only when the file is opened or by
    * an explicit call to the clearerr function or to the rewind function.
    * Returns: no value.
    */
void clearerr(FILE *stream)
{
    
    FIL *fp;

    fp = (FIL *)stream;

    fp->err = 0;
}


extern _ARMABI int feof(FILE * /*stream*/) __attribute__((__nonnull__(1)));
   /*
    * tests the end-of-file indicator for the stream pointed to by stream.
    * Returns: nonzero iff the end-of-file indicator is set for stream.
    */
_ARMABI int feof(FILE *stream)
{
    
    FIL *fp;

    fp = (FIL *)stream;
    if (fp->fptr >= fp->obj.objsize)
    {
    
        return 1;
    }
    return 0;   
}

extern _ARMABI int ferror(FILE * /*stream*/) __attribute__((__nonnull__(1)));
   /*
    * tests the error indicator for the stream pointed to by stream.
    * Returns: nonzero iff the error indicator is set for stream.
    */
_ARMABI int ferror(FILE *stream)
{
    
    FIL *fp;

    fp = (FIL *)stream;

    return fp->err;
}


/*
*********************************************************************************************************
*    函 数 名: fgetc
*    功能说明: 重定义getc函数,这样可以使用getchar函数从串口1输入数据
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
int fgetc(FILE *f)
{
    
    if (f == &__stdin)
    {
         
        return 0;   
    }
    else    /* 文件操作, lua dofile()会执行这个分支 */
    {
    
        FRESULT result;
        uint32_t br = 0;
        FIL *fp;
        char buf[2];

        fp = (FIL *)f;   

        result = f_read(fp, buf, 1,  &br);
        if (result == FR_OK)
        {
    
            return buf[0];
        }

        return 0;
    }
}

/*
*********************************************************************************************************
*    函 数 名: fputc
*    功能说明: 重定义putc函数,这样可以使用printf函数从串口1打印输出
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
int fputc(int ch, FILE *f)
{
    
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
    return 0;
}


time_t time(time_t *timer)
{
    

    return HAL_GetTick();
}

void exit(int status)
{
    
    //  return 1;
}

int system(const char *filename)
{
    
    return 0;
}

测试方法:
main.c 中添加

/* USER CODE BEGIN 0 */
static int lua_led_on(lua_State *L)
{
    
    HAL_GPIO_WritePin(LEDG_GPIO_Port, LEDG_Pin, GPIO_PIN_SET);
    return 1;
}
static int lua_led_off(lua_State *L)
{
    
    HAL_GPIO_WritePin(LEDG_GPIO_Port, LEDG_Pin, GPIO_PIN_RESET);
    return 1;
}

static int lua_delay(lua_State *L)
{
    
    int num;
    num = lua_tointeger(L, 1);
    HAL_Delay(num);
    return 1;
}

static const struct luaL_Reg mylib[] =
    {
    
        {
    "led_on", lua_led_on},
        {
    "led_off", lua_led_off},
        {
    "delay", lua_delay},
        {
    NULL, NULL}};


void Lua_Test(void)
{
    
    lua_State *L;
    L = luaL_newstate(); /* 建立Lua运行环境 */
    //luaL_openlibs(L); //
    luaopen_base(L);            //注册基础函数
    luaL_setfuncs(L, mylib, 0); //注册自定义函数

    //文件程序自动执行,已测试OK
    char strProgramName[] = "0:/lua.lua";

    if (luaL_dofile(L, strProgramName))
        printf("Lua文件错误或不存在!\r\n");

    lua_close(L);/* 关闭Lua 并释放内存 */
}
/* USER CODE END 0 */

main函数中添加:

int main(void)
{
    
  /* USER CODE BEGIN 1 */
  uint32_t cnt =0;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_FATFS_Init();
  MX_QUADSPI_Init();
  MX_SPI2_Init();
#if 0
  /* usb初始化时会打断程序运行,需要根据实际使用情况修改 */
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_FATFS_Init();
  MX_QUADSPI_Init();
  MX_SPI2_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */
#endif
  Lua_Test();
  MX_USB_DEVICE_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    
    HAL_GPIO_TogglePin(LEDR_GPIO_Port, LEDR_Pin);
    HAL_Delay(100);
    cnt++;
    if (cnt == 25)
    {
    
      printf("This is sram \r\n");
      cnt = 0;
    }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

编译下载运行:
此时仅有 LEDR 快速闪烁,串口打印如下信息:

Lua文件错误或不存在!
This is sram
This is sram

同时PC上会提示发现u盘。

准备 lua.lua文件,内容如下:
(实现 LEDG 500ms闪烁 5次)

off = 500
on = 500
i = 0
while i < 5 do
i = i+1
led_on()
delay(off)
led_off()
delay(on)
end 

将文件考入U盘。
在这里插入图片描述

重新上电后,即可看见运行效果,先 LEDG 闪烁 5次,然后 LEDR 开始快速闪烁。
至此移植完成。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_25626001/article/details/119345724

智能推荐

ios审核被拒4.3,马甲包提交_义中的博客-程序员秘密

一. 先说说为什么要制作马甲包 (马甲包应用比较广泛的几种app:金融类,彩票类,付费视频类)①防止app因为违规被苹果下架后"一无所有"付费视频类,彩票类的app多少都会违反苹果的一些规范有被下架的风险,马甲包可以在app被下架的时候顶上去,那什么情况下会被下架呢1.之前审核的时候用到开关,审核过了之后APP的内容和审核时的内容差异较大,苹果复查的时候发现被下架2.用户举报,被...

AVR单片机GCC编程_此间的年少的博客-程序员秘密

Atmel公司的AVR 8位RISC单片机是一种非常普通的单片机.它是一个具有电擦写可编程只读存储器(EEPROM),随机访问存储器(RAM),模数转换器,大量的输入和输出线路,计时器,RS-232通讯接口UART以及其他很多功能的单片集成电路.最好的莫过于在Linux下具有一个可供利用的完整编程环境:你可以采用GCC对这种单片机进行C语言编程.本文我将向你讲述如何安装和使用GCC.我也将

Android四大组件之Service总结_奋斗者Eas的博客-程序员秘密

1、定义Service 中文称 服务,是Android四大组件之一作用:提供需要后台运行的任务(如:复杂计算、下载、音乐播放)特点:后台运行、无界面、生命周期长2、生命周期4个手动调用的方法手动调用方法 作用startService() 启动服务stopService() 关闭服务bindService() 绑定服务unbindService() 解绑服务5个自动调用的方法内部自动调用的方法 作用onCreat() 创建服务onStartCommand() 开始服务onDes

线性回归算法的数学原理_线性回归算法的基本原理_taon1607的博客-程序员秘密

在机器学习中,调用算法是件比较容易的事,但是我们想要将机器学习理解的更加透彻,就必须深刻理解每一种算法背后的数学原理,这对于我们后期调整算法参数,改进算法模型有着非常大的帮助。其实看到这一大长串数学公式,我心里也很绝望,但是没办法呀,为了能深入理解线性回归原理,喝二两白酒也要给自己打打气。下面,我们一步一步去理解线性回归的数学原理。下面是一个银行贷款的案例,银行会根据我们的年龄以及工资来决定我们的可贷款金额。现我们绘制一个拟合平面对该数据集进行拟合。其中X1,X2就是我们的年龄以及工资特征,y是我们的可

【转】一个程序员的顿悟:理想的程序员只比你多了6个一点点_weixin_30337157的博客-程序员秘密

来自: http://www.phpxs.com/post/4338/ 作者 Sandy  我算是靠坑蒙拐骗进了程序员的门,然后一路狂奔。26岁之前几乎没有任何写代码的经验,研究生毕业却意外选择了一家不可能提供培训的初创公司,在每日担忧公司倒闭、害怕被炒鱿鱼以及同事冷落白眼的三重压力下逆流而上,一年半后离职,已是拥有 500万用户产品的后台主程。从前我对计算机技术心怀畏惧,认定技术高人一...

bzoj1503 [NOI2004]郁闷的出纳员 splay_olahiuj的博客-程序员秘密

DescriptionOIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体

随便推点

NYOJ 456-邮票分你一半(01背包)_凉哈哈的博客-程序员秘密

邮票分你一半时间限制:1000 ms  |  内存限制:65535 KB难度:3题目链接:点击打开链接描述     小珂最近收集了些邮票,他想把其中的一些给他的好朋友小明。每张邮票上都有分值,他们想把这些邮票分成两份,并且使这两份邮票的分值和相差最小(就是小珂得到的邮票分值和与小明的差值最小),现在每张邮票的分值已经知道了,他们已经分好了,你知道最后他们

kivy mysql_Kivy中文显示_weixin_39623671的博客-程序员秘密

【Kivy中文显示】的更多相关文章Win7系统 下载 DroidSansFallback.ttf字体(android设备上自带了) 源代码第一行增加#-*- coding:utf-8 -*- 创建widget值定font_name s …1. kivy中显示中文乱码和提示错误的原因: 编码问题 字体问题 2. 字体问题的解决 可以下载支持中文的字体文件ttf,我这里使用了微软雅黑中文简体msy...

oracle 直方图 使用_长烟慢慢的博客-程序员秘密

直方图(histograms) 默认情况下,在收集表的统计信息信息时,对列信息的收集是FOR ALL COLUMNS SIZE AUTO,这种情况下直方图的信息可能没有收集到,所以可以手工指定收集直方图的信息:  exec DBMS_STATS.GATHER_table_STATS(OWNNAME => 'ICD', TABNAME => 'TAGENTOPRINFO',  MET

Oracle数据库检查语句大全_oracle语句检查_zengwende的博客-程序员秘密

1、检查Oracle实例状态select instance_name,host_name,version,to_char(startup_time,'yyyy-mm-dd hh24:mi') startuptime,status,archiver from v$instance;2、检查数据库连接情况select count(*) from v$session;select s...

24C16的读写_24c16读写程序详解_树懒的聪明的博客-程序员秘密

24C16的读写 (2009-04-10 23:11:27)转载▼标签: 杂谈 // 头文件// 使用Eeprom的设备标识符,即器件地址// 24C64最多可以定定义8个//#define I2C_FIRST_ID    0xA0    // 1010,000,0B//#define I2C_SECOND_ID    0xA2    // 1010,001,0B//#define I2C_THI...

Python练习题 007:兔子生兔子_吉大秦少游的博客-程序员秘密

题目斐波那契数列问题代码a,b=0,1for i in range(1,13): print("第{}个月:{}只兔子".format(i,b)) a,b=b,a+b

推荐文章

热门文章

相关标签